[libvirt] [PATCH 4/4] qemu: call the helpers in virshm.c to manage shmem device

Marc-André Lureau marcandre.lureau at gmail.com
Mon Jul 27 15:52:18 UTC 2015


Hi

On Thu, Jul 23, 2015 at 12:13 PM, Luyao Huang <lhuang at redhat.com> wrote:
> Signed-off-by: Luyao Huang <lhuang at redhat.com>
> ---
>  src/qemu/qemu_conf.h    |   3 +
>  src/qemu/qemu_driver.c  |   4 ++
>  src/qemu/qemu_process.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 165 insertions(+)
>
> diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
> index 3f73929..61d3462 100644
> --- a/src/qemu/qemu_conf.h
> +++ b/src/qemu/qemu_conf.h
> @@ -46,6 +46,7 @@
>  # include "virclosecallbacks.h"
>  # include "virhostdev.h"
>  # include "virfile.h"
> +# include "virshm.h"
>
>  # ifdef CPU_SETSIZE /* Linux */
>  #  define QEMUD_CPUMASK_LEN CPU_SETSIZE
> @@ -235,6 +236,8 @@ struct _virQEMUDriver {
>      /* Immutable pointer. Unsafe APIs. XXX */
>      virHashTablePtr sharedDevices;
>
> +    virShmObjectListPtr shmlist;
> +
>      /* Immutable pointer, self-locking APIs */
>      virPortAllocatorPtr remotePorts;
>
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 9dbe635..282ab45 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -778,6 +778,9 @@ qemuStateInitialize(bool privileged,
>      if (qemuMigrationErrorInit(qemu_driver) < 0)
>          goto error;
>
> +    if (!(qemu_driver->shmlist = virShmObjectListGetDefault()))
> +        goto error;
> +
>      if (privileged) {
>          char *channeldir;
>
> @@ -1087,6 +1090,7 @@ qemuStateCleanup(void)
>      virObjectUnref(qemu_driver->config);
>      virObjectUnref(qemu_driver->hostdevMgr);
>      virHashFree(qemu_driver->sharedDevices);
> +    virObjectUnref(qemu_driver->shmlist);
>      virObjectUnref(qemu_driver->caps);
>      virQEMUCapsCacheFree(qemu_driver->qemuCapsCache);
>
> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index 1c0c734..84b3b5e 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -4321,6 +4321,154 @@ qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg,
>  }
>
>
> +static int
> +qemuPrepareShmemDevice(virQEMUDriverPtr driver,
> +                       virDomainObjPtr vm,
> +                       virDomainShmemDefPtr shmem)
> +{
> +    int ret = -1;
> +    virShmObjectPtr tmp;
> +    virShmObjectListPtr list = driver->shmlist;
> +    bool othercreate = false;
> +    char *path = NULL;
> +    bool teardownlabel = false;
> +    bool teardownshm = false;
> +    int type, fd;
> +
> +    virObjectLock(list);
> +
> +    if ((tmp = virShmObjectFindByName(list, shmem->name))) {
> +        if (shmem->size > tmp->size) {
> +            virReportError(VIR_ERR_INTERNAL_ERROR,
> +                           _("Shmem object %s is already exists and "
> +                             "size is smaller than require size"),
> +                           tmp->name);
> +            goto cleanup;
> +        }
> +
> +        if (virShmSetUsedDomain(tmp, QEMU_DRIVER_NAME, vm->def->name) < 0)
> +            goto cleanup;
> +
> +        if (virShmObjectSaveState(tmp, list->stateDir) < 0)
> +            goto cleanup;
> +
> +        virObjectUnlock(list);
> +        return 0;
> +    }
> +
> +    if (!shmem->server.enabled) {
> +        if ((fd = virShmCreate(shmem->name, shmem->size, false, &othercreate, 0600)) < 0)
> +            goto cleanup;
> +        VIR_FORCE_CLOSE(fd);
> +
> +        if ((ret = virShmBuildPath(shmem->name, &path)) == -1) {
> +            ignore_value(virShmUnlink(shmem->name));
> +            goto cleanup;
> +        } else if (ret == -2 && !othercreate) {

What is ret == -2 ?

> +            ignore_value(virShmUnlink(shmem->name));
> +        }
> +        type = VIR_SHM_TYPE_SHM;
> +    } else {
> +        if (!virFileExists(shmem->server.chr.data.nix.path)) {
> +            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                           _("Shmem device server socket is not exist"));

is not / does not

> +            goto cleanup;
> +        } else {
> +            othercreate = true;
> +        }
> +        type = VIR_SHM_TYPE_SERVER;
> +    }
> +    teardownshm = true;
> +
> +    if (virSecurityManagerSetShmemLabel(driver->securityManager,
> +                                        vm->def, shmem, path) < 0)
> +        goto cleanup;

So each time a ivshmem device starts, it will potentially change the
labels. Not sure that's a good idea. Why not apply only when created?

Btw, have you considered managing shm like storage pools? Would that
bring any benefit?

> +    teardownlabel = true;
> +
> +    if (!(tmp = virShmObjectNew(shmem->name, shmem->size, path, type, othercreate,
> +                                QEMU_DRIVER_NAME, vm->def->name)))
> +        goto cleanup;
> +
> +    if (virShmObjectSaveState(tmp, list->stateDir) < 0) {
> +        virShmObjectFree(tmp);
> +        goto cleanup;
> +    }
> +
> +    if (virShmObjectListAdd(list, tmp) < 0) {
> +        virShmObjectFree(tmp);
> +        goto cleanup;
> +    }
> +
> +    ret = 0;
> +
> + cleanup:
> +    if (ret < 0) {
> +        if (teardownlabel &&
> +            virSecurityManagerRestoreShmemLabel(driver->securityManager,
> +                                                vm->def, shmem, path) < 0)
> +            VIR_WARN("Unable to restore shared memory device labelling");
> +
> +        if (teardownshm && !shmem->server.enabled &&
> +            !othercreate && virShmUnlink(shmem->name) < 0)
> +            VIR_WARN("Unable to unlink shared memory object");
> +    }
> +    VIR_FREE(path);
> +    virObjectUnlock(list);
> +    return ret;
> +}
> +
> +
> +static int
> +qemuCleanUpShmemDevice(virQEMUDriverPtr driver,
> +                       virDomainObjPtr vm,
> +                       virDomainShmemDefPtr shmem)
> +{
> +    virShmObjectPtr tmp;
> +    virShmObjectListPtr list = driver->shmlist;
> +    int ret = -1;
> +
> +    virObjectLock(list);
> +
> +    if (!(tmp = virShmObjectFindByName(list, shmem->name))) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                       _("Cannot find share memory named '%s'"),
> +                       shmem->name);
> +        goto cleanup;
> +    }
> +    if ((shmem->server.enabled && tmp->type != VIR_SHM_TYPE_SERVER) ||
> +        (!shmem->server.enabled && tmp->type != VIR_SHM_TYPE_SHM)) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                       _("Shmem object and shmem device type is not equal"));
> +        goto cleanup;
> +    }
> +
> +    if (virShmRemoveUsedDomain(tmp, QEMU_DRIVER_NAME, vm->def->name) < 0)
> +        goto cleanup;
> +
> +    if (tmp->ndomains == 0) {
> +        if (virSecurityManagerRestoreShmemLabel(driver->securityManager,
> +                                                vm->def, shmem, tmp->path) < 0)
> +            VIR_WARN("Unable to restore shared memory device labelling");
> +
> +        if (!shmem->server.enabled) {
> +            if (!tmp->othercreate &&
> +                virShmUnlink(tmp->name) < 0)
> +                VIR_WARN("Unable to unlink shared memory object");
> +        }
> +
> +        if (virShmObjectRemoveStateFile(list, tmp->name) < 0)
> +            goto cleanup;
> +        virShmObjectListDel(list, tmp);
> +        virShmObjectFree(tmp);
> +    }
> +
> +    ret = 0;
> + cleanup:
> +    virObjectUnlock(list);
> +    return ret;
> +}
> +
> +
>  static void
>  qemuLogOperation(virDomainObjPtr vm,
>                   const char *msg,
> @@ -4753,6 +4901,11 @@ int qemuProcessStart(virConnectPtr conn,
>      if (cfg->clearEmulatorCapabilities)
>          virCommandClearCaps(cmd);
>
> +    for (i = 0; i < vm->def->nshmems; i++) {
> +        if (qemuPrepareShmemDevice(driver, vm, vm->def->shmems[i]) < 0)
> +            goto cleanup;
> +    }
> +
>      /* in case a certain disk is desirous of CAP_SYS_RAWIO, add this */
>      for (i = 0; i < vm->def->ndisks; i++) {
>          virDomainDeviceDef dev;
> @@ -5391,6 +5544,11 @@ void qemuProcessStop(virQEMUDriverPtr driver,
>          }
>      }
>
> +    for (i = 0; i < vm->def->nshmems; i++) {
> +        ignore_value(qemuCleanUpShmemDevice(driver, vm,
> +                                            vm->def->shmems[i]));
> +    }
> +
>      vm->taint = 0;
>      vm->pid = -1;
>      virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason);
> --
> 1.8.3.1
>
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list



-- 
Marc-André Lureau
7346 2483 9404 4E20 ABFF  7D48 D864 9487 F43F 0992




More information about the libvir-list mailing list