Hi On Thu, Jul 23, 2015 at 12:13 PM, Luyao Huang <lhuang@xxxxxxxxxx> wrote: > Signed-off-by: Luyao Huang <lhuang@xxxxxxxxxx> > --- > 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@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/libvir-list -- Marc-André Lureau 7346 2483 9404 4E20 ABFF 7D48 D864 9487 F43F 0992 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list