conf: stop using hash key when free'ing hash entries

The virChrdevHashEntryFree method uses the hash 'key'
as the name of the logfile it has to remove. By storing
a struct as the value which contains the stream and
the dev path, we can avoid relying on the hash key
when free'ing entries.

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrangé 2019-11-22 10:49:27 +00:00
parent c6a9e54ce3
commit feef23e130

View File

@ -202,23 +202,30 @@ static void virChrdevLockFileRemove(const char *dev G_GNUC_UNUSED)
} }
#endif /* #ifdef VIR_CHRDEV_LOCK_FILE_PATH */ #endif /* #ifdef VIR_CHRDEV_LOCK_FILE_PATH */
typedef struct {
char *dev;
virStreamPtr st;
} virChrdevHashEntry;
/** /**
* Frees an entry from the hash containing domain's active devices * Frees an entry from the hash containing domain's active devices
* *
* @data Opaque data, struct holding information about the device * @data Opaque data, struct holding information about the device
* @name Path of the device.
*/ */
static void virChrdevHashEntryFree(void *data, static void virChrdevHashEntryFree(void *data, const void *key G_GNUC_UNUSED)
const void *name)
{ {
const char *dev = name; virChrdevHashEntry *ent = data;
virStreamPtr st = data;
if (!ent)
return;
/* free stream reference */ /* free stream reference */
virObjectUnref(st); virObjectUnref(ent->st);
/* delete lock file */ /* delete lock file */
virChrdevLockFileRemove(dev); virChrdevLockFileRemove(ent->dev);
g_free(ent);
} }
/** /**
@ -290,9 +297,9 @@ static int virChrdevFreeClearCallbacks(void *payload,
const void *name G_GNUC_UNUSED, const void *name G_GNUC_UNUSED,
void *data G_GNUC_UNUSED) void *data G_GNUC_UNUSED)
{ {
virStreamPtr st = payload; virChrdevHashEntry *ent = payload;
virFDStreamSetInternalCloseCb(st, NULL, NULL, NULL); virFDStreamSetInternalCloseCb(ent->st, NULL, NULL, NULL);
return 0; return 0;
} }
@ -337,7 +344,7 @@ int virChrdevOpen(virChrdevsPtr devs,
bool force) bool force)
{ {
virChrdevStreamInfoPtr cbdata = NULL; virChrdevStreamInfoPtr cbdata = NULL;
virStreamPtr savedStream; virChrdevHashEntry *ent;
char *path; char *path;
int ret; int ret;
bool added = false; bool added = false;
@ -363,7 +370,7 @@ int virChrdevOpen(virChrdevsPtr devs,
virMutexLock(&devs->lock); virMutexLock(&devs->lock);
if ((savedStream = virHashLookup(devs->hash, path))) { if ((ent = virHashLookup(devs->hash, path))) {
if (!force) { if (!force) {
/* entry found, device is busy */ /* entry found, device is busy */
virMutexUnlock(&devs->lock); virMutexUnlock(&devs->lock);
@ -376,8 +383,8 @@ int virChrdevOpen(virChrdevsPtr devs,
* same thread. We need to unregister the callback and abort the * same thread. We need to unregister the callback and abort the
* stream manually before we create a new device connection. * stream manually before we create a new device connection.
*/ */
virFDStreamSetInternalCloseCb(savedStream, NULL, NULL, NULL); virFDStreamSetInternalCloseCb(ent->st, NULL, NULL, NULL);
virStreamAbort(savedStream); virStreamAbort(ent->st);
virHashRemoveEntry(devs->hash, path); virHashRemoveEntry(devs->hash, path);
/* continue adding a new stream connection */ /* continue adding a new stream connection */
} }
@ -398,8 +405,15 @@ int virChrdevOpen(virChrdevsPtr devs,
if (VIR_ALLOC(cbdata) < 0) if (VIR_ALLOC(cbdata) < 0)
goto error; goto error;
if (virHashAddEntry(devs->hash, path, st) < 0) if (VIR_ALLOC(ent) < 0)
goto error; goto error;
ent->st = st;
ent->dev = g_strdup(path);
if (virHashAddEntry(devs->hash, path, ent) < 0)
goto error;
ent = NULL;
added = true; added = true;
cbdata->devs = devs; cbdata->devs = devs;
@ -441,5 +455,6 @@ int virChrdevOpen(virChrdevsPtr devs,
VIR_FREE(cbdata->path); VIR_FREE(cbdata->path);
VIR_FREE(cbdata); VIR_FREE(cbdata);
virMutexUnlock(&devs->lock); virMutexUnlock(&devs->lock);
virChrdevHashEntryFree(ent, NULL);
return -1; return -1;
} }