{
char *dlid, *name;
struct dm_info info, info2;
+ uint16_t udev_flags = 0;
if (!(name = build_dm_name(dm->mem, lv->vg->name, lv->name, layer)))
return_0;
}
}
- if (info.exists && !dm_tree_add_dev(dtree, info.major, info.minor)) {
+ if (layer || !lv_is_visible(lv))
+ udev_flags |= DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG |
+ DM_UDEV_DISABLE_DISK_RULES_FLAG |
+ DM_UDEV_DISABLE_OTHER_RULES_FLAG;
+
+ if (lv_is_cow(lv))
+ udev_flags |= DM_UDEV_LOW_PRIORITY_FLAG;
+
+ if (!dm->cmd->current_settings.udev_rules)
+ udev_flags |= DM_UDEV_DISABLE_DM_RULES_FLAG |
+ DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG;
+
+ if (info.exists && !dm_tree_add_dev_with_udev_flags(dtree, info.major,
+ info.minor, udev_flags)) {
log_error("Failed to add device (%" PRIu32 ":%" PRIu32") to dtree",
info.major, info.minor);
return 0;
if (lv_is_cow(lv))
udev_flags |= DM_UDEV_LOW_PRIORITY_FLAG;
+ if (!dm->cmd->current_settings.udev_rules)
+ udev_flags |= DM_UDEV_DISABLE_DM_RULES_FLAG |
+ DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG;
+
/*
* Add LV to dtree.
* If we're working with precommitted metadata, clear any
if (*layer)
continue;
- fs_del_lv_byname(dm->cmd->dev_dir, vgname, lvname);
+ fs_del_lv_byname(dm->cmd->dev_dir, vgname, lvname,
+ dm->cmd->current_settings.udev_rules);
}
return r;
}
static int _mk_link(const char *dev_dir, const char *vg_name,
- const char *lv_name, const char *dev)
+ const char *lv_name, const char *dev, int check_udev)
{
char lv_path[PATH_MAX], link_path[PATH_MAX], lvm1_group_path[PATH_MAX];
char vg_path[PATH_MAX];
return 0;
}
- if (dm_udev_get_sync_support()) {
+ if (dm_udev_get_sync_support() && check_udev) {
/* Check udev created the correct link. */
if (!stat(link_path, &buf_lp) &&
!stat(lv_path, &buf)) {
log_sys_error("unlink", lv_path);
return 0;
}
- } else if (dm_udev_get_sync_support())
+ } else if (dm_udev_get_sync_support() && check_udev)
log_warn("The link %s should had been created by udev "
"but it was not found. Falling back to "
"direct link creation.", lv_path);
}
static int _rm_link(const char *dev_dir, const char *vg_name,
- const char *lv_name)
+ const char *lv_name, int check_udev)
{
struct stat buf;
char lv_path[PATH_MAX];
if (lstat(lv_path, &buf) && errno == ENOENT)
return 1;
- else if (dm_udev_get_sync_support())
+ else if (dm_udev_get_sync_support() && check_udev)
log_warn("The link %s should have been removed by udev "
"but it is still present. Falling back to "
"direct link removal.", lv_path);
static int _do_fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
const char *lv_name, const char *dev,
- const char *old_lv_name)
+ const char *old_lv_name, int check_udev)
{
switch (type) {
case FS_ADD:
if (!_mk_dir(dev_dir, vg_name) ||
- !_mk_link(dev_dir, vg_name, lv_name, dev))
+ !_mk_link(dev_dir, vg_name, lv_name, dev, check_udev))
return_0;
break;
case FS_DEL:
- if (!_rm_link(dev_dir, vg_name, lv_name) ||
+ if (!_rm_link(dev_dir, vg_name, lv_name, check_udev) ||
!_rm_dir(dev_dir, vg_name))
return_0;
break;
/* FIXME Use rename() */
case FS_RENAME:
- if (old_lv_name && !_rm_link(dev_dir, vg_name, old_lv_name))
+ if (old_lv_name && !_rm_link(dev_dir, vg_name, old_lv_name,
+ check_udev))
stack;
- if (!_mk_link(dev_dir, vg_name, lv_name, dev))
+ if (!_mk_link(dev_dir, vg_name, lv_name, dev, check_udev))
stack;
}
struct fs_op_parms {
struct dm_list list;
fs_op_t type;
+ int check_udev;
char *dev_dir;
char *vg_name;
char *lv_name;
static int _stack_fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
const char *lv_name, const char *dev,
- const char *old_lv_name)
+ const char *old_lv_name, int check_udev)
{
struct fs_op_parms *fsp;
size_t len = strlen(dev_dir) + strlen(vg_name) + strlen(lv_name) +
pos = fsp->names;
fsp->type = type;
+ fsp->check_udev = check_udev;
_store_str(&pos, &fsp->dev_dir, dev_dir);
_store_str(&pos, &fsp->vg_name, vg_name);
dm_list_iterate_safe(fsph, fspht, &_fs_ops) {
fsp = dm_list_item(fsph, struct fs_op_parms);
_do_fs_op(fsp->type, fsp->dev_dir, fsp->vg_name, fsp->lv_name,
- fsp->dev, fsp->old_lv_name);
+ fsp->dev, fsp->old_lv_name, fsp->check_udev);
dm_list_del(&fsp->list);
dm_free(fsp);
}
}
static int _fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
- const char *lv_name, const char *dev, const char *old_lv_name)
+ const char *lv_name, const char *dev, const char *old_lv_name,
+ int check_udev)
{
if (memlock()) {
if (!_stack_fs_op(type, dev_dir, vg_name, lv_name, dev,
- old_lv_name))
+ old_lv_name, check_udev))
return_0;
return 1;
}
- return _do_fs_op(type, dev_dir, vg_name, lv_name, dev, old_lv_name);
+ return _do_fs_op(type, dev_dir, vg_name, lv_name, dev,
+ old_lv_name, check_udev);
}
int fs_add_lv(const struct logical_volume *lv, const char *dev)
{
return _fs_op(FS_ADD, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
- dev, "");
+ dev, "", lv->vg->cmd->current_settings.udev_rules);
}
int fs_del_lv(const struct logical_volume *lv)
{
return _fs_op(FS_DEL, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
- "", "");
+ "", "", lv->vg->cmd->current_settings.udev_rules);
}
-int fs_del_lv_byname(const char *dev_dir, const char *vg_name, const char *lv_name)
+int fs_del_lv_byname(const char *dev_dir, const char *vg_name,
+ const char *lv_name, int check_udev)
{
- return _fs_op(FS_DEL, dev_dir, vg_name, lv_name, "", "");
+ return _fs_op(FS_DEL, dev_dir, vg_name, lv_name, "", "", check_udev);
}
int fs_rename_lv(struct logical_volume *lv, const char *dev,
{
if (strcmp(old_vgname, lv->vg->name)) {
return
- (_fs_op(FS_DEL, lv->vg->cmd->dev_dir, old_vgname, old_lvname, "", "") &&
- _fs_op(FS_ADD, lv->vg->cmd->dev_dir, lv->vg->name, lv->name, dev, ""));
+ (_fs_op(FS_DEL, lv->vg->cmd->dev_dir, old_vgname,
+ old_lvname, "", "", lv->vg->cmd->current_settings.udev_rules) &&
+ _fs_op(FS_ADD, lv->vg->cmd->dev_dir, lv->vg->name,
+ lv->name, dev, "", lv->vg->cmd->current_settings.udev_rules));
}
else
return _fs_op(FS_RENAME, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
- dev, old_lvname);
+ dev, old_lvname, lv->vg->cmd->current_settings.udev_rules);
}
void fs_unlock(void)
static struct dm_tree_node *_add_dev(struct dm_tree *dtree,
struct dm_tree_node *parent,
- uint32_t major, uint32_t minor)
+ uint32_t major, uint32_t minor,
+ uint16_t udev_flags)
{
struct dm_task *dmt = NULL;
struct dm_info info;
return_NULL;
if (!(node = _create_dm_tree_node(dtree, name, uuid, &info,
- NULL, 0)))
+ NULL, udev_flags)))
goto_out;
new = 1;
}
/* Add dependencies to tree */
for (i = 0; i < deps->count; i++)
if (!_add_dev(dtree, node, MAJOR(deps->device[i]),
- MINOR(deps->device[i]))) {
+ MINOR(deps->device[i]), udev_flags)) {
node = NULL;
goto_out;
}
int dm_tree_add_dev(struct dm_tree *dtree, uint32_t major, uint32_t minor)
{
- return _add_dev(dtree, &dtree->root, major, minor) ? 1 : 0;
+ return _add_dev(dtree, &dtree->root, major, minor, 0) ? 1 : 0;
+}
+
+int dm_tree_add_dev_with_udev_flags(struct dm_tree *dtree, uint32_t major,
+ uint32_t minor, uint16_t udev_flags)
+{
+ return _add_dev(dtree, &dtree->root, major, minor, udev_flags) ? 1 : 0;
}
const char *dm_tree_node_get_name(struct dm_tree_node *node)
r = dm_task_run(dmt);
/* FIXME Until kernel returns actual name so dm-ioctl.c can handle it */
- rm_dev_node(name, dmt->cookie_set);
+ rm_dev_node(name, dmt->cookie_set &&
+ !(udev_flags & DM_UDEV_DISABLE_DM_RULES_FLAG));
/* FIXME Remove node from tree or mark invalid? */
}
/* FIXME Check correct macro use */
- if (!(dev_node = _add_dev(node->dtree, node, MAJOR(info.st_rdev), MINOR(info.st_rdev))))
+ if (!(dev_node = _add_dev(node->dtree, node, MAJOR(info.st_rdev),
+ MINOR(info.st_rdev), 0)))
return_0;
}