summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds-device.c60
-rw-r--r--cmds-replace.c13
-rw-r--r--utils.c58
-rw-r--r--utils.h2
4 files changed, 118 insertions, 15 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;
}
diff --git a/cmds-replace.c b/cmds-replace.c
index 9eb981ba..186a127f 100644
--- a/cmds-replace.c
+++ b/cmds-replace.c
@@ -134,7 +134,7 @@ static int cmd_start_replace(int argc, char **argv)
int fddstdev = -1;
char *path;
char *srcdev;
- char *dstdev;
+ char *dstdev = NULL;
int avoid_reading_from_srcdev = 0;
int force_using_targetdev = 0;
struct stat st;
@@ -209,7 +209,12 @@ static int cmd_start_replace(int argc, char **argv)
}
srcdev = argv[optind];
- dstdev = argv[optind + 1];
+ dstdev = canonicalize_path(argv[optind + 1]);
+ if (!dstdev) {
+ fprintf(stderr,
+ "ERROR: Could not canonicalize path '%s': %s\n",
+ argv[optind + 1], strerror(errno));
+ }
if (is_numerical(srcdev)) {
struct btrfs_ioctl_fs_info_args fi_args;
@@ -283,6 +288,8 @@ static int cmd_start_replace(int argc, char **argv)
close(fddstdev);
fddstdev = -1;
+ free(dstdev);
+ dstdev = NULL;
dev_replace_handle_sigint(fdmnt);
if (!do_not_background) {
@@ -317,6 +324,8 @@ static int cmd_start_replace(int argc, char **argv)
return 0;
leave_with_error:
+ if (dstdev)
+ free(dstdev);
if (fdmnt != -1)
close(fdmnt);
if (fdsrcdev != -1)
diff --git a/utils.c b/utils.c
index 46d47d53..c718d0f6 100644
--- a/utils.c
+++ b/utils.c
@@ -1027,6 +1027,64 @@ static int blk_file_in_dev_list(struct btrfs_fs_devices* fs_devices,
}
/*
+ * Resolve a pathname to a device mapper node to /dev/mapper/<name>
+ * Returns NULL on invalid input or malloc failure; Other failures
+ * will be handled by the caller using the input pathame.
+ */
+char *canonicalize_dm_name(const char *ptname)
+{
+ FILE *f;
+ size_t sz;
+ char path[PATH_MAX], name[PATH_MAX], *res = NULL;
+
+ if (!ptname || !*ptname)
+ return NULL;
+
+ snprintf(path, sizeof(path), "/sys/block/%s/dm/name", ptname);
+ if (!(f = fopen(path, "r")))
+ return NULL;
+
+ /* read <name>\n from sysfs */
+ if (fgets(name, sizeof(name), f) && (sz = strlen(name)) > 1) {
+ name[sz - 1] = '\0';
+ snprintf(path, sizeof(path), "/dev/mapper/%s", name);
+
+ if (access(path, F_OK) == 0)
+ res = strdup(path);
+ }
+ fclose(f);
+ return res;
+}
+
+/*
+ * Resolve a pathname to a canonical device node, e.g. /dev/sda1 or
+ * to a device mapper pathname.
+ * Returns NULL on invalid input or malloc failure; Other failures
+ * will be handled by the caller using the input pathame.
+ */
+char *canonicalize_path(const char *path)
+{
+ char *canonical, *p;
+
+ if (!path || !*path)
+ return NULL;
+
+ canonical = realpath(path, NULL);
+ if (!canonical)
+ return strdup(path);
+ p = strrchr(canonical, '/');
+ if (p && strncmp(p, "/dm-", 4) == 0 && isdigit(*(p + 4))) {
+ char *dm = canonicalize_dm_name(p + 1);
+
+ if (dm) {
+ free(canonical);
+ return dm;
+ }
+ }
+ return canonical;
+}
+
+/*
* returns 1 if the device was mounted, < 0 on error or 0 if everything
* is safe to continue.
*/
diff --git a/utils.h b/utils.h
index 4cfd315a..37fe1ba0 100644
--- a/utils.h
+++ b/utils.h
@@ -53,6 +53,8 @@ int btrfs_add_to_fsid(struct btrfs_trans_handle *trans,
int btrfs_scan_for_fsid(int run_ioctls);
void btrfs_register_one_device(char *fname);
int btrfs_scan_one_dir(char *dirname, int run_ioctl);
+char *canonicalize_dm_name(const char *ptname);
+char *canonicalize_path(const char *path);
int check_mounted(const char *devicename);
int check_mounted_where(int fd, const char *file, char *where, int size,
struct btrfs_fs_devices **fs_devices_mnt);