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
pgpJZrYu0f9nq.pgp
Description: PGP signature

