From: Masayoshi Mizuma <m.mizuma@xxxxxxxxxxxxxx> Introduce locking option for disk source of qemu. It may be useful to avoid file lock issues. locking option supports three switches; 'auto', 'on' and 'off'. The default behaivor will work if locking option isn't set. Example of the usage: <disk type='file' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source file='/tmp/QEMUGuest1.img' locking='off'/> <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> Signed-off-by: Masayoshi Mizuma <m.mizuma@xxxxxxxxxxxxxx> --- docs/schemas/domaincommon.rng | 9 +++++++++ src/conf/domain_conf.c | 8 ++++++++ src/conf/storage_source_conf.c | 9 +++++++++ src/conf/storage_source_conf.h | 14 ++++++++++++++ src/libvirt_private.syms | 1 + src/qemu/qemu_block.c | 5 +++++ 6 files changed, 46 insertions(+) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index a4bddcf132..d33d853f31 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1676,6 +1676,15 @@ <ref name="devSeclabel"/> </zeroOrMore> </interleave> + <optional> + <attribute name="locking"> + <choice> + <value>auto</value> + <value>on</value> + <value>off</value> + </choice> + </attribute> + </optional> </element> </optional> </define> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index dab4f10326..067ffa877b 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -8540,6 +8540,7 @@ virDomainStorageSourceParse(xmlNodePtr node, { VIR_XPATH_NODE_AUTORESTORE(ctxt) xmlNodePtr tmp; + char *locking; ctxt->node = node; @@ -8606,6 +8607,9 @@ virDomainStorageSourceParse(xmlNodePtr node, return -1; } + if ((locking = virXMLPropString(node, "locking"))) + src->locking = virStorageFileLockingTypeFromString(locking); + return 0; } @@ -24102,6 +24106,10 @@ virDomainDiskSourceFormat(virBufferPtr buf, return -1; } + if (src->locking != VIR_STORAGE_FILE_LOCKING_DEFAULT) + virBufferEscapeString(&attrBuf, " locking='%s'", + virStorageFileLockingTypeToString(src->locking)); + virDomainDiskSourceFormatSlices(&childBuf, src); if (src->type != VIR_STORAGE_TYPE_NETWORK) diff --git a/src/conf/storage_source_conf.c b/src/conf/storage_source_conf.c index dab5e855f5..3ac0c7f75b 100644 --- a/src/conf/storage_source_conf.c +++ b/src/conf/storage_source_conf.c @@ -49,6 +49,15 @@ VIR_ENUM_IMPL(virStorage, ); +VIR_ENUM_IMPL(virStorageFileLocking, + VIR_STORAGE_FILE_LOCKING_LAST, + "default", + "auto", + "on", + "off", +); + + VIR_ENUM_IMPL(virStorageFileFormat, VIR_STORAGE_FILE_LAST, "none", diff --git a/src/conf/storage_source_conf.h b/src/conf/storage_source_conf.h index e66ccdedef..6f5b165504 100644 --- a/src/conf/storage_source_conf.h +++ b/src/conf/storage_source_conf.h @@ -82,6 +82,18 @@ typedef enum { VIR_ENUM_DECL(virStorageFileFormat); +typedef enum { + VIR_STORAGE_FILE_LOCKING_DEFAULT = 0, + VIR_STORAGE_FILE_LOCKING_AUTO, + VIR_STORAGE_FILE_LOCKING_ON, + VIR_STORAGE_FILE_LOCKING_OFF, + + VIR_STORAGE_FILE_LOCKING_LAST, +} virStorageFileLocking; + +VIR_ENUM_DECL(virStorageFileLocking); + + typedef enum { VIR_STORAGE_FILE_FEATURE_LAZY_REFCOUNTS = 0, @@ -394,6 +406,8 @@ struct _virStorageSource { char *nfs_group; uid_t nfs_uid; gid_t nfs_gid; + + int locking; /* enum virStorageFileLocking */ }; G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStorageSource, virObjectUnref); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index fbaf16704b..c72d2161b2 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1068,6 +1068,7 @@ virStorageFileFeatureTypeFromString; virStorageFileFeatureTypeToString; virStorageFileFormatTypeFromString; virStorageFileFormatTypeToString; +virStorageFileLockingTypeToString; virStorageNetHostDefClear; virStorageNetHostDefCopy; virStorageNetHostDefFree; diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index d845a3312d..d7eec16ab6 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -1015,6 +1015,7 @@ qemuBlockStorageSourceGetFileProps(virStorageSourcePtr src, { const char *iomode = NULL; const char *prManagerAlias = NULL; + const char *locking = NULL; virJSONValuePtr ret = NULL; if (!onlytarget) { @@ -1023,12 +1024,16 @@ qemuBlockStorageSourceGetFileProps(virStorageSourcePtr src, if (src->iomode != VIR_DOMAIN_DISK_IO_DEFAULT) iomode = virDomainDiskIoTypeToString(src->iomode); + + if (src->locking != VIR_STORAGE_FILE_LOCKING_DEFAULT) + locking = virStorageFileLockingTypeToString(src->locking); } ignore_value(virJSONValueObjectCreate(&ret, "s:filename", src->path, "S:aio", iomode, "S:pr-manager", prManagerAlias, + "S:locking", locking, NULL) < 0); return ret; } -- 2.27.0