[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