diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM index 892fd6883..bccb1364a 100644 --- a/WHATS_NEW_DM +++ b/WHATS_NEW_DM @@ -1,5 +1,7 @@ Version 1.02.56 - ===================================== + Add --setuuid to dmsetup rename. + Add dm_task_set_newuuid to set uuid of mapped device post-creation. Version 1.02.55 - 24th September 2010 ===================================== diff --git a/libdm/ioctl/libdm-iface.c b/libdm/ioctl/libdm-iface.c index 5ba6634ce..49b82e680 100644 --- a/libdm/ioctl/libdm-iface.c +++ b/libdm/ioctl/libdm-iface.c @@ -826,6 +826,11 @@ static int _dm_task_run_v1(struct dm_task *dmt) if (dmt->type == DM_DEVICE_TABLE) dmi->flags |= DM_STATUS_TABLE_FLAG; + if (dmt->new_uuid) { + log_error("Changing UUID is not supported by kernel."); + goto bad; + } + log_debug("dm %s %s %s%s%s [%u]", _cmd_data_v1[dmt->type].name, dmi->name, dmi->uuid, dmt->newname ? " " : "", dmt->newname ? dmt->newname : "", @@ -1185,6 +1190,22 @@ int dm_task_suppress_identical_reload(struct dm_task *dmt) return 1; } +int dm_task_set_newuuid(struct dm_task *dmt, const char *newuuid) +{ + if (strlen(newuuid) >= DM_UUID_LEN) { + log_error("Uuid \"%s\" too long", newuuid); + return 0; + } + + if (!(dmt->newname = dm_strdup(newuuid))) { + log_error("dm_task_set_newuuid: strdup(%s) failed", newuuid); + return 0; + } + dmt->new_uuid = 1; + + return 1; +} + int dm_task_set_newname(struct dm_task *dmt, const char *newname) { if (strchr(newname, '/')) { @@ -1201,6 +1222,7 @@ int dm_task_set_newname(struct dm_task *dmt, const char *newname) log_error("dm_task_set_newname: strdup(%s) failed", newname); return 0; } + dmt->new_uuid = 0; return 1; } @@ -1399,7 +1421,7 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count) } if (count && dmt->newname) { - log_error("targets and newname are incompatible"); + log_error("targets and rename are incompatible"); return NULL; } @@ -1409,12 +1431,12 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count) } if (dmt->newname && (dmt->sector || dmt->message)) { - log_error("message and newname are incompatible"); + log_error("message and rename are incompatible"); return NULL; } if (dmt->newname && dmt->geometry) { - log_error("geometry and newname are incompatible"); + log_error("geometry and rename are incompatible"); return NULL; } @@ -1514,6 +1536,14 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count) "by kernel. It will use live table."); dmi->flags |= DM_QUERY_INACTIVE_TABLE_FLAG; } + if (dmt->new_uuid) { + if (_dm_version_minor < 19) { + log_error("WARNING: Setting UUID unsupported by " + "kernel. Aborting operation."); + goto bad; + } + dmi->flags |= DM_NEW_UUID_FLAG; + } dmi->target_count = count; dmi->event_nr = dmt->event_nr; @@ -1910,9 +1940,10 @@ static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command, } } - log_debug("dm %s %s %s%s%s %s%.0d%s%.0d%s" + log_debug("dm %s %s%s %s%s%s %s%.0d%s%.0d%s" "%s%c%c%s%s %.0" PRIu64 " %s [%u]", _cmd_data_v4[dmt->type].name, + dmt->new_uuid ? "UUID " : "", dmi->name, dmi->uuid, dmt->newname ? " " : "", dmt->newname ? dmt->newname : "", dmt->major > 0 ? "(" : "", @@ -2044,7 +2075,7 @@ repeat_ioctl: case DM_DEVICE_RENAME: /* FIXME Kernel needs to fill in dmi->name */ - if (dmt->dev_name && !udev_only) + if (!dmt->new_uuid && dmt->dev_name && !udev_only) rename_dev_node(dmt->dev_name, dmt->newname, check_udev); break; diff --git a/libdm/ioctl/libdm-targets.h b/libdm/ioctl/libdm-targets.h index ea3d14f77..d8cee4539 100644 --- a/libdm/ioctl/libdm-targets.h +++ b/libdm/ioctl/libdm-targets.h @@ -62,6 +62,7 @@ struct dm_task { int suppress_identical_reload; uint64_t existing_table_size; int cookie_set; + int new_uuid; char *uuid; }; diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h index 34bcf4052..7ed60beb8 100644 --- a/libdm/libdevmapper.h +++ b/libdm/libdevmapper.h @@ -167,6 +167,7 @@ struct dm_versions *dm_task_get_versions(struct dm_task *dmt); int dm_task_set_ro(struct dm_task *dmt); int dm_task_set_newname(struct dm_task *dmt, const char *newname); +int dm_task_set_newuuid(struct dm_task *dmt, const char *newuuid); int dm_task_set_minor(struct dm_task *dmt, int minor); int dm_task_set_major(struct dm_task *dmt, int major); int dm_task_set_major_minor(struct dm_task *dmt, int major, int minor, int allow_default_major_fallback); diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c index 4de2f4b5f..b86739a09 100644 --- a/libdm/libdm-common.c +++ b/libdm/libdm-common.c @@ -192,6 +192,7 @@ struct dm_task *dm_task_create(int type) dmt->event_nr = 0; dmt->cookie_set = 0; dmt->query_inactive_table = 0; + dmt->new_uuid = 0; return dmt; } diff --git a/libdm/misc/dm-ioctl.h b/libdm/misc/dm-ioctl.h index c5b3860ab..f21272b05 100644 --- a/libdm/misc/dm-ioctl.h +++ b/libdm/misc/dm-ioctl.h @@ -46,7 +46,7 @@ * Remove a device, destroy any tables. * * DM_DEV_RENAME: - * Rename a device. + * Rename a device or set its uuid if none was previously supplied. * * DM_SUSPEND: * This performs both suspend and resume, depending which flag is @@ -269,9 +269,9 @@ enum { #define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl) #define DM_VERSION_MAJOR 4 -#define DM_VERSION_MINOR 17 +#define DM_VERSION_MINOR 19 #define DM_VERSION_PATCHLEVEL 0 -#define DM_VERSION_EXTRA "-ioctl (2010-03-05)" +#define DM_VERSION_EXTRA "-ioctl (2010-10-14)" /* Status bits */ #define DM_READONLY_FLAG (1 << 0) /* In/Out */ @@ -324,4 +324,10 @@ enum { */ #define DM_UEVENT_GENERATED_FLAG (1 << 13) /* Out */ +/* + * If set, rename changes the uuid not the name. Only permitted + * if no uuid was previously supplied: an existing uuid cannot be changed. + */ +#define DM_NEW_UUID_FLAG (1 << 14) /* In */ + #endif /* _LINUX_DM_IOCTL_H */ diff --git a/man/dmsetup.8.in b/man/dmsetup.8.in index 9ae6ab1ba..68e981990 100644 --- a/man/dmsetup.8.in +++ b/man/dmsetup.8.in @@ -33,6 +33,9 @@ dmsetup \- low level logical volume management .B dmsetup rename .I device_name new_name .br +.B dmsetup rename +.I device_name --setuuid uuid +.br .B dmsetup message .I device_name sector message .br @@ -285,6 +288,11 @@ process to be killed. This also runs \fBmknodes\fP afterwards. .I device_name new_name .br Renames a device. +.IP \fBrename +.I device_name --setuuid uuid +.br +Sets the uuid of a device that was created without a uuid. +After a uuid has been set it cannot be changed. .IP \fBresume .I device_name .br diff --git a/tools/dmsetup.c b/tools/dmsetup.c index f094f3fb1..a38fc4cf9 100644 --- a/tools/dmsetup.c +++ b/tools/dmsetup.c @@ -140,6 +140,7 @@ enum { READAHEAD_ARG, ROWS_ARG, SEPARATOR_ARG, + SETUUID_ARG, SHOWKEYS_ARG, SORT_ARG, TABLE_ARG, @@ -665,7 +666,10 @@ static int _rename(int argc, char **argv, void *data __attribute__((unused))) if (!_set_task_device(dmt, (argc == 3) ? argv[1] : NULL, 0)) goto out; - if (!dm_task_set_newname(dmt, argv[argc - 1])) + if (_switches[SETUUID_ARG]) { + if (!dm_task_set_newuuid(dmt, argv[argc - 1])) + goto out; + } else if (!dm_task_set_newname(dmt, argv[argc - 1])) goto out; if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt)) @@ -2699,7 +2703,7 @@ static struct command _commands[] = { {"load", " []", 0, 2, _load}, {"clear", "", 0, 1, _clear}, {"reload", " []", 0, 2, _load}, - {"rename", " ", 1, 2, _rename}, + {"rename", " [--setuuid] ", 1, 2, _rename}, {"message", " ", 2, -1, _message}, {"ls", "[--target ] [--exec ] [--tree [-o options]]", 0, 0, _ls}, {"info", "[]", 0, 1, _info}, @@ -3106,6 +3110,7 @@ static int _process_switches(int *argc, char ***argv, const char *dev_dir) {"readahead", 1, &ind, READAHEAD_ARG}, {"rows", 0, &ind, ROWS_ARG}, {"separator", 1, &ind, SEPARATOR_ARG}, + {"setuuid", 0, &ind, SETUUID_ARG}, {"showkeys", 0, &ind, SHOWKEYS_ARG}, {"sort", 1, &ind, SORT_ARG}, {"table", 1, &ind, TABLE_ARG}, @@ -3278,6 +3283,8 @@ static int _process_switches(int *argc, char ***argv, const char *dev_dir) } if ((ind == ROWS_ARG)) _switches[ROWS_ARG]++; + if ((ind == SETUUID_ARG)) + _switches[SETUUID_ARG]++; if ((ind == SHOWKEYS_ARG)) _switches[SHOWKEYS_ARG]++; if ((ind == TABLE_ARG)) {