[libvirt] [PATCHv4 14/18] blockjob: allow mirroring under SELinux

Jiri Denemark jdenemar at redhat.com
Fri Apr 13 20:45:18 UTC 2012


On Mon, Apr 09, 2012 at 21:52:23 -0600, Eric Blake wrote:
> This copies heavily from qemuDomainSnapshotCreateSingleDiskActive(),
> in order to set the SELinux label, obtain locking manager lease, and
> audit the fact that we hand a new file over to qemu.  Alas, releasing
> the lease and label on failure or at the end of the mirroring is a
> trickier prospect.
> 
> * src/qemu/qemu_driver.c (qemuDomainBlockCopy): Set up labeling.
> ---
>  src/qemu/qemu_driver.c |   63 +++++++++++++++++++++++++++++++++++++++++-------
>  1 files changed, 54 insertions(+), 9 deletions(-)
> 
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 661ccb4..41f545f 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -11895,6 +11895,11 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *path,
>      int ret = -1;
>      int idx;
>      struct stat st;
> +    bool need_unlink = false;
> +    char *mirror = NULL;
> +    char *mirrorFormat = NULL;
> +    char *origsrc = NULL;
> +    char *origdriver = NULL;
> 
>      /* Preliminaries: find the disk we are editing, sanity checks */
>      virCheckFlags(VIR_DOMAIN_BLOCK_REBASE_SHALLOW |
> @@ -11976,29 +11981,69 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *path,
>          goto endjob;
>      }
> 
> -    /* XXX We also need to add security labeling, lock manager lease,
> -     * and auditing of those events.  */
> -    if (!format && !(flags & VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT))
> -        format = disk->driverType;
> -    if ((format && !(disk->mirrorFormat = strdup(format))) ||
> -        !(disk->mirror = strdup(dest))) {
> +    if (!(flags & VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT)) {
> +        int fd = qemuOpenFile(driver, dest, O_WRONLY | O_TRUNC | O_CREAT,
> +                              &need_unlink, NULL);
> +        if (fd < 0)
> +            goto endjob;
> +        VIR_FORCE_CLOSE(fd);
> +        if (!format)
> +            format = disk->driverType;
> +    }
> +    if ((format && !(mirrorFormat = strdup(format))) ||
> +        !(mirror = strdup(dest))) {
>          virReportOOMError();
>          goto endjob;
>      }
> 
> +    /* Manipulate disk in place, in a way that can be reverted on
> +     * failure, in order to set up labeling and locking.  */
> +    origsrc = disk->src;
> +    disk->src = (char *) dest;
> +    origdriver = disk->driverType;
> +    disk->driverType = (char *) "raw"; /* Don't want to probe backing files */
> +
> +    if (virDomainLockDiskAttach(driver->lockManager, vm, disk) < 0)
> +        goto endjob;
> +    if (virSecurityManagerSetImageLabel(driver->securityManager, vm->def,
> +                                        disk) < 0) {
> +        if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
> +            VIR_WARN("Unable to release lock on %s", dest);
> +        goto endjob;
> +    }

Is there a reason for calling virDomainLockDiskDetach only when SetImageLabel
fails and not calling it if mirroring itself fails?

> +
> +    disk->src = origsrc;
> +    origsrc = NULL;
> +    disk->driverType = origdriver;
> +    origdriver = NULL;
> +
>      /* Actually start the mirroring */
>      qemuDomainObjEnterMonitorWithDriver(driver, vm);
>      ret = qemuMonitorDriveMirror(priv->mon, NULL, device, dest, format, flags);
> +    virDomainAuditDisk(vm, NULL, dest, "mirror", ret >= 0);
>      if (ret == 0 && bandwidth != 0)
>          ret = qemuMonitorBlockJob(priv->mon, device, NULL, bandwidth, NULL,
>                                    BLOCK_JOB_SPEED_INTERNAL);
>      qemuDomainObjExitMonitorWithDriver(driver, vm);
> +    if (ret < 0)
> +        goto endjob;
> +
> +    /* Update vm in place to match changes.  */
> +    need_unlink = false;
> +    disk->mirror = mirror;
> +    disk->mirrorFormat = mirrorFormat;
> +    mirror = NULL;
> +    mirrorFormat = NULL;
> 
>  endjob:
> -    if (ret < 0) {
> -        VIR_FREE(disk->mirror);
> -        VIR_FREE(disk->mirrorFormat);
> +    if (origsrc) {
> +        disk->src = origsrc;
> +        disk->driverType = origdriver;
>      }
> +    if (need_unlink && unlink(dest))
> +        VIR_WARN("unable to unlink just-created %s", dest);
> +    VIR_FREE(mirror);
> +    VIR_FREE(mirrorFormat);
>      if (qemuDomainObjEndJob(driver, vm) == 0) {
>          vm = NULL;
>          goto cleanup;

Jirka




More information about the libvir-list mailing list