1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

Add deactivation functions

This commit is contained in:
Alasdair Kergon 2005-10-18 12:37:53 +00:00
parent 619449b4ca
commit 3e8c6b731a
3 changed files with 112 additions and 0 deletions

View File

@ -82,3 +82,4 @@ dm_hash_get_data
dm_hash_get_first dm_hash_get_first
dm_hash_get_next dm_hash_get_next
dm_driver_version dm_driver_version
dm_deptree_deactivate_children

View File

@ -246,6 +246,13 @@ const struct dm_info *dm_deptree_node_get_info(struct deptree_node *node);
*/ */
int dm_deptree_node_num_children(struct deptree_node *node, uint32_t inverted); int dm_deptree_node_num_children(struct deptree_node *node, uint32_t inverted);
/*
* Deactivate a device with its dependencies if the uuid prefix matches
*/
int dm_deptree_deactivate_children(struct deptree_node *dnode,
const char *uuid_prefix,
size_t uuid_prefix_len);
/***************************************************************************** /*****************************************************************************
* Library functions * Library functions
*****************************************************************************/ *****************************************************************************/

View File

@ -399,3 +399,107 @@ struct deptree_node *dm_deptree_next_child(void **handle,
return (*dlink) ? list_item(*dlink, struct deptree_link)->node : NULL; return (*dlink) ? list_item(*dlink, struct deptree_link)->node : NULL;
} }
/*
* Deactivate a device with its dependencies if the uuid prefix matches
*/
static int _info_by_dev(uint32_t major, uint32_t minor, struct dm_info *info)
{
struct dm_task *dmt;
int r;
if (!(dmt = dm_task_create(DM_DEVICE_INFO))) {
log_error("_info_by_dev: dm_task creation failed");
return 0;
}
if (!dm_task_set_major(dmt, major) || !dm_task_set_minor(dmt, minor)) {
log_error("_info_by_dev: Failed to set device number");
dm_task_destroy(dmt);
return 0;
}
if ((r = dm_task_run(dmt)))
r = dm_task_get_info(dmt, info);
dm_task_destroy(dmt);
return r;
}
static int _deactivate_node(const char *name, uint32_t major, uint32_t minor)
{
struct dm_task *dmt;
int r;
log_verbose("Removing %s (%" PRIu32 ":%" PRIu32 ")", name, major, minor);
if (!(dmt = dm_task_create(DM_DEVICE_REMOVE))) {
log_error("Deactivation dm_task creation failed for %s", name);
return 0;
}
if (!dm_task_set_major(dmt, major) || !dm_task_set_minor(dmt, minor)) {
log_error("Failed to set device number for %s deactivation", name);
dm_task_destroy(dmt);
return 0;
}
if (!dm_task_no_open_count(dmt))
log_error("Failed to disable open_count");
r = dm_task_run(dmt);
dm_task_destroy(dmt);
return r;
}
int dm_deptree_deactivate_children(struct deptree_node *dnode, const char *uuid_prefix, size_t uuid_prefix_len)
{
void *handle = NULL;
struct deptree_node *child = dnode;
struct dm_info info;
const struct dm_info *dinfo;
const char *name;
const char *uuid;
while ((child = dm_deptree_next_child(&handle, dnode, 0))) {
if (!(dinfo = dm_deptree_node_get_info(child))) {
stack;
continue;
}
if (!(name = dm_deptree_node_get_name(child))) {
stack;
continue;
}
if (!(uuid = dm_deptree_node_get_uuid(child))) {
stack;
continue;
}
/* Ignore if it doesn't belong to this VG */
if (strncmp(uuid, uuid_prefix, uuid_prefix_len)) {
stack;
continue;
}
/* Refresh open_count */
if (!_info_by_dev(dinfo->major, dinfo->minor, &info) ||
!info.exists || info.open_count)
continue;
if (!_deactivate_node(name, info.major, info.minor)) {
log_error("Unable to deactivate %s (%" PRIu32
":%" PRIu32 ")", name, info.major,
info.minor);
continue;
}
if (dm_deptree_node_num_children(child, 0))
dm_deptree_deactivate_children(child, uuid_prefix, uuid_prefix_len);
}
return 1;
}