Hello,

Phillip's recent device-mapper patch series reminded me one SUSE patch
(attached) which I wanted to post as a RFC for quite some time.

To make the story short: In SUSE, we have been bitten several times by
discrepancies between how parted and udev/kpartx create device nodes for
device mapper devices. Instead of keeping these in sync (which is one
of the goals of Phillip's patches IIUC), we decided to patch
parted so that it does not add/remove device-mapper devices on its own
and instead relies on udev/kpartx to do it (parted just issues 'change'
uevent on the device which has been changed).

The patch is in production since at least SLE11-SP1 (or maybe even
longer) and I'm not aware of any issues with it.

Reportedly, this patch fixes RH bug
https://bugzilla.redhat.com/show_bug.cgi?id=698121
to which I don't have access, though. CCing IBM guys who
should have more information about the background of this bug and who
tested the patch in their environment.

Please note that the attached patch is just a RFC, applies to
parted-2.4, contains ugly hack with system("udevadm settle") and also
misses removal of few functions which are no longer needed with this
patch.

The question is: Would this concept be acceptable for parted upstream?

Petr

--
Petr Uzel
IRC: ptr_uzl @ freenode
Index: parted-2.4/libparted/arch/linux.c
===================================================================
--- parted-2.4.orig/libparted/arch/linux.c
+++ parted-2.4/libparted/arch/linux.c
@@ -33,6 +33,7 @@
 #include <stdio.h>
 #include <syscall.h>
 #include <unistd.h>
+#include <stdlib.h>
 #include <stdbool.h>
 #include <dirent.h>
 #include <sys/ioctl.h>
@@ -2770,29 +2771,39 @@ err:
 static int
 _dm_reread_part_table (PedDisk* disk)
 {
-        int largest_partnum = ped_disk_get_last_partition_num (disk);
-        if (largest_partnum <= 0)
-          return 1;
-
-        int     rc = 1;
-        int     last = PED_MIN (largest_partnum, 16);
-        int     i;
+	int 		dev_minor;
+	int 		dev_major;
+	struct stat	dev_stat;
+	char		name_buf[40];
+	FILE*           f;
 
         sync();
-        if (!_dm_remove_parts(disk->dev))
-                rc = 0;
 
-        for (i = 1; i <= last; i++) {
-                PedPartition*      part;
+	/* Issue uevent for the device */
+	if (!_device_stat (disk->dev, &dev_stat))
+	    	return 0;
 
-                part = ped_disk_get_partition (disk, i);
-                if (!part)
-                        continue;
+	dev_major = major (dev_stat.st_rdev);
+	dev_minor = minor (dev_stat.st_rdev);
 
-                if (!_dm_add_partition (disk, part))
-                        rc = 0;
+	snprintf (name_buf, sizeof (name_buf),
+		  "/sys/dev/block/%d:%d/uevent", dev_major, dev_minor);
+
+	if ((f = fopen (name_buf, "w")) == NULL)
+		return 0;
+
+	if (fputs ("change", f) == EOF)
+		return 0;
+
+	fclose(f);
+
+	/* Wait for udev to finish */
+	if (system ("/sbin/udevadm settle --timeout=20") != 0) {
+		/* udevadm settle failed - let's sleep for a while */
+		sleep (2);
         }
-        return rc;
+
+        return 1;
 }
 #endif
 

Attachment: pgpJZrYu0f9nq.pgp
Description: PGP signature

Reply via email to