A bug will be hitted with libvirt+qemu+kvm when doing follow steps:
1.initial status :vm = base+z(z is a snapshot)
2. call snapshotCreateXML( ): vm =  base+z +z'
3. call blockRebase( ): vm = base+z''(z rebase to z')
4.(after rebasing work done) vm shutdown and then start

an error occured like this:
"unable to set user and group to '0:0' on '
/path/to/disk': No such file or directory

A second start may sucess.

The error message reported by virSecurityDACSetSecurityDiskLabel
when the disk chain is misused(that is base+z +z', after rebase,
but z' was deleted yet).virSecurityDACSetSecurityDiskLabel used
an old disk chain after rebasing.
In qemuProcessHandleBlockJob when rebase complete, the disk chain
in vm->def is updated but vm->newDef is not(when vm->newDef is not
null). In shutdown( actrully in qemuProcessStop ), if vm->newDef
is not null , vm->def will be replaced  by vm->newDef, which
contains a wrong disk chain!!! Then the next start will failed with
above message.
To fix it, update disk chain in vm->newDef in qemuProcessHandleBlockJob.

Signed-off-by: Weiwei Li <nuonuoli@tencent.com>
---
 src/qemu/qemu_process.c |   27 +++++++++++++++++++++++++++
 1 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 24e5f0f..0491249 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1033,6 +1033,7 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     virDomainDiskDefPtr disk;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
     virDomainDiskDefPtr persistDisk = NULL;
+    virDomainDiskDefPtr newDisk = NULL;
     bool save = false;
 
     virObjectLock(vm);
@@ -1101,6 +1102,32 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
             disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
             ignore_value(qemuDomainDetermineDiskChain(driver, vm, disk,
                                                       true, true));
+            /* Chang vm->newDef disk chain  */
+            if (!persistDisk && vm->newDef){
+                int indx = virDomainDiskIndexByName(vm->newDef,
+                                                disk->dst,                    
+                                                false);                        
+                virStorageSourcePtr copy = NULL;
+
+                if (indx >=0){  
+                    newDisk = vm->newDef->disks[indx];
+                    copy = virStorageSourceCopy(disk->src, false);
+                    if (virStorageSourceInitChainElement(copy,
+                                                         newDisk->src,                  
+                                                         false) < 0) {                  
+                            VIR_WARN("Unable to update newDef definition "
+                                     "on vm %s after block job",    
+                                     vm->def->name);                
+                            virStorageSourceFree(copy);    
+                            copy = NULL;                  
+                            newDisk = NULL;                
+                    }
+                }
+                if (copy){
+                    virStorageSourceFree(newDisk->src);
+                    newDisk->src = copy;          
+                }
+            }
         } else if (disk->mirror &&
                    (type == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY ||
                     type == VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT)) {
--
1.7.1