In order for our drivers to lock resources for metadata change we
need set of new APIs. Fortunately, we don't have to care about
every possible device a domain can have. We care only about those
which can live on a network filesystem and hence can be accessed
by multiple daemons at the same time. These devices are covered
in virDomainLockMetadataLock() and only a small fraction of
those can be hotplugged (covered in the rest of the introduced
APIs).
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/libvirt_private.syms | 8 ++
src/locking/domain_lock.c | 304 ++++++++++++++++++++++++++++++++++++++++++----
src/locking/domain_lock.h | 28 +++++
3 files changed, 317 insertions(+), 23 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 32ed5a09f9..fdc45e724c 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1284,6 +1284,14 @@ virDomainLockImageAttach;
virDomainLockImageDetach;
virDomainLockLeaseAttach;
virDomainLockLeaseDetach;
+virDomainLockMetadataDiskLock;
+virDomainLockMetadataDiskUnlock;
+virDomainLockMetadataImageLock;
+virDomainLockMetadataImageUnlock;
+virDomainLockMetadataLock;
+virDomainLockMetadataMemLock;
+virDomainLockMetadataMemUnlock;
+virDomainLockMetadataUnlock;
virDomainLockProcessInquire;
virDomainLockProcessPause;
virDomainLockProcessResume;
diff --git a/src/locking/domain_lock.c b/src/locking/domain_lock.c
index 705b132457..19a097fb25 100644
--- a/src/locking/domain_lock.c
+++ b/src/locking/domain_lock.c
@@ -69,7 +69,8 @@ static int virDomainLockManagerAddLease(virLockManagerPtr lock,
static int virDomainLockManagerAddImage(virLockManagerPtr lock,
- virStorageSourcePtr src)
+ virStorageSourcePtr src,
+ bool metadataOnly)
{
unsigned int diskFlags = 0;
int type = virStorageSourceGetActualType(src);
@@ -82,10 +83,14 @@ static int virDomainLockManagerAddImage(virLockManagerPtr lock,
type == VIR_STORAGE_TYPE_DIR))
return 0;
- if (src->readonly)
- diskFlags |= VIR_LOCK_MANAGER_RESOURCE_READONLY;
- if (src->shared)
- diskFlags |= VIR_LOCK_MANAGER_RESOURCE_SHARED;
+ if (metadataOnly) {
+ diskFlags = VIR_LOCK_MANAGER_RESOURCE_METADATA;
+ } else {
+ if (src->readonly)
+ diskFlags |= VIR_LOCK_MANAGER_RESOURCE_READONLY;
+ if (src->shared)
+ diskFlags |= VIR_LOCK_MANAGER_RESOURCE_SHARED;
+ }
VIR_DEBUG("Add disk %s", src->path);
if (virLockManagerAddResource(lock,
@@ -101,13 +106,68 @@ static int virDomainLockManagerAddImage(virLockManagerPtr lock,
}
+static int
+virDomainLockManagerAddMemory(virLockManagerPtr lock,
+ const virDomainMemoryDef *mem)
+{
+ const char *path = NULL;
+
+ switch ((virDomainMemoryModel) mem->model) {
+ case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
+ path = mem->nvdimmPath;
+ break;
+
+ case VIR_DOMAIN_MEMORY_MODEL_DIMM:
+ case VIR_DOMAIN_MEMORY_MODEL_LAST:
+ case VIR_DOMAIN_MEMORY_MODEL_NONE:
+ break;
+ }
+
+ if (!path)
+ return 0;
+
+ VIR_DEBUG("Adding memory %s", path);
+ if (virLockManagerAddResource(lock,
+ VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK,
+ path,
+ 0,
+ NULL,
+ VIR_LOCK_MANAGER_RESOURCE_METADATA) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+static int
+virDomainLockManagerAddFile(virLockManagerPtr lock,
+ const char *file)
+{
+ if (!file)
+ return 0;
+
+ VIR_DEBUG("Adding file %s", file);
+ if (virLockManagerAddResource(lock,
+ VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK,
+ file,
+ 0,
+ NULL,
+ VIR_LOCK_MANAGER_RESOURCE_METADATA) < 0)
+ return -1;
+
+ return 0;
+}
+
+
static virLockManagerPtr virDomainLockManagerNew(virLockManagerPluginPtr plugin,
const char *uri,
virDomainObjPtr dom,
bool withResources,
+ bool metadataOnly,
unsigned int flags)
{
virLockManagerPtr lock;
+ const virDomainDef *def = dom->def;
size_t i;
virLockManagerParam params[] = {
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_UUID,
@@ -115,11 +175,11 @@ static virLockManagerPtr
virDomainLockManagerNew(virLockManagerPluginPtr plugin,
},
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_STRING,
.key = "name",
- .value = { .str = dom->def->name },
+ .value = { .str = def->name },
},
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_UINT,
.key = "id",
- .value = { .iv = dom->def->id },
+ .value = { .iv = def->id },
},
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_UINT,
.key = "pid",
@@ -133,7 +193,7 @@ static virLockManagerPtr
virDomainLockManagerNew(virLockManagerPluginPtr plugin,
VIR_DEBUG("plugin=%p dom=%p withResources=%d",
plugin, dom, withResources);
- memcpy(params[0].value.uuid, dom->def->uuid, VIR_UUID_BUFLEN);
+ memcpy(params[0].value.uuid, def->uuid, VIR_UUID_BUFLEN);
if (!(lock = virLockManagerNew(virLockManagerPluginGetDriver(plugin),
VIR_LOCK_MANAGER_OBJECT_TYPE_DOMAIN,
@@ -144,19 +204,46 @@ static virLockManagerPtr
virDomainLockManagerNew(virLockManagerPluginPtr plugin,
if (withResources) {
VIR_DEBUG("Adding leases");
- for (i = 0; i < dom->def->nleases; i++)
- if (virDomainLockManagerAddLease(lock, dom->def->leases[i]) < 0)
+ for (i = 0; i < def->nleases; i++)
+ if (virDomainLockManagerAddLease(lock, def->leases[i]) < 0)
goto error;
+ }
+ if (withResources || metadataOnly) {
VIR_DEBUG("Adding disks");
- for (i = 0; i < dom->def->ndisks; i++) {
- virDomainDiskDefPtr disk = dom->def->disks[i];
+ for (i = 0; i < def->ndisks; i++) {
+ virDomainDiskDefPtr disk = def->disks[i];
- if (virDomainLockManagerAddImage(lock, disk->src) < 0)
+ if (virDomainLockManagerAddImage(lock, disk->src, metadataOnly) < 0)
goto error;
}
}
+ if (metadataOnly) {
+ for (i = 0; i < def->nmems; i++) {
+ virDomainMemoryDefPtr mem = def->mems[i];
+
+ if (virDomainLockManagerAddMemory(lock, mem) < 0)
+ goto error;
+ }
+
+ if (def->os.loader &&
+ virDomainLockManagerAddFile(lock, def->os.loader->nvram) < 0)
+ goto error;
+
+ if (virDomainLockManagerAddFile(lock, def->os.kernel) < 0)
+ goto error;
+
+ if (virDomainLockManagerAddFile(lock, def->os.initrd) < 0)
+ goto error;
+
+ if (virDomainLockManagerAddFile(lock, def->os.dtb) < 0)
+ goto error;
+
+ if (virDomainLockManagerAddFile(lock, def->os.slic_table) < 0)
+ goto error;
+ }
+
return lock;
error:
@@ -178,7 +265,7 @@ int virDomainLockProcessStart(virLockManagerPluginPtr plugin,
VIR_DEBUG("plugin=%p dom=%p paused=%d fd=%p",
plugin, dom, paused, fd);
- if (!(lock = virDomainLockManagerNew(plugin, uri, dom, true,
+ if (!(lock = virDomainLockManagerNew(plugin, uri, dom, true, false,
VIR_LOCK_MANAGER_NEW_STARTED)))
return -1;
@@ -203,7 +290,7 @@ int virDomainLockProcessPause(virLockManagerPluginPtr plugin,
VIR_DEBUG("plugin=%p dom=%p state=%p",
plugin, dom, state);
- if (!(lock = virDomainLockManagerNew(plugin, NULL, dom, true, 0)))
+ if (!(lock = virDomainLockManagerNew(plugin, NULL, dom, true, false, 0)))
return -1;
ret = virLockManagerRelease(lock, state, 0);
@@ -223,7 +310,7 @@ int virDomainLockProcessResume(virLockManagerPluginPtr plugin,
VIR_DEBUG("plugin=%p dom=%p state=%s",
plugin, dom, NULLSTR(state));
- if (!(lock = virDomainLockManagerNew(plugin, uri, dom, true, 0)))
+ if (!(lock = virDomainLockManagerNew(plugin, uri, dom, true, false, 0)))
return -1;
ret = virLockManagerAcquire(lock, state, 0, dom->def->onLockFailure, NULL);
@@ -242,7 +329,7 @@ int virDomainLockProcessInquire(virLockManagerPluginPtr plugin,
VIR_DEBUG("plugin=%p dom=%p state=%p",
plugin, dom, state);
- if (!(lock = virDomainLockManagerNew(plugin, NULL, dom, true, 0)))
+ if (!(lock = virDomainLockManagerNew(plugin, NULL, dom, true, false, 0)))
return -1;
ret = virLockManagerInquire(lock, state, 0);
@@ -262,10 +349,10 @@ int virDomainLockImageAttach(virLockManagerPluginPtr plugin,
VIR_DEBUG("plugin=%p dom=%p src=%p", plugin, dom, src);
- if (!(lock = virDomainLockManagerNew(plugin, uri, dom, false, 0)))
+ if (!(lock = virDomainLockManagerNew(plugin, uri, dom, false, false, 0)))
return -1;
- if (virDomainLockManagerAddImage(lock, src) < 0)
+ if (virDomainLockManagerAddImage(lock, src, false) < 0)
goto cleanup;
if (virLockManagerAcquire(lock, NULL, 0,
@@ -299,10 +386,10 @@ int virDomainLockImageDetach(virLockManagerPluginPtr plugin,
VIR_DEBUG("plugin=%p dom=%p src=%p", plugin, dom, src);
- if (!(lock = virDomainLockManagerNew(plugin, NULL, dom, false, 0)))
+ if (!(lock = virDomainLockManagerNew(plugin, NULL, dom, false, false, 0)))
return -1;
- if (virDomainLockManagerAddImage(lock, src) < 0)
+ if (virDomainLockManagerAddImage(lock, src, false) < 0)
goto cleanup;
if (virLockManagerRelease(lock, NULL, 0) < 0)
@@ -336,7 +423,7 @@ int virDomainLockLeaseAttach(virLockManagerPluginPtr plugin,
VIR_DEBUG("plugin=%p dom=%p lease=%p",
plugin, dom, lease);
- if (!(lock = virDomainLockManagerNew(plugin, uri, dom, false, 0)))
+ if (!(lock = virDomainLockManagerNew(plugin, uri, dom, false, false, 0)))
return -1;
if (virDomainLockManagerAddLease(lock, lease) < 0)
@@ -364,7 +451,7 @@ int virDomainLockLeaseDetach(virLockManagerPluginPtr plugin,
VIR_DEBUG("plugin=%p dom=%p lease=%p",
plugin, dom, lease);
- if (!(lock = virDomainLockManagerNew(plugin, NULL, dom, false, 0)))
+ if (!(lock = virDomainLockManagerNew(plugin, NULL, dom, false, false, 0)))
return -1;
if (virDomainLockManagerAddLease(lock, lease) < 0)
@@ -380,3 +467,174 @@ int virDomainLockLeaseDetach(virLockManagerPluginPtr plugin,
return ret;
}
+
+
+int
+virDomainLockMetadataLock(virLockManagerPluginPtr plugin,
+ virDomainObjPtr dom)
+{
+ virLockManagerPtr lock;
+ const unsigned int flags = 0;
+ int ret = -1;
+
+ VIR_DEBUG("plugin=%p dom=%p", plugin, dom);
+
+ if (!(lock = virDomainLockManagerNew(plugin, NULL, dom, false, true, 0)))
+ return -1;
+
+ if (virLockManagerAcquire(lock, NULL, flags,
+ VIR_DOMAIN_LOCK_FAILURE_DEFAULT, NULL) < 0)
+ goto cleanup;
+
+ ret = 0;
+ cleanup:
+ virLockManagerFree(lock);
+ return ret;
+}
+
+
+int
+virDomainLockMetadataUnlock(virLockManagerPluginPtr plugin,
+ virDomainObjPtr dom)
+{
+ virLockManagerPtr lock;
+ const unsigned int flags = 0;
+ int ret = -1;
+
+ VIR_DEBUG("plugin=%p dom=%p", plugin, dom);
+
+ if (!(lock = virDomainLockManagerNew(plugin, NULL, dom, false, true, 0)))
+ return -1;
+
+ if (virLockManagerRelease(lock, NULL, flags) < 0)
+ goto cleanup;
+
+ ret = 0;
+ cleanup:
+ virLockManagerFree(lock);
+ return ret;
+}
+
+
+int
+virDomainLockMetadataImageLock(virLockManagerPluginPtr plugin,
+ virDomainObjPtr dom,
+ virStorageSourcePtr src)
+{
+ virLockManagerPtr lock;
+ int ret = -1;
+
+ VIR_DEBUG("plugin=%p dom=%p src=%p", plugin, dom, src);
+
+ if (!(lock = virDomainLockManagerNew(plugin, NULL, dom, false, false, 0)))
+ return -1;
+
+ if (virDomainLockManagerAddImage(lock, src, true) < 0)
+ goto cleanup;
+
+ if (virLockManagerAcquire(lock, NULL, 0,
+ VIR_DOMAIN_LOCK_FAILURE_DEFAULT, NULL) < 0)
+ goto cleanup;
+
+ ret = 0;
+ cleanup:
+ virLockManagerFree(lock);
+ return ret;
+}
+
+
+int
+virDomainLockMetadataImageUnlock(virLockManagerPluginPtr plugin,
+ virDomainObjPtr dom,
+ virStorageSourcePtr src)
+{
+ virLockManagerPtr lock;
+ int ret = -1;
+
+ VIR_DEBUG("plugin=%p dom=%p src=%p", plugin, dom, src);
+
+ if (!(lock = virDomainLockManagerNew(plugin, NULL, dom, false, false, 0)))
+ return -1;
+
+ if (virDomainLockManagerAddImage(lock, src, true) < 0)
+ goto cleanup;
+
+ if (virLockManagerRelease(lock, NULL, 0) < 0)
+ goto cleanup;
+
+ ret = 0;
+ cleanup:
+ virLockManagerFree(lock);
+ return ret;
+}
+
+
+int
+virDomainLockMetadataDiskLock(virLockManagerPluginPtr plugin,
+ virDomainObjPtr dom,
+ virDomainDiskDefPtr disk)
+{
+ return virDomainLockMetadataImageLock(plugin, dom, disk->src);
+}
+
+
+int
+virDomainLockMetadataDiskUnlock(virLockManagerPluginPtr plugin,
+ virDomainObjPtr dom,
+ virDomainDiskDefPtr disk)
+{
+ return virDomainLockMetadataImageUnlock(plugin, dom, disk->src);
+}
+
+
+int
+virDomainLockMetadataMemLock(virLockManagerPluginPtr plugin,
+ virDomainObjPtr dom,
+ virDomainMemoryDefPtr mem)
+{
+ virLockManagerPtr lock;
+ int ret = -1;
+
+ VIR_DEBUG("plugin=%p dom=%p mem=%p", plugin, dom, mem);
+
+ if (!(lock = virDomainLockManagerNew(plugin, NULL, dom, false, false, 0)))
+ return -1;
+
+ if (virDomainLockManagerAddMemory(lock, mem) < 0)
+ goto cleanup;
+
+ if (virLockManagerAcquire(lock, NULL, 0,
+ VIR_DOMAIN_LOCK_FAILURE_DEFAULT, NULL) < 0)
+ goto cleanup;
+
+ ret = 0;
+ cleanup:
+ virLockManagerFree(lock);
+ return ret;
+}
+
+
+int
+virDomainLockMetadataMemUnlock(virLockManagerPluginPtr plugin,
+ virDomainObjPtr dom,
+ virDomainMemoryDefPtr mem)
+{
+ virLockManagerPtr lock;
+ int ret = -1;
+
+ VIR_DEBUG("plugin=%p dom=%p mem=%p", plugin, dom, mem);
+
+ if (!(lock = virDomainLockManagerNew(plugin, NULL, dom, false, false, 0)))
+ return -1;
+
+ if (virDomainLockManagerAddMemory(lock, mem) < 0)
+ goto cleanup;
+
+ if (virLockManagerRelease(lock, NULL, 0) < 0)
+ goto cleanup;
+
+ ret = 0;
+ cleanup:
+ virLockManagerFree(lock);
+ return ret;
+}
diff --git a/src/locking/domain_lock.h b/src/locking/domain_lock.h
index fb4910230c..fbd3ee1d4e 100644
--- a/src/locking/domain_lock.h
+++ b/src/locking/domain_lock.h
@@ -66,4 +66,32 @@ int virDomainLockLeaseDetach(virLockManagerPluginPtr plugin,
virDomainObjPtr dom,
virDomainLeaseDefPtr lease);
+int virDomainLockMetadataLock(virLockManagerPluginPtr plugin,
+ virDomainObjPtr dom);
+
+int virDomainLockMetadataUnlock(virLockManagerPluginPtr plugin,
+ virDomainObjPtr dom);
+
+int virDomainLockMetadataDiskLock(virLockManagerPluginPtr plugin,
+ virDomainObjPtr dom,
+ virDomainDiskDefPtr disk);
+int virDomainLockMetadataDiskUnlock(virLockManagerPluginPtr plugin,
+ virDomainObjPtr dom,
+ virDomainDiskDefPtr disk);
+
+int virDomainLockMetadataImageLock(virLockManagerPluginPtr plugin,
+ virDomainObjPtr dom,
+ virStorageSourcePtr src);
+
+int virDomainLockMetadataImageUnlock(virLockManagerPluginPtr plugin,
+ virDomainObjPtr dom,
+ virStorageSourcePtr src);
+
+int virDomainLockMetadataMemLock(virLockManagerPluginPtr plugin,
+ virDomainObjPtr dom,
+ virDomainMemoryDefPtr mem);
+int virDomainLockMetadataMemUnlock(virLockManagerPluginPtr plugin,
+ virDomainObjPtr dom,
+ virDomainMemoryDefPtr mem);
+
#endif /* __VIR_DOMAIN_LOCK_H__ */
--
2.16.4