Add a little helper to make /sys/dev/block/major:minor paths

This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2017-11-30 12:59:23 +01:00
parent ee3467c6bd
commit 553e15f21b
4 changed files with 34 additions and 46 deletions
+6 -6
View File
@@ -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;
+8
View File
@@ -23,5 +23,13 @@
#include <stddef.h>
#include <sys/types.h>
#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))
+16 -37
View File
@@ -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;
xsprintf_sys_block_path(p, "/queue", makedev(m, n));
if (access(p, F_OK) < 0)
return -ENOENT;
r = access(p, F_OK);
free(p);
if (r >= 0) {
*ret = makedev(m, n);
return 0;
}
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)