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.
#
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"
} 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;
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) {
--- /dev/null
+#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, ¶ms);
+ 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, ¶ms);
+ 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;
+}