include a private program to export the device-mapper information we need
authorDavid Zeuthen <davidz@redhat.com>
Fri, 18 Jul 2008 16:47:33 +0000 (12:47 -0400)
committerDavid Zeuthen <davidz@redhat.com>
Fri, 18 Jul 2008 16:47:33 +0000 (12:47 -0400)
Can't wait anymore for this to land in device-mapper upstream

 https://bugzilla.redhat.com/show_bug.cgi?id=438604

We're using a separate name space for this so once this information
does land in device-mapper upstream we can use it from there.

configure.in
src/95-devkit-disks.rules
src/Makefile.am
src/devkit-disks-device.c
src/devkit-disks-dm-export.c [new file with mode: 0644]

index a0e550d..63c8985 100644 (file)
@@ -135,6 +135,10 @@ PKG_CHECK_MODULES(LIBPARTED, [libparted >= 1.8.8])
 AC_SUBST(LIBPARTED_CFLAGS)
 AC_SUBST(LIBPARTED_LIBS)
 
+PKG_CHECK_MODULES(DEVMAPPER, [devmapper >= 1.02])
+AC_SUBST(DEVMAPPER_CFLAGS)
+AC_SUBST(DEVMAPPER_LIBS)
+
 PKG_CHECK_MODULES(SQLITE3, [sqlite3])
 AC_SUBST(SQLITE3_CFLAGS)
 AC_SUBST(SQLITE3_LIBS)
index d19d76e..e3bf042 100644 (file)
@@ -43,9 +43,29 @@ ATTR{range}=="[0-9]*", ENV{PART_P1_TYPE}!="", ENV{ID_FS_USAGE}="", ENV{ID_FS_TYP
 
 LABEL="probe_parttable_end"
 
+# device-mapper stuff; this really needs to go to upstream
+#
+
+KERNEL!="dm-*", GOTO="device_mapper_end"
+ACTION!="add|change", GOTO="device_mapper_end"
+
+IMPORT{program}="devkit-disks-dm-export %M %m"
+ENV{DKD_DM_NAME}!="?*", GOTO="device_mapper_end"
+
+SYMLINK+="disk/by-id/dm-name-$env{DKD_DM_NAME}"
+ENV{DKD_DM_UUID}=="?*", SYMLINK+="disk/by-id/dm-uuid-$env{DKD_DM_UUID}"
+
+ENV{DKD_DM_STATE}=="SUSPENDED", GOTO="device_mapper_end"
+ENV{DKD_DM_TARGET_TYPES}=="|*error*", GOTO="device_mapper_end"
+
+IMPORT{program}="vol_id --export $tempnode"
+OPTIONS="link_priority=-100"
+ENV{DKD_DM_TARGET_TYPES}=="*snapshot-origin*", OPTIONS="link_priority=-90"
+ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}"
+ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}"
+
+LABEL="device_mapper_end"
 
-# pass all events to the DeviceKit disks daemon
-SUBSYSTEM=="block", RUN+="socket:/org/freedesktop/devicekit/disks/udev_event"
 
 # Temp hack because of jgarzik bug.. credit goes to Kay
 # Sievers for this. Thanks.
@@ -54,3 +74,7 @@ SUBSYSTEM=="block", RUN+="socket:/org/freedesktop/devicekit/disks/udev_event"
 #
 ACTION=="change", SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", PROGRAM="/bin/sh -c 'for i in /sys%p/block/*/uevent; do echo -n change > $$i; done'"
 ACTION=="add", SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", PROGRAM="/bin/chmod 0644 /sys%p/evt_media_change", ATTR{evt_media_change}="1"
+
+# finally pass all events to the DeviceKit disks daemon
+#
+SUBSYSTEM=="block", RUN+="socket:/org/freedesktop/devicekit/disks/udev_event"
index 417ddd7..c30e525 100644 (file)
@@ -122,11 +122,15 @@ devkit_disks_helper_fstab_mounter_LDADD = $(GLIB_LIBS)
 
 # TODO: move to udev
 udevhelperdir = $(slashlibdir)/udev
-udevhelper_PROGRAMS = part_id
+udevhelper_PROGRAMS = part_id devkit-disks-dm-export
 
 part_id_SOURCES = part-id.c
 part_id_CPPFLAGS = $(AM_CPPFLAGS)
 part_id_LDADD = $(GLIB_LIBS) $(top_builddir)/src/libpartutil.la
+
+devkit_disks_dm_export_SOURCES = devkit-disks-dm-export.c
+devkit_disks_dm_export_CPPFLAGS = $(AM_CPPFLAGS) $(DEVMAPPER_CFLAGS)
+devkit_disks_dm_export_LDADD = $(DEVMAPPER_LIBS)
 # end move to udev
 
 
