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