From 787200efd6095c61dc356fb85edc0bf6c94e2b71 Mon Sep 17 00:00:00 2001 From: Peter Rajnoha Date: Thu, 22 Sep 2011 17:36:50 +0000 Subject: [PATCH] Add dm_tree_retry_remove to use retry logic for device removal in a dm_tree. --- WHATS_NEW_DM | 1 + libdm/libdevmapper.h | 5 +++++ libdm/libdm-deptree.c | 17 ++++++++++++++--- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM index ea314b56b..369782ac2 100644 --- a/WHATS_NEW_DM +++ b/WHATS_NEW_DM @@ -1,5 +1,6 @@ Version 1.02.68 - ================================== + Add dm_tree_retry_remove to use retry logic for device removal in a dm_tree. Add dm_device_has_mounted_fs fn to check mounted filesystem on a device. Add dm_device_has_holders fn to to check use of the device by another device. Add dm_sysfs_dir to libdevmapper to retrieve sysfs location thas is set. diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h index 2ef4759b6..17dc1682d 100644 --- a/libdm/libdevmapper.h +++ b/libdm/libdevmapper.h @@ -421,6 +421,11 @@ void dm_tree_skip_lockfs(struct dm_tree_node *dnode); */ void dm_tree_use_no_flush_suspend(struct dm_tree_node *dnode); +/* + * Retry removal of each device if not successful. + */ +void dm_tree_retry_remove(struct dm_tree_node *dnode); + /* * Is the uuid prefix present in the tree? * Only returns 0 if every node was checked successfully. diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c index 45025047a..b1f27d863 100644 --- a/libdm/libdm-deptree.c +++ b/libdm/libdm-deptree.c @@ -222,7 +222,8 @@ struct dm_tree { struct dm_hash_table *uuids; struct dm_tree_node root; int skip_lockfs; /* 1 skips lockfs (for non-snapshots) */ - int no_flush; /* 1 sets noflush (mirrors/multipath) */ + int no_flush; /* 1 sets noflush (mirrors/multipath) */ + int retry_remove; /* 1 retries remove if not successful */ uint32_t cookie; }; @@ -1006,7 +1007,7 @@ static int _node_has_closed_parents(struct dm_tree_node *node, } static int _deactivate_node(const char *name, uint32_t major, uint32_t minor, - uint32_t *cookie, uint16_t udev_flags) + uint32_t *cookie, uint16_t udev_flags, int retry) { struct dm_task *dmt; int r = 0; @@ -1029,6 +1030,10 @@ static int _deactivate_node(const char *name, uint32_t major, uint32_t minor, if (!dm_task_set_cookie(dmt, cookie, udev_flags)) goto out; + + if (retry) + dm_task_retry_remove(dmt); + r = dm_task_run(dmt); /* FIXME Until kernel returns actual name so dm-iface.c can handle it */ @@ -1231,7 +1236,8 @@ static int _dm_tree_deactivate_children(struct dm_tree_node *dnode, continue; if (!_deactivate_node(name, info.major, info.minor, - &child->dtree->cookie, child->udev_flags)) { + &child->dtree->cookie, child->udev_flags, + child->dtree->retry_remove)) { log_error("Unable to deactivate %s (%" PRIu32 ":%" PRIu32 ")", name, info.major, info.minor); @@ -1266,6 +1272,11 @@ void dm_tree_use_no_flush_suspend(struct dm_tree_node *dnode) dnode->dtree->no_flush = 1; } +void dm_tree_retry_remove(struct dm_tree_node *dnode) +{ + dnode->dtree->retry_remove = 1; +} + int dm_tree_suspend_children(struct dm_tree_node *dnode, const char *uuid_prefix, size_t uuid_prefix_len)