diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM index dca6df6c6..836d10dd5 100644 --- a/WHATS_NEW_DM +++ b/WHATS_NEW_DM @@ -1,5 +1,6 @@ Version 1.02.40 - =================================== + Support udev flags even when udev_sync is disabled or not compiled in. Remove 'last_rule' from udev rules: honor ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}. Add dmsetup --inactive support. Add dm_task_query_inactive_table to libdevmapper for kernel driver >= 4.16. diff --git a/libdm/ioctl/libdm-iface.c b/libdm/ioctl/libdm-iface.c index 6e6446f6e..0a8cce120 100644 --- a/libdm/ioctl/libdm-iface.c +++ b/libdm/ioctl/libdm-iface.c @@ -1548,6 +1548,7 @@ static int _create_and_load_v4(struct dm_task *dmt) task->gid = dmt->gid; task->mode = dmt->mode; /* FIXME: Just for udev_check in dm_task_run. Can we avoid this? */ + task->event_nr = dmt->event_nr & DM_UDEV_FLAGS_MASK; task->cookie_set = dmt->cookie_set; r = dm_task_run(task); diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h index 598a5f475..c6546a63b 100644 --- a/libdm/libdevmapper.h +++ b/libdm/libdevmapper.h @@ -1032,6 +1032,10 @@ void dm_report_field_set_value(struct dm_report_field *field, const void *value, * of udev rules we use by decoding the cookie prefix. When doing the * notification, we replace the cookie prefix with DM_COOKIE_MAGIC, * so we notify the right semaphore. + * It is still possible to use cookies for passing the flags to udev + * rules even when udev_sync is disabled. The base part of the cookie + * will be zero (there's no notification semaphore) and prefix will be + * set then. However, having udev_sync enabled is highly recommended. */ #define DM_COOKIE_MAGIC 0x0D4D #define DM_UDEV_FLAGS_MASK 0xFFFF0000 @@ -1076,7 +1080,7 @@ void dm_report_field_set_value(struct dm_report_field *field, const void *value, int dm_cookie_supported(void); /* - * Udev notification functions. + * Udev synchronisation functions. */ void dm_udev_set_sync_support(int sync_with_udev); int dm_udev_get_sync_support(void); diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c index 121f02005..43ef63adb 100644 --- a/libdm/libdm-common.c +++ b/libdm/libdm-common.c @@ -886,6 +886,8 @@ int dm_udev_get_sync_support(void) int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags) { + if (dm_cookie_supported()) + dmt->event_nr = flags << DM_UDEV_FLAGS_SHIFT; *cookie = 0; return 1; @@ -1141,8 +1143,11 @@ int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags) { int semid; + if (dm_cookie_supported()) + dmt->event_nr = flags << DM_UDEV_FLAGS_SHIFT; + if (!dm_udev_get_sync_support()) { - dmt->event_nr = *cookie = 0; + *cookie = 0; return 1; } @@ -1159,8 +1164,7 @@ int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags) goto bad; } - dmt->event_nr = (~DM_UDEV_FLAGS_MASK & *cookie) | - (flags << DM_UDEV_FLAGS_SHIFT); + dmt->event_nr |= ~DM_UDEV_FLAGS_MASK & *cookie; dmt->cookie_set = 1; log_debug("Udev cookie 0x%" PRIx32 " (semid %d) assigned to dm_task " diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c index c98fb3474..1465fd345 100644 --- a/libdm/libdm-deptree.c +++ b/libdm/libdm-deptree.c @@ -1039,7 +1039,7 @@ int dm_tree_deactivate_children(struct dm_tree_node *dnode, continue; if (!_deactivate_node(name, info.major, info.minor, - &dnode->dtree->cookie, dnode->udev_flags)) { + &child->dtree->cookie, child->udev_flags)) { log_error("Unable to deactivate %s (%" PRIu32 ":%" PRIu32 ")", name, info.major, info.minor); diff --git a/tools/dmsetup.c b/tools/dmsetup.c index 186f8f0c3..888edffb1 100644 --- a/tools/dmsetup.c +++ b/tools/dmsetup.c @@ -843,9 +843,17 @@ static int _udevcomplete(int argc, char **argv, void *data __attribute((unused)) if (!(cookie = _get_cookie_value(argv[1]))) return 0; - /* strip flags from the cookie and use cookie magic instead */ - cookie = (cookie & ~DM_UDEV_FLAGS_MASK) | - (DM_COOKIE_MAGIC << DM_UDEV_FLAGS_SHIFT); + /* + * Strip flags from the cookie and use cookie magic instead. + * If the cookie has non-zero prefix and the base is zero then + * this one carries flags to control udev rules only and it is + * not meant to be for notification. Return with success in this + * situation. + */ + if (!(cookie &= ~DM_UDEV_FLAGS_MASK)) + return 1; + + cookie |= DM_COOKIE_MAGIC << DM_UDEV_FLAGS_SHIFT; return dm_udev_complete(cookie); }