index e649f31..bfe52da 100644 (file)
@@ -1488,7 +1488,7 @@ update_info_properties_cb (DevkitDevice *d, const char *key, const char *value,
         } else if (strcmp (key, "MD_EVENTS") == 0) {
                 device->priv->info.linux_md_component_events = devkit_device_get_property_as_uint64 (d, key);
 
-        } else if (strcmp (key, "DM_NAME") == 0) {
+        } else if (strcmp (key, "DKD_DM_NAME") == 0) {
                 if (g_str_has_prefix (value, "temporary-cryptsetup-")) {
                         /* ignore temporary devices created by /sbin/cryptsetup */
                         ignore_device = TRUE;
@@ -1504,7 +1504,7 @@ update_info_properties_cb (DevkitDevice *d, const char *key, const char *value,
                         device->priv->info.dm_name = g_strdup (value);
                 }
 
-        } else if (strcmp (key, "DM_TARGET_TYPES") == 0) {
+        } else if (strcmp (key, "DKD_DM_TARGET_TYPES") == 0) {
                 if (strcmp (value, "crypt") == 0) {
                         /* we're a dm-crypt target and can, by design, then only have one slave */
                         if (device->priv->info.slaves_objpath->len == 1) {
diff --git a/src/devkit-disks-dm-export.c b/src/devkit-disks-dm-export.c
new file mode 100644 (file)
index 0000000..91f7d9d
--- /dev/null
@@ -0,0 +1,148 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libdevmapper.h>
+
+static void
+usage (void)
+{
+        fprintf (stderr, "incorrect usage\n");
+}
+
+/* based on the export patch in https://bugzilla.redhat.com/show_bug.cgi?id=438604 */
+
+static int
+export (int major, int minor)
+{
+        int ret;
+        struct dm_task *dmt;
+        void *next;
+        uint64_t start, length;
+        char *target_type;
+        char *params;
+        const char *name;
+        const char *uuid;
+        struct dm_info info;
+
+        ret = 1;
+        dmt = NULL;
+
+        if (!(dmt = dm_task_create (DM_DEVICE_STATUS))) {
+                perror ("dm_task_create");
+                goto out;
+        }
+
+        if (!dm_task_set_major (dmt, major)) {
+                perror ("dm_task_set_major");
+                goto out;
+        }
+
+        if (!dm_task_set_minor (dmt, minor)) {
+                perror ("dm_task_set_minor");
+                goto out;
+        }
+
+        if (!dm_task_run(dmt)) {
+                perror ("dm_task_run");
+                goto out;
+        }
+
+        if (!dm_task_get_info (dmt, &info) || !info.exists) {
+                perror ("dm_task_get_info");
+                goto out;
+        }
+
+        if ((name = dm_task_get_name (dmt)) == NULL) {
+                perror ("dm_task_get_name");
+                goto out;
+        }
+
+        uuid = dm_task_get_uuid (dmt);
+
+        printf("DKD_DM_NAME=%s\n", name);
+
+        if ((uuid = dm_task_get_uuid (dmt)) && *uuid)
+                printf("DKD_DM_UUID=%s\n", uuid);
+
+        if (!info.exists) {
+                printf("DKD_DM_STATE=NOTPRESENT\n");
+                goto out;
+        }
+
+        printf("DKD_DM_STATE=%s\n",
+               info.suspended ? "SUSPENDED" :
+               (info.read_only ? " READONLY" : "ACTIVE"));
+
+        if (!info.live_table && !info.inactive_table)
+                printf("DKD_DM_TABLE_STATE=NONE\n");
+        else
+                printf("DKD_DM_TABLE_STATE=%s%s%s\n",
+                       info.live_table ? "LIVE" : "",
+                       info.live_table && info.inactive_table ? "/" : "",
+                       info.inactive_table ? "INACTIVE" : "");
+
+        if (info.open_count != -1)
+                printf("DKD_DM_OPENCOUNT=%d\n", info.open_count);
+
+        printf("DKD_DM_LAST_EVENT_NR=%" PRIu32 "\n", info.event_nr);
+
+        printf("DKD_DM_MAJOR=%d\n", info.major);
+        printf("DKD_DM_MINOR=%d\n", info.minor);
+
+        if (info.target_count != -1)
+                printf("DKD_DM_TARGET_COUNT=%d\n", info.target_count);
+
+        /* export all table types */
+        next = NULL;
+        next = dm_get_next_target (dmt, next, &start, &length, &target_type, &params);
+        if (target_type != NULL) {
+                printf("DKD_DM_TARGET_TYPES=%s", target_type);
+                while (next != NULL) {
+                        next = dm_get_next_target (dmt, next, &start, &length, &target_type, &params);
+                        if (target_type)
+                                printf(",%s", target_type);
+                }
+                printf("\n");
+        }
+
+        ret = 0;
+
+out:
+        if (dmt != NULL)
+                dm_task_destroy(dmt);
+        return ret;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+        int ret;
+        int major;
+        int minor;
+        char *endp;
+
+        ret = 1;
+
+        if (argc != 3) {
+                usage ();
+                goto out;
+        }
+
+        major = strtol (argv[1], &endp, 10);
+        if (endp == NULL || *endp != '\0') {
+                usage ();
+                goto out;
+        }
+
+        minor = strtol (argv[2], &endp, 10);
+        if (endp == NULL || *endp != '\0') {
+                usage ();
+                goto out;
+        }
+
+        ret = export (major, minor);
+
+out:
+        return ret;
+}