1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-30 17:18:21 +03:00

Add udev flags support in libdevmapper and provide 'dmsetup udevflags' command to decode them.

This commit is contained in:
Peter Rajnoha 2009-10-22 12:55:47 +00:00
parent 70a0e7aba6
commit 5f1f31f942
6 changed files with 112 additions and 17 deletions

View File

@ -1,5 +1,7 @@
Version 1.02.39 -
=====================================
Add dmsetup udevflags command to decode udev flags in given cookie value.
Add udev flags support in libdevmapper.
Make libdm ABI consistent when built with/without selinux support.
Version 1.02.38 - 25th September 2009

View File

@ -1492,8 +1492,14 @@ static int _mknodes_v4(struct dm_task *dmt)
*/
static int _udev_complete(struct dm_task *dmt)
{
if (dmt->cookie_set)
return dm_udev_complete(dmt->event_nr);
uint32_t cookie;
if (dmt->cookie_set) {
/* 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 1;
}

View File

@ -164,7 +164,7 @@ int dm_task_set_major_minor(struct dm_task *dmt, int major, int minor, int allow
int dm_task_set_uid(struct dm_task *dmt, uid_t uid);
int dm_task_set_gid(struct dm_task *dmt, gid_t gid);
int dm_task_set_mode(struct dm_task *dmt, mode_t mode);
int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie);
int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags);
int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr);
int dm_task_set_geometry(struct dm_task *dmt, const char *cylinders, const char *heads, const char *sectors, const char *start);
int dm_task_set_message(struct dm_task *dmt, const char *message);
@ -1014,7 +1014,38 @@ int dm_report_field_uint64(struct dm_report *rh, struct dm_report_field *field,
void dm_report_field_set_value(struct dm_report_field *field, const void *value,
const void *sortvalue);
/* Cookie prefixes.
* The cookie value consists of a prefix (16 bits) and a base (16 bits).
* We can use the prefix to store the flags. These flags are sent to
* kernel within given dm task. When returned back to userspace in
* DM_COOKIE udev environment variable, we can control several aspects
* 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.
*/
#define DM_COOKIE_MAGIC 0x0D4D
#define DM_UDEV_FLAGS_MASK 0xFFFF0000
#define DM_UDEV_FLAGS_SHIFT 16
/*
* DM_UDEV_DISABLE_SUBSYTEM_RULES_FLAG is set in case we need to disable
* subsystem udev rules, but still we need the general DM udev rules to
* be applied (to create the nodes and symlinks under /dev and /dev/disk).
*/
#define DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG 0x0001
/*
* DM_UDEV_DISABLE_DISK_RULES_FLAG is set in case we need to disable
* general DM rules that set symlinks in /dev/disk directory.
*/
#define DM_UDEV_DISABLE_DISK_RULES_FLAG 0x0002
/*
* DM_UDEV_LOW_PRIORITY_FLAG is set in case we need to instruct the
* udev rules to give low priority to the device that is currently
* processed. For example, this provides a way to select which symlinks
* could be overwritten by high priority ones if their names are equal.
* Common situation is a name based on FS UUID while using origin and
* snapshot devices.
*/
#define DM_UDEV_LOW_PRIORITY_FLAG 0x0004
int dm_cookie_supported(void);

View File

@ -876,7 +876,7 @@ int dm_udev_get_sync_support(void)
return 0;
}
int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie)
int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags)
{
*cookie = 0;
@ -1129,7 +1129,7 @@ bad:
return 0;
}
int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie)
int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags)
{
int semid;
@ -1151,11 +1151,11 @@ int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie)
goto bad;
}
dmt->event_nr = *cookie;
dmt->event_nr = (0x0000FFFF & *cookie) | (flags << 16);
dmt->cookie_set = 1;
log_debug("Udev cookie 0x%" PRIx32 " (semid %d) assigned to dm_task",
dmt->event_nr, semid);
log_debug("Udev cookie 0x%" PRIx32 " (semid %d) assigned to dm_task "
"with flags 0x%" PRIx16, *cookie, semid, flags);
return 1;

View File

