1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-22 17:35:59 +03:00

Move udev_only logic inside stacked node op code.

(We still need to treat add+readhead+del as a no-op.)
Rename udev_fallback to verify_udev_operations.
Rename --udevfallback to --verifyudev
This commit is contained in:
Alasdair Kergon 2011-06-27 21:43:58 +00:00
parent 1a3dab6075
commit ea687806b3
11 changed files with 110 additions and 86 deletions

View File

@ -3,7 +3,7 @@ Version 2.02.86 -
Fix to preserve exclusive activation of mirror while up-converting. Fix to preserve exclusive activation of mirror while up-converting.
Reject allocation if number of extents is not divisible by area count. Reject allocation if number of extents is not divisible by area count.
Fix issue preventing cluster mirror creation. Fix issue preventing cluster mirror creation.
Disable udev fallback by default and add activation/udev_fallback to lvm.conf. Add activation/verify_udev_operations to lvm.conf, disabled by default.
Call vg_mark_partial_lvs() before VG structure is returned from the cache. Call vg_mark_partial_lvs() before VG structure is returned from the cache.
Remove unused internal flag ACTIVATE_EXCL from the code. Remove unused internal flag ACTIVATE_EXCL from the code.
Remove useless test of ACTIVATE_EXCL in lv_add_mirrors() clustered code path. Remove useless test of ACTIVATE_EXCL in lv_add_mirrors() clustered code path.

View File

@ -1,7 +1,7 @@
Version 1.02.65 - Version 1.02.65 -
================================== ==================================
Return immediately dm_lib_exit() if called more than once. Return immediately from dm_lib_exit() if called more than once.
Disable udev fallback by default and add --udevfallback option to dmsetup. Disable udev fallback by default and add --verifyudev option to dmsetup.
Warn if a table is loaded while a device is known to be in suspended state. Warn if a table is loaded while a device is known to be in suspended state.
Add dm_get_suspended_counter() for number of devs in suspended state by lib. Add dm_get_suspended_counter() for number of devs in suspended state by lib.
Fix "all" report field prefix matching to include label fields with pv_all. Fix "all" report field prefix matching to include label fields with pv_all.

View File

