In a recent commit I've attempted to rewrite the XML generator to use virXMLFormatElement instead of manual steps. Unfortunately the commit had multiple problems resulting in a garbled XML: 1) in certain cases the wrong buffer was used resulting in misplaced snippets 2) the child element buffer was improperly set up so sub-elements were not indented This resulted in following XML being generated: $ virsh blockcopy cd vda /tmp/test.copy --raw --print-xml type='file''/tmp/test.copy'/> <driver type='raw'/> <disk> <source file=</disk> To fix this we'll generate the '<source>' element in one go and use the proper buffer for it and other places. Fixes: 1cd95f858ab83f2baab0e35070d00766bb06ce3a Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2078274 Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx> --- tools/virsh-domain.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 452e518156..ba492e807e 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -2481,18 +2481,17 @@ cmdBlockcopy(vshControl *ctl, const vshCmd *cmd) if (!xmlstr) { g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER; - g_auto(virBuffer) childBuf = VIR_BUFFER_INITIALIZER; + g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(&buf); if (blockdev) { virBufferAddLit(&attrBuf, " type='block'"); - virBufferAddLit(&childBuf, "<source dev="); + virBufferEscapeString(&childBuf, "<source dev='%s'/>\n", dest); } else { - virBufferAddLit(&buf, " type='file'"); - virBufferAddLit(&childBuf, "<source file="); + virBufferAddLit(&attrBuf, " type='file'"); + virBufferEscapeString(&childBuf, "<source file='%s'/>\n", dest); } - virBufferEscapeString(&buf, "'%s'/>\n", dest); - virBufferEscapeString(&buf, "<driver type='%s'/>\n", format); + virBufferEscapeString(&childBuf, "<driver type='%s'/>\n", format); virXMLFormatElement(&buf, "disk", &attrBuf, &childBuf); xmlstr = virBufferContentAndReset(&buf); } -- 2.35.1