1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-02 01:18:26 +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 - 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. Make libdm ABI consistent when built with/without selinux support.
Version 1.02.38 - 25th September 2009 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) static int _udev_complete(struct dm_task *dmt)
{ {
if (dmt->cookie_set) uint32_t cookie;
return dm_udev_complete(dmt->event_nr);
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; 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_uid(struct dm_task *dmt, uid_t uid);
int dm_task_set_gid(struct dm_task *dmt, gid_t gid); 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_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_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_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); 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, void dm_report_field_set_value(struct dm_report_field *field, const void *value,
const void *sortvalue); 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_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); int dm_cookie_supported(void);

View File

@ -876,7 +876,7 @@ int dm_udev_get_sync_support(void)
return 0; 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; *cookie = 0;
@ -1129,7 +1129,7 @@ bad:
return 0; 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; int semid;
@ -1151,11 +1151,11 @@ int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie)
goto bad; goto bad;
} }
dmt->event_nr = *cookie; dmt->event_nr = (0x0000FFFF & *cookie) | (flags << 16);
dmt->cookie_set = 1; dmt->cookie_set = 1;
log_debug("Udev cookie 0x%" PRIx32 " (semid %d) assigned to dm_task", log_debug("Udev cookie 0x%" PRIx32 " (semid %d) assigned to dm_task "
dmt->event_nr, semid); "with flags 0x%" PRIx16, *cookie, semid, flags);
return 1; 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)) if (!dm_task_no_open_count(dmt))
log_error("Failed to disable open_count"); log_error("Failed to disable open_count");
if (!dm_task_set_cookie(dmt, cookie)) if (!dm_task_set_cookie(dmt, cookie, 0))
goto out; goto out;
r = dm_task_run(dmt); 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)) if (!dm_task_no_open_count(dmt))
log_error("Failed to disable open_count"); log_error("Failed to disable open_count");
if (!dm_task_set_cookie(dmt, cookie)) if (!dm_task_set_cookie(dmt, cookie, 0))
goto out; goto out;
r = dm_task_run(dmt); 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)) if (!dm_task_set_read_ahead(dmt, read_ahead, read_ahead_flags))
log_error("Failed to set read ahead"); log_error("Failed to set read ahead");
if (!dm_task_set_cookie(dmt, cookie)) if (!dm_task_set_cookie(dmt, cookie, 0))
goto out; goto out;
if ((r = dm_task_run(dmt))) 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]) if (_switches[NOTABLE_ARG])
dm_udev_set_sync_support(0); 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)) !dm_task_run(dmt))
goto out; 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)) if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))
goto out; goto out;
if (!dm_task_set_cookie(dmt, &cookie) || if (!dm_task_set_cookie(dmt, &cookie, 0) ||
!dm_task_run(dmt)) !dm_task_run(dmt))
goto out; goto out;
@ -758,15 +758,70 @@ static int _splitname(int argc, char **argv, void *data __attribute((unused)))
return r; 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; 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"); err("Incorrect cookie value");
return 0; 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); 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)) _read_ahead_flags))
goto out; 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; goto out;
r = dm_task_run(dmt); r = dm_task_run(dmt);
@ -2436,6 +2491,7 @@ static struct command _commands[] = {
{"table", "[<device>] [--target <target_type>] [--showkeys]", 0, 1, _status}, {"table", "[<device>] [--target <target_type>] [--showkeys]", 0, 1, _status},
{"wait", "<device> [<event_nr>]", 0, 2, _wait}, {"wait", "<device> [<event_nr>]", 0, 2, _wait},
{"mknodes", "[<device>]", 0, 1, _mknodes}, {"mknodes", "[<device>]", 0, 1, _mknodes},
{"udevflags", "<cookie>", 1, 1, _udevflags},
{"udevcomplete", "<cookie>", 1, 1, _udevcomplete}, {"udevcomplete", "<cookie>", 1, 1, _udevcomplete},
{"udevcomplete_all", "", 0, 0, _udevcomplete_all}, {"udevcomplete_all", "", 0, 0, _udevcomplete_all},
{"udevcookies", "", 0, 0, _udevcookies}, {"udevcookies", "", 0, 0, _udevcookies},