@ -841,7 +841,7 @@ static int _deactivate_node(const char *name, uint32_t major, uint32_t minor, ui
if (!dm_task_no_open_count(dmt))
log_error("Failed to disable open_count");
if (!dm_task_set_cookie(dmt, cookie))
if (!dm_task_set_cookie(dmt, cookie, 0))
goto out;
r = dm_task_run(dmt);
@ -881,7 +881,7 @@ static int _rename_node(const char *old_name, const char *new_name, uint32_t maj
if (!dm_task_no_open_count(dmt))
log_error("Failed to disable open_count");
if (!dm_task_set_cookie(dmt, cookie))
if (!dm_task_set_cookie(dmt, cookie, 0))
goto out;
r = dm_task_run(dmt);
@ -924,7 +924,7 @@ static int _resume_node(const char *name, uint32_t major, uint32_t minor,
if (!dm_task_set_read_ahead(dmt, read_ahead, read_ahead_flags))
log_error("Failed to set read ahead");
if (!dm_task_set_cookie(dmt, cookie))
if (!dm_task_set_cookie(dmt, cookie, 0))
goto out;
if ((r = dm_task_run(dmt)))

View File

@ -595,7 +595,7 @@ static int _create(int argc, char **argv, void *data __attribute((unused)))
if (_switches[NOTABLE_ARG])
dm_udev_set_sync_support(0);
if (!dm_task_set_cookie(dmt, &cookie) ||
if (!dm_task_set_cookie(dmt, &cookie, 0) ||
!dm_task_run(dmt))
goto out;
@ -630,7 +630,7 @@ static int _rename(int argc, char **argv, void *data __attribute((unused)))
if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))
goto out;
if (!dm_task_set_cookie(dmt, &cookie) ||
if (!dm_task_set_cookie(dmt, &cookie, 0) ||
!dm_task_run(dmt))
goto out;
@ -758,15 +758,70 @@ static int _splitname(int argc, char **argv, void *data __attribute((unused)))
return r;
}
static int _udevcomplete(int argc, char **argv, void *data __attribute((unused)))
static uint32_t _get_cookie_value(char *str_value)
{
uint32_t cookie;
unsigned long int value;
char *p;
if (!(cookie = (uint32_t) strtoul(argv[1], &p, 0)) || *p) {
if (!(value = strtoul(str_value, &p, 0)) ||
*p ||
(value == ULONG_MAX && errno == ERANGE) ||
value > 0xFFFFFFFF) {
err("Incorrect cookie value");
return 0;
}
else
return (uint32_t) value;
}
static int _udevflags(int args, char **argv, void *data __attribute((unused)))
{
uint32_t cookie;
uint16_t flags;
int i;
static const char *dm_flag_names[] = {"DISABLE_SUBSYSTEM_RULES",
"DISABLE_DISK_RULES",
"LOW_PRIORITY",
0, 0, 0, 0, 0};
if (!(cookie = _get_cookie_value(argv[1])))
return 0;
flags = cookie >> DM_UDEV_FLAGS_SHIFT;
for (i = 0; i < DM_UDEV_FLAGS_SHIFT; i++)
if (1 << i & flags) {
if (i < DM_UDEV_FLAGS_SHIFT / 2 && dm_flag_names[i])
printf("DM_UDEV_%s_FLAG='1'\n", dm_flag_names[i]);
else if (i < DM_UDEV_FLAGS_SHIFT / 2)
/*
* This is just a fallback. Each new DM flag
* should have its symbolic name assigned.
*/
printf("DM_UDEV_FLAG%d='1'\n", i);
else
/*
* We can't assign symbolic names to subsystem
* flags. Their semantics vary based on the
* subsystem that is currently used.
*/
printf("DM_SUBSYSTEM_UDEV_FLAG%d='1'\n",
i - DM_UDEV_FLAGS_SHIFT / 2);
}
return 1;
}
static int _udevcomplete(int argc, char **argv, void *data __attribute((unused)))
{
uint32_t cookie;
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);
return dm_udev_complete(cookie);
}
@ -953,7 +1008,7 @@ static int _simple(int task, const char *name, uint32_t event_nr, int display)
_read_ahead_flags))
goto out;
if (udev_wait_flag && !dm_task_set_cookie(dmt, &cookie))
if (udev_wait_flag && !dm_task_set_cookie(dmt, &cookie, 0))
goto out;
r = dm_task_run(dmt);
@ -2436,6 +2491,7 @@ static struct command _commands[] = {
{"table", "[<device>] [--target <target_type>] [--showkeys]", 0, 1, _status},
{"wait", "<device> [<event_nr>]", 0, 2, _wait},
{"mknodes", "[<device>]", 0, 1, _mknodes},
{"udevflags", "<cookie>", 1, 1, _udevflags},
{"udevcomplete", "<cookie>", 1, 1, _udevcomplete},
{"udevcomplete_all", "", 0, 0, _udevcomplete_all},
{"udevcookies", "", 0, 0, _udevcookies},