From 553e15f21bd7b1ecb709edfb5686d5768fe942f2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 31 Oct 2017 09:37:15 +0100 Subject: [PATCH] Add a little helper to make /sys/dev/block/major:minor paths --- src/basic/btrfs-util.c | 12 +++++------ src/basic/device-nodes.h | 8 +++++++ src/basic/util.c | 53 ++++++++++++++-------------------------------- src/shared/dissect-image.c | 7 +++--- 4 files changed, 34 insertions(+), 46 deletions(-) diff --git a/src/basic/btrfs-util.c b/src/basic/btrfs-util.c index b7e237f..ac96e63 100644 --- a/src/basic/btrfs-util.c +++ b/src/basic/btrfs-util.c @@ -42,6 +42,7 @@ #include "btrfs-util.h" #include "chattr-util.h" #include "copy.h" +#include "device-nodes.h" #include "fd-util.h" #include "fileio.h" #include "io-util.h" @@ -910,7 +911,8 @@ int btrfs_subvol_set_subtree_quota_limit(const char *path, uint64_t subvol_id, u int btrfs_resize_loopback_fd(int fd, uint64_t new_size, bool grow_only) { struct btrfs_ioctl_vol_args args = {}; - _cleanup_free_ char *p = NULL, *loop = NULL, *backing = NULL; + char p[SYS_BLOCK_PATH_MAX("/loop/backing_file")]; + _cleanup_free_ char *backing = NULL; _cleanup_close_ int loop_fd = -1, backing_fd = -1; struct stat st; dev_t dev = 0; @@ -930,8 +932,7 @@ int btrfs_resize_loopback_fd(int fd, uint64_t new_size, bool grow_only) { if (r == 0) return -ENODEV; - if (asprintf(&p, "/sys/dev/block/%u:%u/loop/backing_file", major(dev), minor(dev)) < 0) - return -ENOMEM; + xsprintf_sys_block_path(p, "/loop/backing_file", dev); r = read_one_line_file(p, &backing); if (r == -ENOENT) return -ENODEV; @@ -955,9 +956,8 @@ int btrfs_resize_loopback_fd(int fd, uint64_t new_size, bool grow_only) { if (grow_only && new_size < (uint64_t) st.st_size) return -EINVAL; - if (asprintf(&loop, "/dev/block/%u:%u", major(dev), minor(dev)) < 0) - return -ENOMEM; - loop_fd = open(loop, O_RDWR|O_CLOEXEC|O_NOCTTY); + xsprintf_sys_block_path(p, NULL, dev); + loop_fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY); if (loop_fd < 0) return -errno; diff --git a/src/basic/device-nodes.h b/src/basic/device-nodes.h index 1e09bdc..9f3c6d6 100644 --- a/src/basic/device-nodes.h +++ b/src/basic/device-nodes.h @@ -23,5 +23,13 @@ #include #include +#include "macro.h" +#include "stdio-util.h" + int encode_devnode_name(const char *str, char *str_enc, size_t len); int whitelisted_char_for_devnode(char c, const char *additional); + +#define SYS_BLOCK_PATH_MAX(suffix) \ + (strlen("/sys/dev/block/") + DECIMAL_STR_MAX(dev_t) + 1 + DECIMAL_STR_MAX(dev_t) + strlen_ptr(suffix)) +#define xsprintf_sys_block_path(buf, suffix, devno) \ + xsprintf(buf, "/sys/dev/block/%u:%u%s", major(devno), minor(devno), strempty(suffix)) diff --git a/src/basic/util.c b/src/basic/util.c index 0c278ab..f61d901 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -39,6 +39,7 @@ #include "build.h" #include "cgroup-util.h" #include "def.h" +#include "device-nodes.h" #include "dirent-util.h" #include "fd-util.h" #include "fileio.h" @@ -118,63 +119,42 @@ int socket_from_display(const char *display, char **path) { } int block_get_whole_disk(dev_t d, dev_t *ret) { - char *p, *s; + char p[SYS_BLOCK_PATH_MAX("/partition")]; + _cleanup_free_ char *s = NULL; int r; unsigned n, m; assert(ret); /* If it has a queue this is good enough for us */ - if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0) - return -ENOMEM; - - r = access(p, F_OK); - free(p); - - if (r >= 0) { + xsprintf_sys_block_path(p, "/queue", d); + if (access(p, F_OK) >= 0) { *ret = d; return 0; } /* If it is a partition find the originating device */ - if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0) - return -ENOMEM; - - r = access(p, F_OK); - free(p); - - if (r < 0) + xsprintf_sys_block_path(p, "/partition", d); + if (access(p, F_OK) < 0) return -ENOENT; /* Get parent dev_t */ - if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0) - return -ENOMEM; - + xsprintf_sys_block_path(p, "/../dev", d); r = read_one_line_file(p, &s); - free(p); - if (r < 0) return r; r = sscanf(s, "%u:%u", &m, &n); - free(s); - if (r != 2) return -EINVAL; /* Only return this if it is really good enough for us. */ - if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0) - return -ENOMEM; - - r = access(p, F_OK); - free(p); - - if (r >= 0) { - *ret = makedev(m, n); - return 0; - } + xsprintf_sys_block_path(p, "/queue", makedev(m, n)); + if (access(p, F_OK) < 0) + return -ENOENT; - return -ENOENT; + *ret = makedev(m, n); + return 0; } bool kexec_loaded(void) { @@ -749,7 +729,8 @@ int get_block_device(const char *path, dev_t *dev) { int get_block_device_harder(const char *path, dev_t *dev) { _cleanup_closedir_ DIR *d = NULL; - _cleanup_free_ char *p = NULL, *t = NULL; + _cleanup_free_ char *t = NULL; + char p[SYS_BLOCK_PATH_MAX("/slaves")]; struct dirent *de, *found = NULL; const char *q; unsigned maj, min; @@ -767,9 +748,7 @@ int get_block_device_harder(const char *path, dev_t *dev) { if (r <= 0) return r; - if (asprintf(&p, "/sys/dev/block/%u:%u/slaves", major(dt), minor(dt)) < 0) - return -ENOMEM; - + xsprintf_sys_block_path(p, "/slaves", dt); d = opendir(p); if (!d) { if (errno == ENOENT) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 219ba8c..1a7ccbe 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -33,6 +33,7 @@ #include "blkid-util.h" #include "copy.h" #include "def.h" +#include "device-nodes.h" #include "dissect-image.h" #include "fd-util.h" #include "fileio.h" @@ -652,7 +653,7 @@ DissectedImage* dissected_image_unref(DissectedImage *m) { } static int is_loop_device(const char *path) { - char s[strlen("/sys/dev/block/") + DECIMAL_STR_MAX(dev_t) + 1 + DECIMAL_STR_MAX(dev_t) + strlen("/../loop/")]; + char s[SYS_BLOCK_PATH_MAX("/../loop/")]; struct stat st; assert(path); @@ -663,13 +664,13 @@ static int is_loop_device(const char *path) { if (!S_ISBLK(st.st_mode)) return -ENOTBLK; - xsprintf(s, "/sys/dev/block/%u:%u/loop/", major(st.st_rdev), minor(st.st_rdev)); + xsprintf_sys_block_path(s, "/loop/", st.st_dev); if (access(s, F_OK) < 0) { if (errno != ENOENT) return -errno; /* The device itself isn't a loop device, but maybe it's a partition and its parent is? */ - xsprintf(s, "/sys/dev/block/%u:%u/../loop/", major(st.st_rdev), minor(st.st_rdev)); + xsprintf_sys_block_path(s, "/../loop/", st.st_dev); if (access(s, F_OK) < 0) return errno == ENOENT ? false : -errno; } -- 2.7.4