diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM index 9976a5c30..0485b6c43 100644 --- a/WHATS_NEW_DM +++ b/WHATS_NEW_DM @@ -1,5 +1,6 @@ Version 1.02.46 - ================================ + Add support for ioctl's DM_UEVENT_GENERATED_FLAG. Version 1.02.45 - 9th March 2010 ================================ diff --git a/libdm/ioctl/libdm-iface.c b/libdm/ioctl/libdm-iface.c index 4efb684b8..ace6d9642 100644 --- a/libdm/ioctl/libdm-iface.c +++ b/libdm/ioctl/libdm-iface.c @@ -1505,18 +1505,28 @@ static int _mknodes_v4(struct dm_task *dmt) */ static int _udev_complete(struct dm_task *dmt) { - uint32_t cookie; + uint16_t base; - if (dmt->cookie_set) { + if (dmt->cookie_set && + (base = dmt->event_nr & ~DM_UDEV_FLAGS_MASK)) /* strip flags from the cookie and use cookie magic instead */ - cookie = (dmt->event_nr & ~DM_UDEV_FLAGS_MASK) | - (DM_COOKIE_MAGIC << DM_UDEV_FLAGS_SHIFT); - return dm_udev_complete(cookie); - } + return dm_udev_complete(base | (DM_COOKIE_MAGIC << + DM_UDEV_FLAGS_SHIFT)); return 1; } +static int _check_uevent_generated(struct dm_ioctl *dmi) +{ + if (!dm_check_version() || + _dm_version < 4 || + _dm_version_minor < 17) + /* can't check, assume uevent is generated */ + return 1; + + return dmi->flags & DM_UEVENT_GENERATED_FLAG; +} + static int _create_and_load_v4(struct dm_task *dmt) { struct dm_task *task; @@ -1691,6 +1701,7 @@ static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command, unsigned repeat_count) { struct dm_ioctl *dmi; + int ioctl_with_uevent; dmi = _flatten(dmt, repeat_count); if (!dmi) { @@ -1706,6 +1717,10 @@ static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command, if (dmt->no_open_count) dmi->flags |= DM_SKIP_BDGET_FLAG; + ioctl_with_uevent = dmt->type == DM_DEVICE_RESUME || + dmt->type == DM_DEVICE_REMOVE || + dmt->type == DM_DEVICE_RENAME; + /* * Prevent udev vs. libdevmapper race when processing nodes and * symlinks. This can happen when the udev rules are installed and @@ -1715,10 +1730,7 @@ static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command, * to be applied at all in this situation so we can gracefully fallback * to libdevmapper's node and symlink creation code. */ - if (dm_udev_get_sync_support() && !dmt->cookie_set && - (dmt->type == DM_DEVICE_RESUME || - dmt->type == DM_DEVICE_REMOVE || - dmt->type == DM_DEVICE_RENAME)) { + if (dm_udev_get_sync_support() && !dmt->cookie_set && ioctl_with_uevent) { log_debug("Cookie value is not set while trying to call " "DM_DEVICE_RESUME, DM_DEVICE_REMOVE or DM_DEVICE_RENAME " "ioctl. Please, consider using libdevmapper's udev " @@ -1774,6 +1786,10 @@ static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command, return NULL; } } + + if (ioctl_with_uevent && !_check_uevent_generated(dmi)) + _udev_complete(dmt); + #else /* Userspace alternative for testing */ #endif return dmi; diff --git a/libdm/misc/dm-ioctl.h b/libdm/misc/dm-ioctl.h index 77979842b..a7b80f6a5 100644 --- a/libdm/misc/dm-ioctl.h +++ b/libdm/misc/dm-ioctl.h @@ -268,9 +268,9 @@ enum { #define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl) #define DM_VERSION_MAJOR 4 -#define DM_VERSION_MINOR 16 +#define DM_VERSION_MINOR 17 #define DM_VERSION_PATCHLEVEL 0 -#define DM_VERSION_EXTRA "-ioctl (2009-11-05)" +#define DM_VERSION_EXTRA "-ioctl (2010-03-05)" /* Status bits */ #define DM_READONLY_FLAG (1 << 0) /* In/Out */ @@ -318,4 +318,9 @@ enum { */ #define DM_QUERY_INACTIVE_TABLE_FLAG (1 << 12) /* In */ +/* + * If set, a uevent was generated for which the caller may need to wait. + */ +#define DM_UEVENT_GENERATED_FLAG (1 << 13) /* Out */ + #endif /* _LINUX_DM_IOCTL_H */