@ -428,12 +428,11 @@ activation {
# while any logical volumes are active. # while any logical volumes are active.
udev_rules = 1 udev_rules = 1
# Set to 1 to enable udev fallback. This will enable additional checks and # Set to 1 for LVM2 to verify operations performed by udev. This turns on
# possible repairs done on entries in the device directory after udev has # additional checks (and if necessary, repairs) on entries in the device
# completed processing the events. This is normally not needed if udev # directory after udev has completed processing its events.
# works correctly but it may be used in some problematic situations or # Useful for diagnosing problems with LVM2/udev interactions.
# for debugging purposes. verify_udev_operations = 0
udev_fallback = 0
# How to fill in missing stripes if activating an incomplete volume. # How to fill in missing stripes if activating an incomplete volume.
# Using "error" will make inaccessible parts of the device return # Using "error" will make inaccessible parts of the device return

View File

@ -293,8 +293,8 @@ static int _process_config(struct cmd_context *cmd)
* without any fallback. * without any fallback.
*/ */
cmd->default_settings.udev_fallback = cmd->default_settings.udev_rules ? cmd->default_settings.udev_fallback = cmd->default_settings.udev_rules ?
find_config_tree_int(cmd, "activation/udev_fallback", find_config_tree_int(cmd, "activation/verify_udev_operations",
DEFAULT_UDEV_FALLBACK) : 1; DEFAULT_VERIFY_UDEV_OPERATIONS) : 1;
#else #else
/* We must use old node/symlink creation code if not compiled with udev support at all! */ /* We must use old node/symlink creation code if not compiled with udev support at all! */
cmd->default_settings.udev_fallback = 1; cmd->default_settings.udev_fallback = 1;

View File

@ -78,7 +78,7 @@
#define DEFAULT_READ_AHEAD "auto" #define DEFAULT_READ_AHEAD "auto"
#define DEFAULT_UDEV_RULES 1 #define DEFAULT_UDEV_RULES 1
#define DEFAULT_UDEV_SYNC 0 #define DEFAULT_UDEV_SYNC 0
#define DEFAULT_UDEV_FALLBACK 0 #define DEFAULT_VERIFY_UDEV_OPERATIONS 0
#define DEFAULT_EXTENT_SIZE 4096 /* In KB */ #define DEFAULT_EXTENT_SIZE 4096 /* In KB */
#define DEFAULT_MAX_PV 0 #define DEFAULT_MAX_PV 0
#define DEFAULT_MAX_LV 0 #define DEFAULT_MAX_LV 0

View File

@ -2025,7 +2025,7 @@ int dm_task_run(struct dm_task *dmt)
struct dm_ioctl *dmi; struct dm_ioctl *dmi;
unsigned command; unsigned command;
int check_udev; int check_udev;
int udev_only; int rely_on_udev;
int suspended_counter; int suspended_counter;
#ifdef DM_COMPAT #ifdef DM_COMPAT
@ -2097,40 +2097,43 @@ repeat_ioctl:
} }
} }
/*
* Are we expecting a udev operation to occur that we need to check for?
*/
check_udev = dmt->cookie_set && check_udev = dmt->cookie_set &&
!(dmt->event_nr >> DM_UDEV_FLAGS_SHIFT & !(dmt->event_nr >> DM_UDEV_FLAGS_SHIFT &
DM_UDEV_DISABLE_DM_RULES_FLAG); DM_UDEV_DISABLE_DM_RULES_FLAG);
udev_only = dmt->cookie_set ? (dmt->event_nr >> DM_UDEV_FLAGS_SHIFT & rely_on_udev = dmt->cookie_set ? (dmt->event_nr >> DM_UDEV_FLAGS_SHIFT &
DM_UDEV_DISABLE_LIBRARY_FALLBACK) : 0; DM_UDEV_DISABLE_LIBRARY_FALLBACK) : 0;
switch (dmt->type) { switch (dmt->type) {
case DM_DEVICE_CREATE: case DM_DEVICE_CREATE:
if ((dmt->add_node == DM_ADD_NODE_ON_CREATE) && if ((dmt->add_node == DM_ADD_NODE_ON_CREATE) &&
dmt->dev_name && *dmt->dev_name && !udev_only) dmt->dev_name && *dmt->dev_name && !rely_on_udev)
add_dev_node(dmt->dev_name, MAJOR(dmi->dev), add_dev_node(dmt->dev_name, MAJOR(dmi->dev),
MINOR(dmi->dev), dmt->uid, dmt->gid, MINOR(dmi->dev), dmt->uid, dmt->gid,
dmt->mode, check_udev); dmt->mode, check_udev, rely_on_udev);
break; break;
case DM_DEVICE_REMOVE: case DM_DEVICE_REMOVE:
/* FIXME Kernel needs to fill in dmi->name */ /* FIXME Kernel needs to fill in dmi->name */
if (dmt->dev_name && !udev_only) if (dmt->dev_name && !rely_on_udev)
rm_dev_node(dmt->dev_name, check_udev); rm_dev_node(dmt->dev_name, check_udev, rely_on_udev);
break; break;
case DM_DEVICE_RENAME: case DM_DEVICE_RENAME:
/* FIXME Kernel needs to fill in dmi->name */ /* FIXME Kernel needs to fill in dmi->name */
if (!dmt->new_uuid && dmt->dev_name && !udev_only) if (!dmt->new_uuid && dmt->dev_name)
rename_dev_node(dmt->dev_name, dmt->newname, rename_dev_node(dmt->dev_name, dmt->newname,
check_udev); check_udev, rely_on_udev);
break; break;
case DM_DEVICE_RESUME: case DM_DEVICE_RESUME:
if ((dmt->add_node == DM_ADD_NODE_ON_RESUME) && if ((dmt->add_node == DM_ADD_NODE_ON_RESUME) &&
dmt->dev_name && *dmt->dev_name && !udev_only) dmt->dev_name && *dmt->dev_name)
add_dev_node(dmt->dev_name, MAJOR(dmi->dev), add_dev_node(dmt->dev_name, MAJOR(dmi->dev),
MINOR(dmi->dev), dmt->uid, dmt->gid, MINOR(dmi->dev), dmt->uid, dmt->gid,
dmt->mode, check_udev); dmt->mode, check_udev, rely_on_udev);
/* FIXME Kernel needs to fill in dmi->name */ /* FIXME Kernel needs to fill in dmi->name */
set_dev_node_read_ahead(dmt->dev_name, dmt->read_ahead, set_dev_node_read_ahead(dmt->dev_name, dmt->read_ahead,
dmt->read_ahead_flags); dmt->read_ahead_flags);
@ -2140,9 +2143,9 @@ repeat_ioctl:
if (dmi->flags & DM_EXISTS_FLAG) if (dmi->flags & DM_EXISTS_FLAG)
add_dev_node(dmi->name, MAJOR(dmi->dev), add_dev_node(dmi->name, MAJOR(dmi->dev),
MINOR(dmi->dev), dmt->uid, MINOR(dmi->dev), dmt->uid,
dmt->gid, dmt->mode, 0); dmt->gid, dmt->mode, 0, rely_on_udev);
else if (dmt->dev_name) else if (dmt->dev_name)
rm_dev_node(dmt->dev_name, 0); rm_dev_node(dmt->dev_name, 0, rely_on_udev);
break; break;
case DM_DEVICE_STATUS: case DM_DEVICE_STATUS:

View File

@ -501,8 +501,13 @@ void selinux_release(void)
#endif #endif
} }
static int _warn_if_op_needed(int warn_if_udev_failed)
{
return warn_if_udev_failed && dm_udev_get_sync_support() && dm_udev_get_checking();
}
static int _add_dev_node(const char *dev_name, uint32_t major, uint32_t minor, static int _add_dev_node(const char *dev_name, uint32_t major, uint32_t minor,
uid_t uid, gid_t gid, mode_t mode, int check_udev) uid_t uid, gid_t gid, mode_t mode, int warn_if_udev_failed)
{ {
char path[PATH_MAX]; char path[PATH_MAX];
struct stat info; struct stat info;
@ -527,8 +532,7 @@ static int _add_dev_node(const char *dev_name, uint32_t major, uint32_t minor,
dev_name); dev_name);
return 0; return 0;
} }
} else if (dm_udev_get_sync_support() && dm_udev_get_checking() && } else if (_warn_if_op_needed(warn_if_udev_failed))
check_udev)
log_warn("%s not set up by udev: Falling back to direct " log_warn("%s not set up by udev: Falling back to direct "
"node creation.", path); "node creation.", path);
@ -553,7 +557,7 @@ static int _add_dev_node(const char *dev_name, uint32_t major, uint32_t minor,
return 1; return 1;
} }
static int _rm_dev_node(const char *dev_name, int check_udev) static int _rm_dev_node(const char *dev_name, int warn_if_udev_failed)
{ {
char path[PATH_MAX]; char path[PATH_MAX];
struct stat info; struct stat info;
@ -562,8 +566,7 @@ static int _rm_dev_node(const char *dev_name, int check_udev)
if (stat(path, &info) < 0) if (stat(path, &info) < 0)
return 1; return 1;
else if (dm_udev_get_sync_support() && dm_udev_get_checking() && else if (_warn_if_op_needed(warn_if_udev_failed))
check_udev)
log_warn("Node %s was not removed by udev. " log_warn("Node %s was not removed by udev. "
"Falling back to direct node removal.", path); "Falling back to direct node removal.", path);
@ -578,7 +581,7 @@ static int _rm_dev_node(const char *dev_name, int check_udev)
} }
static int _rename_dev_node(const char *old_name, const char *new_name, static int _rename_dev_node(const char *old_name, const char *new_name,
int check_udev) int warn_if_udev_failed)
{ {
char oldpath[PATH_MAX]; char oldpath[PATH_MAX];
char newpath[PATH_MAX]; char newpath[PATH_MAX];
@ -593,8 +596,7 @@ static int _rename_dev_node(const char *old_name, const char *new_name,
"is already present", newpath); "is already present", newpath);
return 0; return 0;
} }
else if (dm_udev_get_sync_support() && dm_udev_get_checking() && else if (_warn_if_op_needed(warn_if_udev_failed)) {
check_udev) {
if (stat(oldpath, &info) < 0 && if (stat(oldpath, &info) < 0 &&
errno == ENOENT) errno == ENOENT)
/* assume udev already deleted this */ /* assume udev already deleted this */
@ -618,8 +620,7 @@ static int _rename_dev_node(const char *old_name, const char *new_name,
return 0; return 0;
} }
} }
else if (dm_udev_get_sync_support() && dm_udev_get_checking() && else if (_warn_if_op_needed(warn_if_udev_failed))
check_udev)
log_warn("The node %s should have been renamed to %s " log_warn("The node %s should have been renamed to %s "
"by udev but new node is not present. " "by udev but new node is not present. "
"Falling back to direct node rename.", "Falling back to direct node rename.",
@ -759,16 +760,16 @@ typedef enum {
static int _do_node_op(node_op_t type, const char *dev_name, uint32_t major, static int _do_node_op(node_op_t type, const char *dev_name, uint32_t major,
uint32_t minor, uid_t uid, gid_t gid, mode_t mode, uint32_t minor, uid_t uid, gid_t gid, mode_t mode,
const char *old_name, uint32_t read_ahead, const char *old_name, uint32_t read_ahead,
uint32_t read_ahead_flags, int check_udev) uint32_t read_ahead_flags, int warn_if_udev_failed)
{ {
switch (type) { switch (type) {
case NODE_ADD: case NODE_ADD:
return _add_dev_node(dev_name, major, minor, uid, gid, return _add_dev_node(dev_name, major, minor, uid, gid,
mode, check_udev); mode, warn_if_udev_failed);
case NODE_DEL: case NODE_DEL:
return _rm_dev_node(dev_name, check_udev); return _rm_dev_node(dev_name, warn_if_udev_failed);
case NODE_RENAME: case NODE_RENAME:
return _rename_dev_node(old_name, dev_name, check_udev); return _rename_dev_node(old_name, dev_name, warn_if_udev_failed);
case NODE_READ_AHEAD: case NODE_READ_AHEAD:
return _set_dev_node_read_ahead(dev_name, read_ahead, return _set_dev_node_read_ahead(dev_name, read_ahead,
read_ahead_flags); read_ahead_flags);
@ -794,7 +795,8 @@ struct node_op_parms {
uint32_t read_ahead; uint32_t read_ahead;
uint32_t read_ahead_flags; uint32_t read_ahead_flags;
char *old_name; char *old_name;
int check_udev; int warn_if_udev_failed;
unsigned rely_on_udev;
char names[0]; char names[0];
}; };
@ -824,16 +826,33 @@ static int _other_node_ops(node_op_t type)
return 0; return 0;
} }
/* Check if udev is supposed to create nodes */ static void _log_node_op(const char *action_str, struct node_op_parms *nop)
static int _check_udev(int check_udev)
{ {
return check_udev && dm_udev_get_sync_support() && dm_udev_get_checking(); switch (nop->type) {
case NODE_ADD:
log_debug("%s: %s NODE_ADD (%" PRIu32 ",%" PRIu32 ") %u:%u 0%o",
nop->dev_name, action_str, nop->major, nop->minor, nop->uid, nop->gid, nop->mode);
break;
case NODE_DEL:
log_debug("%s: %s NODE_DEL", nop->dev_name, action_str);
break;
case NODE_RENAME:
log_debug("%s: %s NODE_RENAME to %s", nop->old_name, action_str, nop->dev_name);
break;
case NODE_READ_AHEAD:
log_debug("%s: %s NODE_READ_AHEAD %" PRIu32 " (flags=%" PRIu32
")", nop->dev_name, action_str, nop->read_ahead, nop->read_ahead_flags);
break;
default:
; /* NOTREACHED */
}
} }
static int _stack_node_op(node_op_t type, const char *dev_name, uint32_t major, static int _stack_node_op(node_op_t type, const char *dev_name, uint32_t major,
uint32_t minor, uid_t uid, gid_t gid, mode_t mode, uint32_t minor, uid_t uid, gid_t gid, mode_t mode,
const char *old_name, uint32_t read_ahead, const char *old_name, uint32_t read_ahead,
uint32_t read_ahead_flags, int check_udev) uint32_t read_ahead_flags, int warn_if_udev_failed,
unsigned rely_on_udev)
{ {
struct node_op_parms *nop; struct node_op_parms *nop;
struct dm_list *noph, *nopht; struct dm_list *noph, *nopht;
@ -841,7 +860,7 @@ static int _stack_node_op(node_op_t type, const char *dev_name, uint32_t major,
char *pos; char *pos;
/* /*
* Note: check_udev must have valid content * Note: warn_if_udev_failed must have valid content
*/ */
if ((type == NODE_DEL) && _other_node_ops(type)) if ((type == NODE_DEL) && _other_node_ops(type))
/* /*
@ -850,27 +869,29 @@ static int _stack_node_op(node_op_t type, const char *dev_name, uint32_t major,
dm_list_iterate_safe(noph, nopht, &_node_ops) { dm_list_iterate_safe(noph, nopht, &_node_ops) {
nop = dm_list_item(noph, struct node_op_parms); nop = dm_list_item(noph, struct node_op_parms);
if (!strcmp(dev_name, nop->dev_name)) { if (!strcmp(dev_name, nop->dev_name)) {
_log_node_op("Unstacking", nop);
_del_node_op(nop); _del_node_op(nop);
if (!_other_node_ops(type)) if (!_other_node_ops(type))
break; /* no other non DEL ops */ break; /* no other non DEL ops */
} }
} }
else if ((type == NODE_ADD) && _count_node_ops[NODE_DEL] && _check_udev(check_udev)) else if ((type == NODE_ADD) && _count_node_ops[NODE_DEL])
/* /*
* If udev is running ignore previous DEL operation on added node. * Ignore previous DEL operation on added node.
* (No other operations for this device then DEL could be stacked here). * (No other operations for this device then DEL could be stacked here).
*/ */
dm_list_iterate_safe(noph, nopht, &_node_ops) { dm_list_iterate_safe(noph, nopht, &_node_ops) {
nop = dm_list_item(noph, struct node_op_parms); nop = dm_list_item(noph, struct node_op_parms);
if ((nop->type == NODE_DEL) && if ((nop->type == NODE_DEL) &&
!strcmp(dev_name, nop->dev_name)) { !strcmp(dev_name, nop->dev_name)) {
_log_node_op("Unstacking", nop);
_del_node_op(nop); _del_node_op(nop);
break; /* no other DEL ops */ break; /* no other DEL ops */
} }
} }
else if ((type == NODE_RENAME) && _check_udev(check_udev)) else if ((type == NODE_RENAME))
/* /*
* If udev is running ignore any outstanding operations if renaming it. * Ignore any outstanding operations if renaming it.
* *
* Currently RENAME operation happens through 'suspend -> resume'. * Currently RENAME operation happens through 'suspend -> resume'.
* On 'resume' device is added with read_ahead settings, so it is * On 'resume' device is added with read_ahead settings, so it is
@ -880,6 +901,7 @@ static int _stack_node_op(node_op_t type, const char *dev_name, uint32_t major,
dm_list_iterate_safe(noph, nopht, &_node_ops) { dm_list_iterate_safe(noph, nopht, &_node_ops) {
nop = dm_list_item(noph, struct node_op_parms); nop = dm_list_item(noph, struct node_op_parms);
if (!strcmp(old_name, nop->dev_name)) if (!strcmp(old_name, nop->dev_name))
_log_node_op("Unstacking", nop);
_del_node_op(nop); _del_node_op(nop);
} }
@ -897,7 +919,8 @@ static int _stack_node_op(node_op_t type, const char *dev_name, uint32_t major,
nop->mode = mode; nop->mode = mode;
nop->read_ahead = read_ahead; nop->read_ahead = read_ahead;
nop->read_ahead_flags = read_ahead_flags; nop->read_ahead_flags = read_ahead_flags;
nop->check_udev = check_udev; nop->warn_if_udev_failed = warn_if_udev_failed;
nop->rely_on_udev = rely_on_udev;
_store_str(&pos, &nop->dev_name, dev_name); _store_str(&pos, &nop->dev_name, dev_name);
_store_str(&pos, &nop->old_name, old_name); _store_str(&pos, &nop->old_name, old_name);
@ -905,6 +928,8 @@ static int _stack_node_op(node_op_t type, const char *dev_name, uint32_t major,
_count_node_ops[type]++; _count_node_ops[type]++;
dm_list_add(&_node_ops, &nop->list); dm_list_add(&_node_ops, &nop->list);
_log_node_op("Stacking", nop);
return 1; return 1;
} }
@ -915,38 +940,35 @@ static void _pop_node_ops(void)
dm_list_iterate_safe(noph, nopht, &_node_ops) { dm_list_iterate_safe(noph, nopht, &_node_ops) {
nop = dm_list_item(noph, struct node_op_parms); nop = dm_list_item(noph, struct node_op_parms);
if (!nop->rely_on_udev) {
_log_node_op("Processing", nop);
_do_node_op(nop->type, nop->dev_name, nop->major, nop->minor, _do_node_op(nop->type, nop->dev_name, nop->major, nop->minor,
nop->uid, nop->gid, nop->mode, nop->old_name, nop->uid, nop->gid, nop->mode, nop->old_name,
nop->read_ahead, nop->read_ahead_flags, nop->read_ahead, nop->read_ahead_flags,
nop->check_udev); nop->warn_if_udev_failed);
} else
_log_node_op("Skipping (udev)", nop);
_del_node_op(nop); _del_node_op(nop);
} }
} }
int add_dev_node(const char *dev_name, uint32_t major, uint32_t minor, int add_dev_node(const char *dev_name, uint32_t major, uint32_t minor,
uid_t uid, gid_t gid, mode_t mode, int check_udev) uid_t uid, gid_t gid, mode_t mode, int check_udev, unsigned rely_on_udev)
{ {
log_debug("%s: Stacking NODE_ADD (%" PRIu32 ",%" PRIu32 ") %u:%u 0%o",
dev_name, major, minor, uid, gid, mode);
return _stack_node_op(NODE_ADD, dev_name, major, minor, uid, return _stack_node_op(NODE_ADD, dev_name, major, minor, uid,
gid, mode, "", 0, 0, check_udev); gid, mode, "", 0, 0, check_udev, rely_on_udev);
} }
int rename_dev_node(const char *old_name, const char *new_name, int check_udev) int rename_dev_node(const char *old_name, const char *new_name, int check_udev, unsigned rely_on_udev)
{ {
log_debug("%s: Stacking NODE_RENAME to %s", old_name, new_name);
return _stack_node_op(NODE_RENAME, new_name, 0, 0, 0, return _stack_node_op(NODE_RENAME, new_name, 0, 0, 0,
0, 0, old_name, 0, 0, check_udev); 0, 0, old_name, 0, 0, check_udev, rely_on_udev);
} }
int rm_dev_node(const char *dev_name, int check_udev) int rm_dev_node(const char *dev_name, int check_udev, unsigned rely_on_udev)
{ {
log_debug("%s: Stacking NODE_DEL (replaces other stacked ops)", dev_name);
return _stack_node_op(NODE_DEL, dev_name, 0, 0, 0, return _stack_node_op(NODE_DEL, dev_name, 0, 0, 0,
0, 0, "", 0, 0, check_udev); 0, 0, "", 0, 0, check_udev, rely_on_udev);
} }
int set_dev_node_read_ahead(const char *dev_name, uint32_t read_ahead, int set_dev_node_read_ahead(const char *dev_name, uint32_t read_ahead,
@ -955,11 +977,8 @@ int set_dev_node_read_ahead(const char *dev_name, uint32_t read_ahead,
if (read_ahead == DM_READ_AHEAD_AUTO) if (read_ahead == DM_READ_AHEAD_AUTO)
return 1; return 1;
log_debug("%s: Stacking NODE_READ_AHEAD %" PRIu32 " (flags=%" PRIu32
")", dev_name, read_ahead, read_ahead_flags);
return _stack_node_op(NODE_READ_AHEAD, dev_name, 0, 0, 0, 0, return _stack_node_op(NODE_READ_AHEAD, dev_name, 0, 0, 0, 0,
0, "", read_ahead, read_ahead_flags, 0); 0, "", read_ahead, read_ahead_flags, 0, 0);
} }
void update_devs(void) void update_devs(void)
@ -1428,7 +1447,7 @@ static int _udev_wait(uint32_t cookie)
return 0; return 0;
} }
log_debug("Udev cookie 0x%" PRIx32 " (semid %d): Waiting for zero", log_debug("Udev cookie 0x%" PRIx32 " (semid %d) waiting for zero",
cookie, semid); cookie, semid);
repeat_wait: repeat_wait:

View File

@ -23,10 +23,10 @@ struct target *create_target(uint64_t start,
const char *type, const char *params); const char *type, const char *params);
int add_dev_node(const char *dev_name, uint32_t minor, uint32_t major, int add_dev_node(const char *dev_name, uint32_t minor, uint32_t major,
uid_t uid, gid_t gid, mode_t mode, int check_udev); uid_t uid, gid_t gid, mode_t mode, int check_udev, unsigned rely_on_udev);
int rm_dev_node(const char *dev_name, int check_udev); int rm_dev_node(const char *dev_name, int check_udev, unsigned rely_on_udev);
int rename_dev_node(const char *old_name, const char *new_name, int rename_dev_node(const char *old_name, const char *new_name,
int check_udev); int check_udev, unsigned rely_on_udev);
int get_dev_node_read_ahead(const char *dev_name, uint32_t *read_ahead); int get_dev_node_read_ahead(const char *dev_name, uint32_t *read_ahead);
int set_dev_node_read_ahead(const char *dev_name, uint32_t read_ahead, int set_dev_node_read_ahead(const char *dev_name, uint32_t read_ahead,
uint32_t read_ahead_flags); uint32_t read_ahead_flags);

View File

@ -983,10 +983,9 @@ static int _deactivate_node(const char *name, uint32_t major, uint32_t minor,
r = dm_task_run(dmt); r = dm_task_run(dmt);
/* FIXME Until kernel returns actual name so dm-ioctl.c can handle it */ /* FIXME Until kernel returns actual name so dm-iface.c can handle it */
if (!(udev_flags & DM_UDEV_DISABLE_LIBRARY_FALLBACK)) rm_dev_node(name, dmt->cookie_set && !(udev_flags & DM_UDEV_DISABLE_DM_RULES_FLAG),
rm_dev_node(name, dmt->cookie_set && dmt->cookie_set && !(udev_flags & DM_UDEV_DISABLE_LIBRARY_FALLBACK));
!(udev_flags & DM_UDEV_DISABLE_DM_RULES_FLAG));
/* FIXME Remove node from tree or mark invalid? */ /* FIXME Remove node from tree or mark invalid? */

View File

@ -181,6 +181,10 @@ Answer yes to all prompts automatically.
.IP \fB-v|--verbose\ [-v|--verbose] .IP \fB-v|--verbose\ [-v|--verbose]
.br .br
Produce additional output. Produce additional output.
.IP \fB--verifyudev
If udev synchronisation is enabled, verify that udev operations get performed
correctly and try to fix up the device nodes afterwards if not.
.br
.IP \fB--version .IP \fB--version
.br .br
Display the library and kernel driver version. Display the library and kernel driver version.

View File

@ -135,7 +135,6 @@ enum {
UDEVCOOKIE_ARG, UDEVCOOKIE_ARG,
NOUDEVRULES_ARG, NOUDEVRULES_ARG,
NOUDEVSYNC_ARG, NOUDEVSYNC_ARG,
UDEVFALLBACK_ARG,
OPTIONS_ARG, OPTIONS_ARG,
READAHEAD_ARG, READAHEAD_ARG,
ROWS_ARG, ROWS_ARG,
@ -151,6 +150,7 @@ enum {
UNQUOTED_ARG, UNQUOTED_ARG,
UUID_ARG, UUID_ARG,
VERBOSE_ARG, VERBOSE_ARG,
VERIFYUDEV_ARG,
VERSION_ARG, VERSION_ARG,
YES_ARG, YES_ARG,
ADD_NODE_ON_RESUME_ARG, ADD_NODE_ON_RESUME_ARG,
@ -1007,7 +1007,7 @@ static int _set_up_udev_support(const char *dev_dir)
else else
dirs_diff = strcmp(dev_dir, udev_dev_dir); dirs_diff = strcmp(dev_dir, udev_dev_dir);
_udev_only = !dirs_diff && (_udev_cookie || !_switches[UDEVFALLBACK_ARG]); _udev_only = !dirs_diff && (_udev_cookie || !_switches[VERIFYUDEV_ARG]);
if (dirs_diff) { if (dirs_diff) {
log_debug("The path %s used for creating device nodes that is " log_debug("The path %s used for creating device nodes that is "
@ -2745,7 +2745,7 @@ static void _usage(FILE *out)
fprintf(out, "dmsetup [--version] [-h|--help [-c|-C|--columns]]\n" fprintf(out, "dmsetup [--version] [-h|--help [-c|-C|--columns]]\n"
" [-v|--verbose [-v|--verbose ...]]\n" " [-v|--verbose [-v|--verbose ...]]\n"
" [-r|--readonly] [--noopencount] [--nolockfs] [--inactive]\n" " [-r|--readonly] [--noopencount] [--nolockfs] [--inactive]\n"
" [--udevcookie] [--noudevrules] [--noudevsync] [--udevfallback]\n" " [--udevcookie] [--noudevrules] [--noudevsync] [--verifyudev]\n"
" [-y|--yes] [--readahead [+]<sectors>|auto|none]\n" " [-y|--yes] [--readahead [+]<sectors>|auto|none]\n"
" [-c|-C|--columns] [-o <fields>] [-O|--sort <sort_fields>]\n" " [-c|-C|--columns] [-o <fields>] [-O|--sort <sort_fields>]\n"
" [--nameprefixes] [--noheadings] [--separator <separator>]\n\n"); " [--nameprefixes] [--noheadings] [--separator <separator>]\n\n");
@ -3116,7 +3116,6 @@ static int _process_switches(int *argc, char ***argv, const char *dev_dir)
{"udevcookie", 1, &ind, UDEVCOOKIE_ARG}, {"udevcookie", 1, &ind, UDEVCOOKIE_ARG},
{"noudevrules", 0, &ind, NOUDEVRULES_ARG}, {"noudevrules", 0, &ind, NOUDEVRULES_ARG},
{"noudevsync", 0, &ind, NOUDEVSYNC_ARG}, {"noudevsync", 0, &ind, NOUDEVSYNC_ARG},
{"udevfallback", 0, &ind, UDEVFALLBACK_ARG},
{"options", 1, &ind, OPTIONS_ARG}, {"options", 1, &ind, OPTIONS_ARG},
{"readahead", 1, &ind, READAHEAD_ARG}, {"readahead", 1, &ind, READAHEAD_ARG},
{"rows", 0, &ind, ROWS_ARG}, {"rows", 0, &ind, ROWS_ARG},
@ -3132,6 +3131,7 @@ static int _process_switches(int *argc, char ***argv, const char *dev_dir)
{"unbuffered", 0, &ind, UNBUFFERED_ARG}, {"unbuffered", 0, &ind, UNBUFFERED_ARG},
{"unquoted", 0, &ind, UNQUOTED_ARG}, {"unquoted", 0, &ind, UNQUOTED_ARG},
{"verbose", 1, &ind, VERBOSE_ARG}, {"verbose", 1, &ind, VERBOSE_ARG},
{"verifyudev", 0, &ind, VERIFYUDEV_ARG},
{"version", 0, &ind, VERSION_ARG}, {"version", 0, &ind, VERSION_ARG},
{"yes", 0, &ind, YES_ARG}, {"yes", 0, &ind, YES_ARG},
{"addnodeonresume", 0, &ind, ADD_NODE_ON_RESUME_ARG}, {"addnodeonresume", 0, &ind, ADD_NODE_ON_RESUME_ARG},
@ -3245,8 +3245,8 @@ static int _process_switches(int *argc, char ***argv, const char *dev_dir)
_switches[NOUDEVRULES_ARG]++; _switches[NOUDEVRULES_ARG]++;
if (ind == NOUDEVSYNC_ARG) if (ind == NOUDEVSYNC_ARG)
_switches[NOUDEVSYNC_ARG]++; _switches[NOUDEVSYNC_ARG]++;
if (ind == UDEVFALLBACK_ARG) if (ind == VERIFYUDEV_ARG)
_switches[UDEVFALLBACK_ARG]++; _switches[VERIFYUDEV_ARG]++;
if (c == 'G' || ind == GID_ARG) { if (c == 'G' || ind == GID_ARG) {
_switches[GID_ARG]++; _switches[GID_ARG]++;
_int_args[GID_ARG] = atoi(optarg); _int_args[GID_ARG] = atoi(optarg);