virlockspace: Use automatic mutex management

Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Tim Wiederhake 2022-02-08 14:45:36 +01:00
parent bc27d34e3b
commit db7eede6b4

View File

@ -414,12 +414,11 @@ virJSONValue *virLockSpacePreExecRestart(virLockSpace *lockspace)
g_autoptr(virJSONValue) resources = virJSONValueNewArray(); g_autoptr(virJSONValue) resources = virJSONValueNewArray();
g_autofree virHashKeyValuePair *pairs = NULL; g_autofree virHashKeyValuePair *pairs = NULL;
virHashKeyValuePair *tmp; virHashKeyValuePair *tmp;
VIR_LOCK_GUARD lock = virLockGuardLock(&lockspace->lock);
virMutexLock(&lockspace->lock);
if (lockspace->dir && if (lockspace->dir &&
virJSONValueObjectAppendString(object, "directory", lockspace->dir) < 0) virJSONValueObjectAppendString(object, "directory", lockspace->dir) < 0)
goto error; return NULL;
tmp = pairs = virHashGetItems(lockspace->resources, NULL, false); tmp = pairs = virHashGetItems(lockspace->resources, NULL, false);
@ -434,41 +433,36 @@ virJSONValue *virLockSpacePreExecRestart(virLockSpace *lockspace)
virJSONValueObjectAppendNumberInt(child, "fd", res->fd) < 0 || virJSONValueObjectAppendNumberInt(child, "fd", res->fd) < 0 ||
virJSONValueObjectAppendBoolean(child, "lockHeld", res->lockHeld) < 0 || virJSONValueObjectAppendBoolean(child, "lockHeld", res->lockHeld) < 0 ||
virJSONValueObjectAppendNumberUint(child, "flags", res->flags) < 0) virJSONValueObjectAppendNumberUint(child, "flags", res->flags) < 0)
goto error; return NULL;
if (virSetInherit(res->fd, true) < 0) { if (virSetInherit(res->fd, true) < 0) {
virReportSystemError(errno, "%s", virReportSystemError(errno, "%s",
_("Cannot disable close-on-exec flag")); _("Cannot disable close-on-exec flag"));
goto error; return NULL;
} }
for (i = 0; i < res->nOwners; i++) { for (i = 0; i < res->nOwners; i++) {
g_autoptr(virJSONValue) owner = virJSONValueNewNumberUlong(res->owners[i]); g_autoptr(virJSONValue) owner = virJSONValueNewNumberUlong(res->owners[i]);
if (!owner) if (!owner)
goto error; return NULL;
if (virJSONValueArrayAppend(owners, &owner) < 0) if (virJSONValueArrayAppend(owners, &owner) < 0)
goto error; return NULL;
} }
if (virJSONValueObjectAppend(child, "owners", &owners) < 0) if (virJSONValueObjectAppend(child, "owners", &owners) < 0)
goto error; return NULL;
if (virJSONValueArrayAppend(resources, &child) < 0) if (virJSONValueArrayAppend(resources, &child) < 0)
goto error; return NULL;
tmp++; tmp++;
} }
if (virJSONValueObjectAppend(object, "resources", &resources) < 0) if (virJSONValueObjectAppend(object, "resources", &resources) < 0)
goto error; return NULL;
virMutexUnlock(&lockspace->lock);
return g_steal_pointer(&object); return g_steal_pointer(&object);
error:
virMutexUnlock(&lockspace->lock);
return NULL;
} }
@ -493,67 +487,55 @@ const char *virLockSpaceGetDirectory(virLockSpace *lockspace)
int virLockSpaceCreateResource(virLockSpace *lockspace, int virLockSpaceCreateResource(virLockSpace *lockspace,
const char *resname) const char *resname)
{ {
int ret = -1;
g_autofree char *respath = NULL; g_autofree char *respath = NULL;
VIR_LOCK_GUARD lock = virLockGuardLock(&lockspace->lock);
VIR_DEBUG("lockspace=%p resname=%s", lockspace, resname); VIR_DEBUG("lockspace=%p resname=%s", lockspace, resname);
virMutexLock(&lockspace->lock);
if (virHashLookup(lockspace->resources, resname) != NULL) { if (virHashLookup(lockspace->resources, resname) != NULL) {
virReportError(VIR_ERR_RESOURCE_BUSY, virReportError(VIR_ERR_RESOURCE_BUSY,
_("Lockspace resource '%s' is locked"), _("Lockspace resource '%s' is locked"),
resname); resname);
goto cleanup; return -1;
} }
if (!(respath = virLockSpaceGetResourcePath(lockspace, resname))) if (!(respath = virLockSpaceGetResourcePath(lockspace, resname)))
goto cleanup; return -1;
if (virFileTouch(respath, 0600) < 0) if (virFileTouch(respath, 0600) < 0)
goto cleanup; return -1;
ret = 0; return 0;
cleanup:
virMutexUnlock(&lockspace->lock);
return ret;
} }
int virLockSpaceDeleteResource(virLockSpace *lockspace, int virLockSpaceDeleteResource(virLockSpace *lockspace,
const char *resname) const char *resname)
{ {
int ret = -1;
g_autofree char *respath = NULL; g_autofree char *respath = NULL;
VIR_LOCK_GUARD lock = virLockGuardLock(&lockspace->lock);
VIR_DEBUG("lockspace=%p resname=%s", lockspace, resname); VIR_DEBUG("lockspace=%p resname=%s", lockspace, resname);
virMutexLock(&lockspace->lock);
if (virHashLookup(lockspace->resources, resname) != NULL) { if (virHashLookup(lockspace->resources, resname) != NULL) {
virReportError(VIR_ERR_RESOURCE_BUSY, virReportError(VIR_ERR_RESOURCE_BUSY,
_("Lockspace resource '%s' is locked"), _("Lockspace resource '%s' is locked"),
resname); resname);
goto cleanup; return -1;
} }
if (!(respath = virLockSpaceGetResourcePath(lockspace, resname))) if (!(respath = virLockSpaceGetResourcePath(lockspace, resname)))
goto cleanup; return -1;
if (unlink(respath) < 0 && if (unlink(respath) < 0 &&
errno != ENOENT) { errno != ENOENT) {
virReportSystemError(errno, virReportSystemError(errno,
_("Unable to delete lockspace resource %s"), _("Unable to delete lockspace resource %s"),
respath); respath);
goto cleanup; return -1;
} }
ret = 0; return 0;
cleanup:
virMutexUnlock(&lockspace->lock);
return ret;
} }
@ -562,8 +544,8 @@ int virLockSpaceAcquireResource(virLockSpace *lockspace,
pid_t owner, pid_t owner,
unsigned int flags) unsigned int flags)
{ {
int ret = -1;
virLockSpaceResource *res; virLockSpaceResource *res;
VIR_LOCK_GUARD lock = virLockGuardLock(&lockspace->lock);
VIR_DEBUG("lockspace=%p resname=%s flags=0x%x owner=%lld", VIR_DEBUG("lockspace=%p resname=%s flags=0x%x owner=%lld",
lockspace, resname, flags, (unsigned long long)owner); lockspace, resname, flags, (unsigned long long)owner);
@ -571,8 +553,6 @@ int virLockSpaceAcquireResource(virLockSpace *lockspace,
virCheckFlags(VIR_LOCK_SPACE_ACQUIRE_SHARED | virCheckFlags(VIR_LOCK_SPACE_ACQUIRE_SHARED |
VIR_LOCK_SPACE_ACQUIRE_AUTOCREATE, -1); VIR_LOCK_SPACE_ACQUIRE_AUTOCREATE, -1);
virMutexLock(&lockspace->lock);
if ((res = virHashLookup(lockspace->resources, resname))) { if ((res = virHashLookup(lockspace->resources, resname))) {
if ((res->flags & VIR_LOCK_SPACE_ACQUIRE_SHARED) && if ((res->flags & VIR_LOCK_SPACE_ACQUIRE_SHARED) &&
(flags & VIR_LOCK_SPACE_ACQUIRE_SHARED)) { (flags & VIR_LOCK_SPACE_ACQUIRE_SHARED)) {
@ -580,28 +560,23 @@ int virLockSpaceAcquireResource(virLockSpace *lockspace,
VIR_EXPAND_N(res->owners, res->nOwners, 1); VIR_EXPAND_N(res->owners, res->nOwners, 1);
res->owners[res->nOwners-1] = owner; res->owners[res->nOwners-1] = owner;
goto done; return 0;
} }
virReportError(VIR_ERR_RESOURCE_BUSY, virReportError(VIR_ERR_RESOURCE_BUSY,
_("Lockspace resource '%s' is locked"), _("Lockspace resource '%s' is locked"),
resname); resname);
goto cleanup; return -1;
} }
if (!(res = virLockSpaceResourceNew(lockspace, resname, flags, owner))) if (!(res = virLockSpaceResourceNew(lockspace, resname, flags, owner)))
goto cleanup; return -1;
if (virHashAddEntry(lockspace->resources, resname, res) < 0) { if (virHashAddEntry(lockspace->resources, resname, res) < 0) {
virLockSpaceResourceFree(res); virLockSpaceResourceFree(res);
goto cleanup; return -1;
} }
done: return 0;
ret = 0;
cleanup:
virMutexUnlock(&lockspace->lock);
return ret;
} }
@ -609,20 +584,18 @@ int virLockSpaceReleaseResource(virLockSpace *lockspace,
const char *resname, const char *resname,
pid_t owner) pid_t owner)
{ {
int ret = -1;
virLockSpaceResource *res; virLockSpaceResource *res;
size_t i; size_t i;
VIR_LOCK_GUARD lock = virLockGuardLock(&lockspace->lock);
VIR_DEBUG("lockspace=%p resname=%s owner=%lld", VIR_DEBUG("lockspace=%p resname=%s owner=%lld",
lockspace, resname, (unsigned long long)owner); lockspace, resname, (unsigned long long)owner);
virMutexLock(&lockspace->lock);
if (!(res = virHashLookup(lockspace->resources, resname))) { if (!(res = virHashLookup(lockspace->resources, resname))) {
virReportError(VIR_ERR_RESOURCE_BUSY, virReportError(VIR_ERR_RESOURCE_BUSY,
_("Lockspace resource '%s' is not locked"), _("Lockspace resource '%s' is not locked"),
resname); resname);
goto cleanup; return -1;
} }
for (i = 0; i < res->nOwners; i++) { for (i = 0; i < res->nOwners; i++) {
@ -634,20 +607,16 @@ int virLockSpaceReleaseResource(virLockSpace *lockspace,
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("owner %lld does not hold the resource lock"), _("owner %lld does not hold the resource lock"),
(unsigned long long)owner); (unsigned long long)owner);
goto cleanup; return -1;
} }
VIR_DELETE_ELEMENT(res->owners, i, res->nOwners); VIR_DELETE_ELEMENT(res->owners, i, res->nOwners);
if ((res->nOwners == 0) && if ((res->nOwners == 0) &&
virHashRemoveEntry(lockspace->resources, resname) < 0) virHashRemoveEntry(lockspace->resources, resname) < 0)
goto cleanup; return -1;
ret = 0; return 0;
cleanup:
virMutexUnlock(&lockspace->lock);
return ret;
} }
@ -693,26 +662,17 @@ virLockSpaceRemoveResourcesForOwner(const void *payload,
int virLockSpaceReleaseResourcesForOwner(virLockSpace *lockspace, int virLockSpaceReleaseResourcesForOwner(virLockSpace *lockspace,
pid_t owner) pid_t owner)
{ {
int ret = 0;
struct virLockSpaceRemoveData data = { struct virLockSpaceRemoveData data = {
owner, 0 owner, 0
}; };
VIR_LOCK_GUARD lock = virLockGuardLock(&lockspace->lock);
VIR_DEBUG("lockspace=%p owner=%lld", lockspace, (unsigned long long)owner); VIR_DEBUG("lockspace=%p owner=%lld", lockspace, (unsigned long long)owner);
virMutexLock(&lockspace->lock);
if (virHashRemoveSet(lockspace->resources, if (virHashRemoveSet(lockspace->resources,
virLockSpaceRemoveResourcesForOwner, virLockSpaceRemoveResourcesForOwner,
&data) < 0) &data) < 0)
goto error; return -1;
ret = data.count; return data.count;
virMutexUnlock(&lockspace->lock);
return ret;
error:
virMutexUnlock(&lockspace->lock);
return -1;
} }