Hi Joe, I have a new feature request for Device-Mapper that I'm hoping you'll consider. Currently, the DM ioctl interface allows device's to be renamed, but the UUID remains unchanged for the life of the device. This patch adds the ability to change the UUID as well as the name. The changes are pretty straight-forward. The UUID rename uses the same ioctl command as regular rename. I have added a new flag field that can be set on that command to indicate a UUID rename instead of a regular rename. The rename() and dm_hash_rename() functions in dm-ioctl.c were modified to check for this flag, and take the appropriate actions. The change is backwards compatible with the old version of the ioctl interface (i.e. LVM2 will be able to run on the new interface without any changes) but not forwards compatible (i.e. any app that wants to use this new UUID rename function needs the new ioctl version). Thus, the DM_VERSION_MINOR is incremented by one (according to the comments in dm-ioctl.h). There are a couple reasons for this request. First, some of the EVMS modules do not have actual UUIDs stored anywhere, but rather generate UUIDs based on other metadata information. For instance, a DOS partition has a name that is based on the location of that partition within the partition tables (e.g. hda6), and has a UUID that reflects the name of the disk, the staring LBA, and the partition size (e.g. hda:63:10240). Since DOS partitions can be "moved" into available freespace elsewhere on the disk, the UUID could change, even though the name might stay the same. Thus, we'd like to keep the assigned UUID up-to-date in the kernel, to make sure it can be correctly located in future query's to the kernel. Another reason for the change is due to our implementation of snapshotting. When taking a snapshot of a device (we'll call that device the origin child), we'd like the newly created snapshot-origin (we'll call it the origin parent) to effectively switch device numbers with the child. This way, any active users of the origin child will not notice that the snapshot has taken place. However, the device numbers cannot be changed. Thus, we create the parent device with the child's mapping, perform a series of renames, and reload the child device with a snapshot-origin map. But in order for the renames to work correctly, both the names and uuids must be switched. Please take a look at the patch, and let me know if you have any questions. Also, as the 2.4 and 2.5 versions of the interface are quite similar, this patch should apply to 2.5.63-dm-1 as well. Thanks! Kevin Corry --- 2.4.20a/drivers/md/dm-ioctl.c 2003/02/13 19:35:45 +++ 2.4.20b/drivers/md/dm-ioctl.c 2003/02/27 21:51:41 @@ -262,7 +262,7 @@ up_write(&_hash_lock); } -int dm_hash_rename(const char *old, const char *new) +int dm_hash_rename(const char *old, const char *new, int uuid_rename) { char *new_name, *old_name; struct hash_cell *hc; @@ -279,7 +279,7 @@ /* * Is new free ? */ - hc = __get_name_cell(new); + hc = uuid_rename ? __get_uuid_cell(new) : __get_name_cell(new); if (hc) { DMWARN("asked to rename to an already existing name %s -> %s", old, new); @@ -290,7 +290,7 @@ /* * Is there such a device as 'old' ? */ - hc = __get_name_cell(old); + hc = uuid_rename ? __get_uuid_cell(old) : __get_name_cell(old); if (!hc) { DMWARN("asked to rename a non existent device %s -> %s", old, new); @@ -301,14 +301,21 @@ /* * rename and move the name cell. */ - list_del(&hc->name_list); - old_name = hc->name; - hc->name = new_name; - list_add(&hc->name_list, _name_buckets + hash_str(new_name)); - - /* rename the device node in devfs */ - unregister_with_devfs(hc); - register_with_devfs(hc); + if (uuid_rename) { + list_del(&hc->uuid_list); + old_name = hc->uuid; + hc->uuid = new_name; + list_add(&hc->uuid_list, _name_buckets + hash_str(new_name)); + } else { + list_del(&hc->name_list); + old_name = hc->name; + hc->name = new_name; + list_add(&hc->name_list, _name_buckets + hash_str(new_name)); + + /* rename the device node in devfs */ + unregister_with_devfs(hc); + register_with_devfs(hc); + } up_write(&_hash_lock); kfree(old_name); @@ -909,6 +916,8 @@ static int rename(struct dm_ioctl *param, struct dm_ioctl *user) { int r; + int uuid_rename = (param->flags & DM_RENAME_UUID_FLAG); + char *old_name = (uuid_rename) ? param->uuid : param->name; char *new_name = (char *) param + param->data_start; if (valid_str(new_name, (void *) param, @@ -917,11 +926,13 @@ return -EINVAL; } - r = check_name(new_name); - if (r) - return r; + if (!uuid_rename) { + r = check_name(new_name); + if (r) + return r; + } - return dm_hash_rename(param->name, new_name); + return dm_hash_rename(old_name, new_name, uuid_rename); } /*----------------------------------------------------------------- --- linux-2.4.20a/include/linux/dm-ioctl.h 2003/01/10 16:49:14 +++ linux-2.4.20b/include/linux/dm-ioctl.h 2003/02/27 19:55:51 @@ -130,7 +130,7 @@ #define DM_TARGET_WAIT _IOWR(DM_IOCTL, DM_TARGET_WAIT_CMD, struct dm_ioctl) #define DM_VERSION_MAJOR 1 -#define DM_VERSION_MINOR 0 +#define DM_VERSION_MINOR 1 #define DM_VERSION_PATCHLEVEL 6 #define DM_VERSION_EXTRA "-ioctl (2002-10-15)" @@ -145,5 +145,11 @@ * rather than current status. */ #define DM_STATUS_TABLE_FLAG 0x00000010 + +/* + * Flag passed into ioctl RENAME command to change the uuid + * rather than the name. + */ +#define DM_RENAME_UUID_FLAG 0x00000020 #endif /* _LINUX_DM_IOCTL_H */