Previously we've removed the data only in virshUpdateDiskXML when
changing the disk source for the CDROM since the backing store would be
invalid. Move the code into a separate function and callit from
virshFindDisk which is also used when detaching disk.
The detaching code does not necessarily need to get the full backing
chain since it will need to act on the one managed by libvirt anyways
and this also takes care of problems when parts of the backing store
were invalid due to buggy RBD detection code.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
tools/virsh-domain.c | 34 +++++++++++++++++++++++-----------
1 file changed, 23 insertions(+), 11 deletions(-)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index c10bf184f9..d158327bd7 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -12151,6 +12151,26 @@ cmdDetachInterface(vshControl *ctl, const vshCmd *cmd)
return ret;
}
+
+static void
+virshDiskDropBackingStore(xmlNodePtr disk_node)
+{
+ xmlNodePtr tmp;
+
+ for (tmp = disk_node->children; tmp; tmp = tmp->next) {
+ if (tmp->type != XML_ELEMENT_NODE)
+ continue;
+
+ if (virXMLNodeNameEqual(tmp, "backingStore")) {
+ xmlUnlinkNode(tmp);
+ xmlFreeNode(tmp);
+
+ return;
+ }
+ }
+}
+
+
typedef enum {
VIRSH_FIND_DISK_NORMAL,
VIRSH_FIND_DISK_CHANGEABLE,
@@ -12228,6 +12248,8 @@ virshFindDisk(const char *doc,
if (STREQ_NULLABLE(tmp, path)) {
ret = xmlCopyNode(obj->nodesetval->nodeTab[i], 1);
+ /* drop backing store since they are not needed here */
+ virshDiskDropBackingStore(ret);
VIR_FREE(tmp);
goto cleanup;
}
@@ -12266,7 +12288,6 @@ virshUpdateDiskXML(xmlNodePtr disk_node,
{
xmlNodePtr tmp = NULL;
xmlNodePtr source = NULL;
- xmlNodePtr backingStore = NULL;
xmlNodePtr target_node = NULL;
xmlNodePtr text_node = NULL;
char *device_type = NULL;
@@ -12307,22 +12328,13 @@ virshUpdateDiskXML(xmlNodePtr disk_node,
if (virXMLNodeNameEqual(tmp, "target"))
target_node = tmp;
- if (virXMLNodeNameEqual(tmp, "backingStore"))
- backingStore = tmp;
-
/*
* We've found all we needed.
*/
- if (source && target_node && backingStore)
+ if (source && target_node)
break;
}
- /* drop the <backingStore> subtree since it would become invalid */
- if (backingStore) {
- xmlUnlinkNode(backingStore);
- xmlFreeNode(backingStore);
- }
-
if (type == VIRSH_UPDATE_DISK_XML_EJECT) {
if (!source) {
vshError(NULL, _("The disk device '%s' doesn't have
media"), target);
--
2.15.0