[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[dm-devel] RFC: UUID rename



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 */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]