summaryrefslogtreecommitdiff
path: root/cmds-device.c
diff options
context:
space:
mode:
authorJeff Mahoney <jeffm@suse.com>2014-06-04 16:43:11 -0400
committerDavid Sterba <dsterba@suse.cz>2014-08-22 14:39:34 +0200
commitb276e4bc50b6ca99056a45315ea859c68d58fc1b (patch)
tree28a5c42642a658d46fd1b9c5d473d65fbfd1c955 /cmds-device.c
parent350bb14bc6b925418e9ecc9852261085d38224df (diff)
btrfs-progs: canonicalize pathnames for device commands
mount(8) will canonicalize pathnames before passing them to the kernel. Links to e.g. /dev/sda will be resolved to /dev/sda. Links to /dev/dm-# will be resolved using the name of the device mapper table to /dev/mapper/<name>. Btrfs will use whatever name the user passes to it, regardless of whether it is canonical or not. That means that if a 'btrfs device ready' is issued on any device node pointing to the original device, it will adopt the new name instead of the name that was used during mount. Mounting using /dev/sdb2 will result in df: /dev/sdb2 209715200 39328 207577088 1% /mnt lrwxrwxrwx 1 root root 4 Jun 4 13:36 /dev/whatever-i-like -> sdb2 /dev/whatever-i-like 209715200 39328 207577088 1% /mnt Likewise, mounting with /dev/mapper/whatever and using /dev/dm-0 with a btrfs device command results in df showing /dev/dm-0. This can happen with multipath devices with friendly names enabled and doing something like 'partprobe' which (at least with our version) ends up issuing a 'change' uevent on the sysfs node. That *always* uses the dm-# name, and we get confused users. This patch does the same canonicalization of the paths that mount does so that we don't end up having inconsistent names reported by ->show_devices later. Signed-off-by: Jeff Mahoney <jeffm@suse.com> [use PATH_MAX in canonicalize_dm_name] Signed-off-by: David Sterba <dsterba@suse.cz>
Diffstat (limited to 'cmds-device.c')
-rw-r--r--cmds-device.c60
1 files changed, 47 insertions, 13 deletions
diff --git a/cmds-device.c b/cmds-device.c
index 29da661e..d7af0901 100644
--- a/cmds-device.c
+++ b/cmds-device.c
@@ -94,6 +94,7 @@ static int cmd_add_dev(int argc, char **argv)
int devfd, res;
u64 dev_block_count = 0;
int mixed = 0;
+ char *path;
res = test_dev_for_mkfs(argv[i], force, estr);
if (res) {
@@ -117,15 +118,24 @@ static int cmd_add_dev(int argc, char **argv)
goto error_out;
}
- strncpy_null(ioctl_args.name, argv[i]);
+ path = canonicalize_path(argv[i]);
+ if (!path) {
+ fprintf(stderr,
+ "ERROR: Could not canonicalize pathname '%s': %s\n",
+ argv[i], strerror(errno));
+ ret++;
+ goto error_out;
+ }
+
+ strncpy_null(ioctl_args.name, path);
res = ioctl(fdmnt, BTRFS_IOC_ADD_DEV, &ioctl_args);
e = errno;
- if(res<0){
+ if (res < 0) {
fprintf(stderr, "ERROR: error adding the device '%s' - %s\n",
- argv[i], strerror(e));
+ path, strerror(e));
ret++;
}
-
+ free(path);
}
error_out:
@@ -241,6 +251,7 @@ static int cmd_scan_dev(int argc, char **argv)
for( i = devstart ; i < argc ; i++ ){
struct btrfs_ioctl_vol_args args;
+ char *path;
if (!is_block_device(argv[i])) {
fprintf(stderr,
@@ -248,9 +259,17 @@ static int cmd_scan_dev(int argc, char **argv)
ret = 1;
goto close_out;
}
- printf("Scanning for Btrfs filesystems in '%s'\n", argv[i]);
+ path = canonicalize_path(argv[i]);
+ if (!path) {
+ fprintf(stderr,
+ "ERROR: Could not canonicalize path '%s': %s\n",
+ argv[i], strerror(errno));
+ ret = 1;
+ goto close_out;
+ }
+ printf("Scanning for Btrfs filesystems in '%s'\n", path);
- strncpy_null(args.name, argv[i]);
+ strncpy_null(args.name, path);
/*
* FIXME: which are the error code returned by this ioctl ?
* it seems that is impossible to understand if there no is
@@ -261,9 +280,11 @@ static int cmd_scan_dev(int argc, char **argv)
if( ret < 0 ){
fprintf(stderr, "ERROR: unable to scan the device '%s' - %s\n",
- argv[i], strerror(e));
+ path, strerror(e));
+ free(path);
goto close_out;
}
+ free(path);
}
close_out:
@@ -283,6 +304,7 @@ static int cmd_ready_dev(int argc, char **argv)
struct btrfs_ioctl_vol_args args;
int fd;
int ret;
+ char *path;
if (check_argc_min(argc, 2))
usage(cmd_ready_dev_usage);
@@ -292,22 +314,34 @@ static int cmd_ready_dev(int argc, char **argv)
perror("failed to open /dev/btrfs-control");
return 1;
}
- if (!is_block_device(argv[1])) {
+
+ path = canonicalize_path(argv[argc - 1]);
+ if (!path) {
fprintf(stderr,
- "ERROR: %s is not a block device\n", argv[1]);
- close(fd);
- return 1;
+ "ERROR: Could not canonicalize pathname '%s': %s\n",
+ argv[argc - 1], strerror(errno));
+ ret = 1;
+ goto out;
}
- strncpy(args.name, argv[argc - 1], BTRFS_PATH_NAME_MAX);
+ if (!is_block_device(path)) {
+ fprintf(stderr,
+ "ERROR: %s is not a block device\n", path);
+ ret = 1;
+ goto out;
+ }
+
+ strncpy(args.name, path, BTRFS_PATH_NAME_MAX);
ret = ioctl(fd, BTRFS_IOC_DEVICES_READY, &args);
if (ret < 0) {
fprintf(stderr, "ERROR: unable to determine if the device '%s'"
- " is ready for mounting - %s\n", argv[argc - 1],
+ " is ready for mounting - %s\n", path,
strerror(errno));
ret = 1;
}
+out:
+ free(path);
close(fd);
return ret;
}