From: "M.H. Tsai" <mingnus@gmail.com>
To: linux-lvm@redhat.com
Subject: [linux-lvm] libdm cannot swap names between two child volumes
Date: Thu, 4 Jun 2015 18:02:39 +0800 [thread overview]
Message-ID: <CAAYit8QCcaGvb5QPw_Xuk+oavthHR1c32oB0GsGd+Ypk0rPtRg@mail.gmail.com> (raw)
Hi All,
I found that there's a potential bug in libdm when I try to swap sub
volume's name. By executing the following code, the function
dm_tree_activate_children() will go into infinite loop since that
_rename_conflict_exists() still reports "resolvable=1" in this case.
logical_volume *parent = ...;
logical_volume *child1 = seg_lv(parent, 0);
logical_volume *child2 = seg_lv(parent, 1);
char const *tmp = child1->name;
child1->name = child2->name;
child2->name = tmp;
resume_lv(cmd, parent);
Although this scenario might not happen through command-line
operation, some programmers might need this feature. I think that this
issue could be resolve in libdm by assigning a temporary name, as the
following patch does. Is it safe to do this?
diff --git libdm/libdm-deptree.c libdm/libdm-deptree.c
index 1335351..b0c5f13 100644
--- a/libdm/libdm-deptree.c
+++ b/libdm/libdm-deptree.c
@@ -1771,7 +1771,8 @@ static int _rename_conflict_exists(struct
dm_tree_node *parent,
}
if (!strcmp(node->props.new_name, sibling_name)) {
- if (sibling->props.new_name)
+ if (sibling->props.new_name &&
+ strcmp(sibling->props.new_name,
dm_tree_node_get_name(node)))
*resolvable = 1;
return 1;
}
@@ -1790,8 +1791,10 @@ int dm_tree_activate_children(struct dm_tree_node *dnode,
struct dm_tree_node *child = dnode;
struct dm_info newinfo;
const char *name;
+ const char *new_name = NULL;
const char *uuid;
int priority;
+ int rename_conflict = 0;
/* Activate children first */
while ((child = dm_tree_next_child(&handle, dnode, 0))) {
@@ -1831,12 +1834,21 @@ int dm_tree_activate_children(struct
dm_tree_node *dnode,
/* Rename? */
if (child->props.new_name) {
- if (_rename_conflict_exists(dnode,
child, &resolvable_name_conflict) &&
- resolvable_name_conflict) {
- awaiting_peer_rename++;
- continue;
+ rename_conflict =
_rename_conflict_exists(dnode, child, &resolvable_name_conflict);
+ if (rename_conflict) {
+ if (resolvable_name_conflict) {
+ awaiting_peer_rename++;
+ continue;
+ } else {
+ /* assign a temporary
name for swapping names */
+ new_name =
dm_pool_zalloc(dnode->dtree->mem, strlen(child->props.new_name) + 5);
+
dm_snprintf((char*)new_name, strlen(child->props.new_name) + 5,
"%s_tmp", child->props.new_name);
+ awaiting_peer_rename++;
+ }
+ } else {
+ new_name = child->props.new_name;
}
- if (!_rename_node(name,
child->props.new_name, child->info.major,
+ if (!_rename_node(name, new_name,
child->info.major,
child->info.minor,
&child->dtree->cookie,
child->udev_flags)) {
log_error("Failed to rename %s
(%" PRIu32
@@ -1844,8 +1856,10 @@ int dm_tree_activate_children(struct dm_tree_node *dnode,
child->info.minor,
child->props.new_name);
return 0;
}
- child->name = child->props.new_name;
- child->props.new_name = NULL;
+ child->name = new_name;
+
+ if (!rename_conflict)
+ child->props.new_name = NULL;
}
if (!child->info.inactive_table &&
!child->info.suspended)
Thanks,
Ming-Hung Tsai
next reply other threads:[~2015-06-04 10:02 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-04 10:02 M.H. Tsai [this message]
2015-06-04 12:14 ` [linux-lvm] libdm cannot swap names between two child volumes Zdenek Kabelac
2015-06-05 3:32 ` M.H. Tsai
2015-06-05 8:04 ` Zdenek Kabelac
2015-06-08 2:09 ` M.H. Tsai
2015-06-08 7:17 ` Zdenek Kabelac
2015-06-11 2:54 ` M.H. Tsai
2015-06-11 7:46 ` Zdenek Kabelac
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAAYit8QCcaGvb5QPw_Xuk+oavthHR1c32oB0GsGd+Ypk0rPtRg@mail.gmail.com \
--to=mingnus@gmail.com \
--cc=linux-lvm@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).