From bc1024812ae31df83b4973ec0b9172de4d32aa99 Mon Sep 17 00:00:00 2001 From: Zdenek Kabelac Date: Fri, 21 May 2010 12:30:35 +0000 Subject: [PATCH] Replicator: check open_count for parents of presuspend_node For deactivation of Replicator check in advance that all heads have open_count == 0. For this presuspend_node is used as all head nodes are linking this control node. --- WHATS_NEW | 1 + libdm/libdm-deptree.c | 44 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/WHATS_NEW b/WHATS_NEW index 80fc3d45f..b9550d8a3 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.67 - =============================== + Checking open_count in all parents of presuspend_node. Added dm_tree_node_set_presuspend_node() to presuspend child in deactivate. Initial libdm support for Replicator target (API is not stable yet). Extend process_each_lv_in_vg() with support for list of failed lvnames. diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c index 3cf68b9bf..b9f22059b 100644 --- a/libdm/libdm-deptree.c +++ b/libdm/libdm-deptree.c @@ -902,6 +902,44 @@ static int _info_by_dev(uint32_t major, uint32_t minor, int with_open_count, return r; } +/* Check if all parent nodes of given node have open_count == 0 */ +static int _node_has_closed_parents(struct dm_tree_node *node, + const char *uuid_prefix, + size_t uuid_prefix_len) +{ + struct dm_tree_link *dlink; + const struct dm_info *dinfo; + struct dm_info info; + const char *uuid; + + /* Iterate through parents of this node */ + dm_list_iterate_items(dlink, &node->used_by) { + if (!(uuid = dm_tree_node_get_uuid(dlink->node))) { + stack; + continue; + } + + /* Ignore if it doesn't belong to this VG */ + if (!_uuid_prefix_matches(uuid, uuid_prefix, uuid_prefix_len)) + continue; + + if (!(dinfo = dm_tree_node_get_info(dlink->node))) { + stack; /* FIXME Is this normal? */ + return 0; + } + + /* Refresh open_count */ + if (!_info_by_dev(dinfo->major, dinfo->minor, 1, &info) || + !info.exists) + continue; + + if (info.open_count) + return 0; + } + + return 1; +} + static int _deactivate_node(const char *name, uint32_t major, uint32_t minor, uint32_t *cookie, uint16_t udev_flags) { @@ -1100,7 +1138,11 @@ static int _dm_tree_deactivate_children(struct dm_tree_node *dnode, !info.exists) continue; - if (info.open_count) { + /* Also checking open_count in parent nodes of presuspend_node */ + if (info.open_count || + (child->presuspend_node && + !_node_has_closed_parents(child->presuspend_node, + uuid_prefix, uuid_prefix_len))) { /* Only report error from (likely non-internal) dependency at top level */ if (!level) { log_error("Unable to deactivate open %s (%" PRIu32 -- 2.43.5