Re: [libvirt] [PATCH 4/4] qemu: call the helpers in virshm.c to manage shmem device
On 07/30/2015 06:25 PM, Daniel P. Berrange wrote: On Thu, Jul 23, 2015 at 06:13:49PM +0800, Luyao Huang wrote: Signed-off-by: Luyao Huang lhu...@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(+) +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) { +ignore_value(virShmUnlink(shmem-name)); Why are you treating -1 differentl from -2 - in both cases we should abort creation as that indicates the method either failed or is not supported in this platform. What i thought when i wrote this is : when ret = -2 this means we do not support virShmBuildPath in that platform (this could only happened on some other platform which support shm_open/shm_unlink ,just like solaris, freebsd) but we could use shm_open, on that platform the shm obj is not in /dev/shm or not exist in the file system, if we help to create that shm obj but cannot find a way to relabel it, qemu will cannot use the shm in that case, so unlink the shm and let qemu create it will make guest can start success, and we could unlink the qemu create shm obj if there is no guest use it. I am not sure this is a good idea right now, since i am not sure this will work as except on different platform. Maybe i should remove it and make virShmBuildPath return -1 if not support on that platform. Regards, Daniel Luyao -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 4/4] qemu: call the helpers in virshm.c to manage shmem device
Hi Marc-André On 07/27/2015 11:52 PM, Marc-André Lureau wrote: Hi On Thu, Jul 23, 2015 at 12:13 PM, Luyao Huang lhu...@redhat.com wrote: Signed-off-by: Luyao Huang lhu...@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 ? when ret = -2 this means we do not support virShmBuildPath in that platform (this could only happened on some other platform which support shm_open/shm_unlink ,just like solaris, freebsd), at that platform the shm obj is not in /dev/shm or not exist in the file system, if we help to create that shm obj but cannot find a way to relabel it, qemu will cannot use the shm in that case, so unlink the shm and let qemu create it will make guest can start success, and we could unlink the qemu create shm obj if there is no guest use it. +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? Good question, we allow specify the label in the shmem device XML, and if the user create the shm with a label which only allow that guest access, then the other guest will cannot use it if we do not change the label, but if we change the label to a label which allow all libvirt guest can access, it will
Re: [libvirt] [PATCH 4/4] qemu: call the helpers in virshm.c to manage shmem device
On 07/30/2015 06:23 PM, Daniel P. Berrange wrote: On Thu, Jul 23, 2015 at 06:13:49PM +0800, Luyao Huang wrote: Signed-off-by: Luyao Huang lhu...@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_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) { +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)); +goto cleanup; +} else { +othercreate = true; +} +type = VIR_SHM_TYPE_SERVER; +} +teardownshm = true; + +if (virSecurityManagerSetShmemLabel(driver-securityManager, +vm-def, shmem, path) 0) +goto cleanup; You shouldn't be setting labelling at this point. That should be done by the later call to virSecurityManagerSetAllLabel Okay, i see, i will move it to virSecurityManagerSetAllLabel +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); Likewise this should be left to the main label restore code Okay, Thanks a lot for your review and advise. + +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; +} Regards, Daniel Luyao -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 4/4] qemu: call the helpers in virshm.c to manage shmem device
On Thu, Jul 23, 2015 at 06:13:49PM +0800, Luyao Huang wrote: Signed-off-by: Luyao Huang lhu...@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_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) { +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)); +goto cleanup; +} else { +othercreate = true; +} +type = VIR_SHM_TYPE_SERVER; +} +teardownshm = true; + +if (virSecurityManagerSetShmemLabel(driver-securityManager, +vm-def, shmem, path) 0) +goto cleanup; You shouldn't be setting labelling at this point. That should be done by the later call to virSecurityManagerSetAllLabel +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); Likewise this should be left to the main label restore code + +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; +} Regards, Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 4/4] qemu: call the helpers in virshm.c to manage shmem device
On Thu, Jul 23, 2015 at 06:13:49PM +0800, Luyao Huang wrote: Signed-off-by: Luyao Huang lhu...@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(+) +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) { +ignore_value(virShmUnlink(shmem-name)); Why are you treating -1 differentl from -2 - in both cases we should abort creation as that indicates the method either failed or is not supported in this platform. Regards, Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 4/4] qemu: call the helpers in virshm.c to manage shmem device
Hi On Thu, Jul 23, 2015 at 12:13 PM, Luyao Huang lhu...@redhat.com wrote: Signed-off-by: Luyao Huang lhu...@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
[libvirt] [PATCH 4/4] qemu: call the helpers in virshm.c to manage shmem device
Signed-off-by: Luyao Huang lhu...@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) { +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)); +goto cleanup; +} else { +othercreate = true; +} +type = VIR_SHM_TYPE_SERVER; +} +teardownshm = true; + +if (virSecurityManagerSetShmemLabel(driver-securityManager, +vm-def, shmem, path) 0) +goto cleanup; +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 =