[lvm-devel] LVM2 ./WHATS_NEW_DM libdm/.exported_symbols li ...
prajnoha at sourceware.org
prajnoha at sourceware.org
Mon Feb 15 16:21:35 UTC 2010
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: prajnoha at sourceware.org 2010-02-15 16:21:34
Modified files:
. : WHATS_NEW_DM
libdm : .exported_symbols libdevmapper.h libdm-common.c
libdm/ioctl : libdm-iface.c
tools : dmsetup.c
Log message:
Several changes in dmsetup and libdevmapper:
- add DM_UDEV_DISABLE_LIBRARY_FALLBACK udev flag to rely on udev only
- export dm_udev_create_cookie function to create new cookies on demand
- add --udevcookie, udevcreatecookie and udevreleasecookie for dmsetup
(to support "udev transactions" where one cookie value can be used for
several dmsetup calls)
- don't use DM_UDEV_DISABLE_CHECKING env. var. anymore and set the state
automatically (based on udev and libdevmapper dev path comparison)
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW_DM.diff?cvsroot=lvm2&r1=1.343&r2=1.344
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/.exported_symbols.diff?cvsroot=lvm2&r1=1.48&r2=1.49
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/libdevmapper.h.diff?cvsroot=lvm2&r1=1.108&r2=1.109
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/libdm-common.c.diff?cvsroot=lvm2&r1=1.92&r2=1.93
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/ioctl/libdm-iface.c.diff?cvsroot=lvm2&r1=1.66&r2=1.67
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/dmsetup.c.diff?cvsroot=lvm2&r1=1.133&r2=1.134
--- LVM2/WHATS_NEW_DM 2010/02/02 14:09:17 1.343
+++ LVM2/WHATS_NEW_DM 2010/02/15 16:21:33 1.344
@@ -1,5 +1,9 @@
Version 1.02.44 -
===================================
+ Add DM_UDEV_DISABLE_LIBRARY_FALLBACK udev flag to rely on udev only.
+ Export dm_udev_create_cookie function to create new cookies on demand.
+ Add --udevcookie, udevcreatecookie and udevreleasecookie for dmsetup.
+ Don't use DM_UDEV_DISABLE_CHECKING env. var. anymore and set the state automatically.
Version 1.02.43 - 21st January 2010
===================================
--- LVM2/libdm/.exported_symbols 2010/01/13 01:39:45 1.48
+++ LVM2/libdm/.exported_symbols 2010/02/15 16:21:33 1.49
@@ -166,5 +166,6 @@
dm_udev_get_sync_support
dm_udev_set_checking
dm_udev_get_checking
+dm_udev_create_cookie
dm_udev_complete
dm_udev_wait
--- LVM2/libdm/libdevmapper.h 2010/01/14 10:15:23 1.108
+++ LVM2/libdm/libdevmapper.h 2010/02/15 16:21:33 1.109
@@ -1084,6 +1084,13 @@
* snapshot devices.
*/
#define DM_UDEV_LOW_PRIORITY_FLAG 0x0010
+/*
+ * DM_UDEV_DISABLE_LIBRARY_FALLBACK is set in case we need to disable
+ * libdevmapper's node management. We will rely on udev completely
+ * and there will be no fallback action provided by libdevmapper if
+ * udev does something improperly.
+ */
+#define DM_UDEV_DISABLE_LIBRARY_FALLBACK 0x0020
int dm_cookie_supported(void);
@@ -1094,6 +1101,7 @@
int dm_udev_get_sync_support(void);
void dm_udev_set_checking(int checking);
int dm_udev_get_checking(void);
+int dm_udev_create_cookie(uint32_t *cookie);
int dm_udev_complete(uint32_t cookie);
int dm_udev_wait(uint32_t cookie);
--- LVM2/libdm/libdm-common.c 2010/01/11 15:36:24 1.92
+++ LVM2/libdm/libdm-common.c 2010/02/15 16:21:33 1.93
@@ -1166,6 +1166,16 @@
return 0;
}
+int dm_udev_create_cookie(uint32_t *cookie)
+{
+ int semid;
+
+ if (!dm_udev_get_sync_support())
+ return 1;
+
+ return _udev_notify_sem_create(cookie, &semid);
+}
+
int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags)
{
int semid;
--- LVM2/libdm/ioctl/libdm-iface.c 2009/11/13 12:43:22 1.66
+++ LVM2/libdm/ioctl/libdm-iface.c 2010/02/15 16:21:34 1.67
@@ -1789,6 +1789,7 @@
struct dm_ioctl *dmi;
unsigned command;
int check_udev;
+ int udev_only;
#ifdef DM_COMPAT
if (_dm_version == 1)
@@ -1847,22 +1848,25 @@
!(dmt->event_nr >> DM_UDEV_FLAGS_SHIFT &
DM_UDEV_DISABLE_DM_RULES_FLAG);
+ udev_only = dmt->cookie_set ? (dmt->event_nr >> DM_UDEV_FLAGS_SHIFT &
+ DM_UDEV_DISABLE_LIBRARY_FALLBACK) : 0;
+
switch (dmt->type) {
case DM_DEVICE_CREATE:
- if (dmt->dev_name && *dmt->dev_name)
+ if (dmt->dev_name && *dmt->dev_name && !udev_only)
add_dev_node(dmt->dev_name, MAJOR(dmi->dev),
MINOR(dmi->dev), dmt->uid, dmt->gid,
dmt->mode, check_udev);
break;
case DM_DEVICE_REMOVE:
/* FIXME Kernel needs to fill in dmi->name */
- if (dmt->dev_name)
+ if (dmt->dev_name && !udev_only)
rm_dev_node(dmt->dev_name, check_udev);
break;
case DM_DEVICE_RENAME:
/* FIXME Kernel needs to fill in dmi->name */
- if (dmt->dev_name)
+ if (dmt->dev_name && !udev_only)
rename_dev_node(dmt->dev_name, dmt->newname,
check_udev);
break;
--- LVM2/tools/dmsetup.c 2010/01/14 10:15:23 1.133
+++ LVM2/tools/dmsetup.c 2010/02/15 16:21:34 1.134
@@ -45,6 +45,10 @@
# include <sys/types.h>
# include <sys/ipc.h>
# include <sys/sem.h>
+#ifdef HAVE_UDEV_QUEUE_GET_UDEV_IS_ACTIVE
+# define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE
+# include <libudev.h>
+#endif
#endif
/* FIXME Unused so far */
@@ -96,7 +100,10 @@
#define ARGS_MAX 256
#define LOOP_TABLE_SIZE (PATH_MAX + 255)
-#define DEFAULT_DM_DEV_DIR "/dev"
+#define DEFAULT_DM_DEV_DIR "/dev/"
+
+#define DM_DEV_DIR_ENV_VAR_NAME "DM_DEV_DIR"
+#define DM_UDEV_COOKIE_ENV_VAR_NAME "DM_UDEV_COOKIE"
/* FIXME Should be imported */
#ifndef DM_MAX_TYPE_NAME
@@ -127,6 +134,7 @@
NOLOCKFS_ARG,
NOOPENCOUNT_ARG,
NOTABLE_ARG,
+ UDEVCOOKIE_ARG,
NOUDEVRULES_ARG,
NOUDEVSYNC_ARG,
OPTIONS_ARG,
@@ -165,6 +173,8 @@
static char *_target;
static char *_command;
static uint32_t _read_ahead_flags;
+static uint32_t _udev_cookie;
+static int _udev_only;
static struct dm_tree *_dtree;
static struct dm_report *_report;
static report_type_t _report_type;
@@ -611,6 +621,12 @@
udev_flags |= DM_UDEV_DISABLE_DM_RULES_FLAG |
DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG;
+ if (_udev_cookie) {
+ cookie = _udev_cookie;
+ if (_udev_only)
+ udev_flags |= DM_UDEV_DISABLE_LIBRARY_FALLBACK;
+ }
+
if (!dm_task_set_cookie(dmt, &cookie, udev_flags) ||
!dm_task_run(dmt))
goto out;
@@ -621,7 +637,8 @@
r = _display_info(dmt);
out:
- (void) dm_udev_wait(cookie);
+ if (!_udev_cookie)
+ (void) dm_udev_wait(cookie);
dm_task_destroy(dmt);
return r;
@@ -654,6 +671,12 @@
udev_flags |= DM_UDEV_DISABLE_DM_RULES_FLAG |
DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG;
+ if (_udev_cookie) {
+ cookie = _udev_cookie;
+ if (_udev_only)
+ udev_flags |= DM_UDEV_DISABLE_LIBRARY_FALLBACK;
+ }
+
if (!dm_task_set_cookie(dmt, &cookie, udev_flags) ||
!dm_task_run(dmt))
goto out;
@@ -661,7 +684,8 @@
r = 1;
out:
- (void) dm_udev_wait(cookie);
+ if (!_udev_cookie)
+ (void) dm_udev_wait(cookie);
dm_task_destroy(dmt);
return r;
@@ -791,7 +815,7 @@
return r;
}
-static uint32_t _get_cookie_value(char *str_value)
+static uint32_t _get_cookie_value(const char *str_value)
{
unsigned long int value;
char *p;
@@ -817,7 +841,8 @@
"DISABLE_DISK_RULES",
"DISABLE_OTHER_RULES",
"LOW_PRIORITY",
- 0, 0, 0};
+ "DISABLE_LIBRARY_FALLBACK",
+ 0, 0};
if (!(cookie = _get_cookie_value(argv[1])))
return 0;
@@ -872,6 +897,22 @@
#ifndef UDEV_SYNC_SUPPORT
static const char _cmd_not_supported[] = "Command not supported. Recompile with \"--enable-udev-sync\" to enable.";
+static int _udevcreatecookie(int argc, char **argv,
+ void *data __attribute((unused)))
+{
+ log_error(_cmd_not_supported);
+
+ return 0;
+}
+
+static int _udevreleasecookie(int argc, char **argv,
+ void *data __attribute((unused)))
+{
+ log_error(_cmd_not_supported);
+
+ return 0;
+}
+
static int _udevcomplete_all(int argc __attribute((unused)), char **argv __attribute((unused)), void *data __attribute((unused)))
{
log_error(_cmd_not_supported);
@@ -887,6 +928,102 @@
}
#else /* UDEV_SYNC_SUPPORT */
+static int _set_up_udev_support(const char *dev_dir)
+{
+#ifdef HAVE_UDEV_QUEUE_GET_UDEV_IS_ACTIVE
+ struct udev *udev;
+ const char *udev_dev_dir;
+ size_t udev_dev_dir_len;
+ int dirs_diff;
+#endif
+ const char *env;
+
+ if (_switches[NOUDEVSYNC_ARG])
+ dm_udev_set_sync_support(0);
+
+ if (!_udev_cookie) {
+ env = getenv(DM_UDEV_COOKIE_ENV_VAR_NAME);
+ if (env && *env && (_udev_cookie = _get_cookie_value(env)))
+ log_debug("Using udev transaction 0x%08" PRIX32
+ " defined by %s environment variable.",
+ _udev_cookie,
+ DM_UDEV_COOKIE_ENV_VAR_NAME);
+ }
+ else if (_switches[UDEVCOOKIE_ARG])
+ log_debug("Using udev transaction 0x%08" PRIX32
+ " defined by --udevcookie option.",
+ _udev_cookie);
+
+#ifdef HAVE_UDEV_QUEUE_GET_UDEV_IS_ACTIVE
+ if (!(udev = udev_new()) ||
+ !(udev_dev_dir = udev_get_dev_path(udev)) ||
+ !*udev_dev_dir) {
+ log_error("Could not get udev dev path.");
+ return 0;
+ }
+ udev_dev_dir_len = strlen(udev_dev_dir);
+
+ /*
+ * Normally, there's always a fallback action by libdevmapper if udev
+ * has not done its job correctly, e.g. the nodes were not created.
+ * If using udev transactions by specifying existing cookie value,
+ * we need to disable node creation by libdevmapper completely,
+ * disabling any fallback actions, since any synchronisation happens
+ * at the end of the transaction only. We need to do this to prevent
+ * races between udev and libdevmapper but only in case udev "dev path"
+ * is the same as "dev path" used by libdevmapper.
+ */
+
+ /* There's always a slash at the end of dev_dir. But check udev_dev_dir! */
+ if (udev_dev_dir[udev_dev_dir_len - 1] != '/')
+ dirs_diff = strncmp(dev_dir, udev_dev_dir, udev_dev_dir_len);
+ else
+ dirs_diff = strcmp(dev_dir, udev_dev_dir);
+
+ _udev_only = _udev_cookie && !dirs_diff;
+
+ if (dirs_diff) {
+ log_debug("The path %s used for creating device nodes that is "
+ "set via DM_DEV_DIR environment variable differs from "
+ "the path %s that is used by udev. All warnings "
+ "about udev not working correctly while processing "
+ "particular nodes will be suppressed. These nodes "
+ "and symlinks will be managed in each directory "
+ "separately.", dev_dir, udev_dev_dir);
+ dm_udev_set_checking(0);
+ }
+
+ udev_unref(udev);
+#endif
+ return 1;
+}
+
+static int _udevcreatecookie(int argc, char **argv,
+ void *data __attribute((unused)))
+{
+ uint32_t cookie;
+
+ if (!dm_udev_create_cookie(&cookie))
+ return 0;
+
+ printf("0x%08" PRIX32 "\n", cookie);
+
+ return 1;
+}
+
+static int _udevreleasecookie(int argc, char **argv,
+ void *data __attribute((unused)))
+{
+ if (argv[1] && !(_udev_cookie = _get_cookie_value(argv[1])))
+ return 0;
+
+ if (!_udev_cookie) {
+ log_error("No udev transaction cookie given.");
+ return 0;
+ }
+
+ return dm_udev_wait(_udev_cookie);
+}
static char _yes_no_prompt(const char *prompt, ...)
{
@@ -1059,6 +1196,12 @@
udev_flags |= DM_UDEV_DISABLE_DM_RULES_FLAG |
DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG;
+ if (_udev_cookie) {
+ cookie = _udev_cookie;
+ if (_udev_only)
+ udev_flags |= DM_UDEV_DISABLE_LIBRARY_FALLBACK;
+ }
+
if (udev_wait_flag && !dm_task_set_cookie(dmt, &cookie, udev_flags))
goto out;
@@ -1068,7 +1211,7 @@
r = _display_info(dmt);
out:
- if (udev_wait_flag)
+ if (!_udev_cookie && udev_wait_flag)
(void) dm_udev_wait(cookie);
dm_task_destroy(dmt);
@@ -2559,6 +2702,8 @@
{"table", "[<device>] [--target <target_type>] [--showkeys]", 0, 1, _status},
{"wait", "<device> [<event_nr>]", 0, 2, _wait},
{"mknodes", "[<device>]", 0, 1, _mknodes},
+ {"udevcreatecookie", "", 0, 0, _udevcreatecookie},
+ {"udevreleasecookie", "[<cookie>]", 0, 1, _udevreleasecookie},
{"udevflags", "<cookie>", 1, 1, _udevflags},
{"udevcomplete", "<cookie>", 1, 1, _udevcomplete},
{"udevcomplete_all", "", 0, 0, _udevcomplete_all},
@@ -2577,7 +2722,7 @@
fprintf(out, "Usage:\n\n");
fprintf(out, "dmsetup [--version] [-v|--verbose [-v|--verbose ...]]\n"
" [-r|--readonly] [--noopencount] [--nolockfs] [--inactive]\n"
- " [--noudevrules] [--noudevsync] [-y|--yes]\n"
+ " [--udevcookie] [--noudevrules] [--noudevsync] [-y|--yes]\n"
" [--readahead [+]<sectors>|auto|none]\n"
" [-c|-C|--columns] [-o <fields>] [-O|--sort <sort_fields>]\n"
" [--nameprefixes] [--noheadings] [--separator <separator>]\n\n");
@@ -2812,6 +2957,8 @@
return 0;
}
+
+
static int _process_losetup_switches(const char *base, int *argc, char ***argv,
const char *dev_dir)
{
@@ -2946,6 +3093,7 @@
{"nolockfs", 0, &ind, NOLOCKFS_ARG},
{"noopencount", 0, &ind, NOOPENCOUNT_ARG},
{"notable", 0, &ind, NOTABLE_ARG},
+ {"udevcookie", 1, &ind, UDEVCOOKIE_ARG},
{"noudevrules", 0, &ind, NOUDEVRULES_ARG},
{"noudevsync", 0, &ind, NOUDEVSYNC_ARG},
{"options", 1, &ind, OPTIONS_ARG},
@@ -3059,6 +3207,10 @@
}
if (c == 'y' || ind == YES_ARG)
_switches[YES_ARG]++;
+ if (ind == UDEVCOOKIE_ARG) {
+ _switches[UDEVCOOKIE_ARG]++;
+ _udev_cookie = _get_cookie_value(optarg);
+ }
if (ind == NOUDEVRULES_ARG)
_switches[NOUDEVRULES_ARG]++;
if (ind == NOUDEVSYNC_ARG)
@@ -3160,11 +3312,10 @@
struct command *c;
int r = 1;
const char *dev_dir;
- const char *disable_udev_checking;
(void) setlocale(LC_ALL, "");
- dev_dir = getenv ("DM_DEV_DIR");
+ dev_dir = getenv (DM_DEV_DIR_ENV_VAR_NAME);
if (dev_dir && *dev_dir) {
if (!dm_set_dev_dir(dev_dir)) {
fprintf(stderr, "Invalid DM_DEV_DIR environment variable value.\n");
@@ -3207,13 +3358,10 @@
if (_switches[COLS_ARG] && !_report_init(c))
goto out;
- if (_switches[NOUDEVSYNC_ARG])
- dm_udev_set_sync_support(0);
-
- disable_udev_checking = getenv("DM_UDEV_DISABLE_CHECKING");
- if ((disable_udev_checking && *disable_udev_checking) &&
- !strcmp(disable_udev_checking, "1"))
- dm_udev_set_checking(0);
+ #ifdef UDEV_SYNC_SUPPORT
+ if (!_set_up_udev_support(dev_dir))
+ goto out;
+ #endif
doit:
if (!c->fn(argc, argv, NULL)) {
More information about the lvm-devel
mailing list