mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
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:
parent
c6a9e54ce3
commit
feef23e130
@ -202,23 +202,30 @@ static void virChrdevLockFileRemove(const char *dev G_GNUC_UNUSED)
|
||||
}
|
||||
#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
|
||||
*
|
||||
* @data Opaque data, struct holding information about the device
|
||||
* @name Path of the device.
|
||||
*/
|
||||
static void virChrdevHashEntryFree(void *data,
|
||||
const void *name)
|
||||
static void virChrdevHashEntryFree(void *data, const void *key G_GNUC_UNUSED)
|
||||
{
|
||||
const char *dev = name;
|
||||
virStreamPtr st = data;
|
||||
virChrdevHashEntry *ent = data;
|
||||
|
||||
if (!ent)
|
||||
return;
|
||||
|
||||
/* free stream reference */
|
||||
virObjectUnref(st);
|
||||
virObjectUnref(ent->st);
|
||||
|
||||
/* 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,
|
||||
void *data G_GNUC_UNUSED)
|
||||
{
|
||||
virStreamPtr st = payload;
|
||||
virChrdevHashEntry *ent = payload;
|
||||
|
||||
virFDStreamSetInternalCloseCb(st, NULL, NULL, NULL);
|
||||
virFDStreamSetInternalCloseCb(ent->st, NULL, NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -337,7 +344,7 @@ int virChrdevOpen(virChrdevsPtr devs,
|
||||
bool force)
|
||||
{
|
||||
virChrdevStreamInfoPtr cbdata = NULL;
|
||||
virStreamPtr savedStream;
|
||||
virChrdevHashEntry *ent;
|
||||
char *path;
|
||||
int ret;
|
||||
bool added = false;
|
||||
@ -363,7 +370,7 @@ int virChrdevOpen(virChrdevsPtr devs,
|
||||
|
||||
virMutexLock(&devs->lock);
|
||||
|
||||
if ((savedStream = virHashLookup(devs->hash, path))) {
|
||||
if ((ent = virHashLookup(devs->hash, path))) {
|
||||
if (!force) {
|
||||
/* entry found, device is busy */
|
||||
virMutexUnlock(&devs->lock);
|
||||
@ -376,8 +383,8 @@ int virChrdevOpen(virChrdevsPtr devs,
|
||||
* same thread. We need to unregister the callback and abort the
|
||||
* stream manually before we create a new device connection.
|
||||
*/
|
||||
virFDStreamSetInternalCloseCb(savedStream, NULL, NULL, NULL);
|
||||
virStreamAbort(savedStream);
|
||||
virFDStreamSetInternalCloseCb(ent->st, NULL, NULL, NULL);
|
||||
virStreamAbort(ent->st);
|
||||
virHashRemoveEntry(devs->hash, path);
|
||||
/* continue adding a new stream connection */
|
||||
}
|
||||
@ -398,8 +405,15 @@ int virChrdevOpen(virChrdevsPtr devs,
|
||||
if (VIR_ALLOC(cbdata) < 0)
|
||||
goto error;
|
||||
|
||||
if (virHashAddEntry(devs->hash, path, st) < 0)
|
||||
if (VIR_ALLOC(ent) < 0)
|
||||
goto error;
|
||||
|
||||
ent->st = st;
|
||||
ent->dev = g_strdup(path);
|
||||
|
||||
if (virHashAddEntry(devs->hash, path, ent) < 0)
|
||||
goto error;
|
||||
ent = NULL;
|
||||
added = true;
|
||||
|
||||
cbdata->devs = devs;
|
||||
@ -441,5 +455,6 @@ int virChrdevOpen(virChrdevsPtr devs,
|
||||
VIR_FREE(cbdata->path);
|
||||
VIR_FREE(cbdata);
|
||||
virMutexUnlock(&devs->lock);
|
||||
virChrdevHashEntryFree(ent, NULL);
|
||||
return -1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user