snapshot: Break out virDomainSnapshotObj into its own file

snapshot_conf.h was mixing three separate types: the snapshot
definition, the snapshot object, and the snapshot object list.
Separate out the snapshot object code into its own file, which
includes moving a typedef to avoid circular inclusions.

Mostly straight code motion, although I fixed a comment along
the way, now that virDomainSnapshotForEachDescendent now
guarantees a topological visit (missed in b647d219).

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Eric Blake 2019-03-14 20:03:40 -05:00
parent 41e3d35e09
commit ca20690e9f
7 changed files with 184 additions and 107 deletions

View File

@ -29,6 +29,8 @@ DOMAIN_CONF_SOURCES = \
conf/virconftypes.h \
conf/virdomainobjlist.c \
conf/virdomainobjlist.h \
conf/virdomainsnapshotobj.c \
conf/virdomainsnapshotobj.h \
$(NULL)
OBJECT_EVENT_SOURCES = \

View File

@ -1299,64 +1299,6 @@ virDomainSnapshotForEach(virDomainSnapshotObjListPtr snapshots,
return virHashForEach(snapshots->objs, iter, data);
}
/* Run iter(data) on all direct children of snapshot, while ignoring all
* other entries in snapshots. Return the number of children
* visited. No particular ordering is guaranteed. */
int
virDomainSnapshotForEachChild(virDomainSnapshotObjPtr snapshot,
virHashIterator iter,
void *data)
{
virDomainSnapshotObjPtr child = snapshot->first_child;
while (child) {
virDomainSnapshotObjPtr next = child->sibling;
(iter)(child, child->def->name, data);
child = next;
}
return snapshot->nchildren;
}
struct snapshot_act_on_descendant {
int number;
virHashIterator iter;
void *data;
};
static int
virDomainSnapshotActOnDescendant(void *payload,
const void *name,
void *data)
{
virDomainSnapshotObjPtr obj = payload;
struct snapshot_act_on_descendant *curr = data;
(curr->iter)(payload, name, curr->data);
curr->number += 1 + virDomainSnapshotForEachDescendant(obj,
curr->iter,
curr->data);
return 0;
}
/* Run iter(data) on all descendants of snapshot, while ignoring all
* other entries in snapshots. Return the number of descendants
* visited. No particular ordering is guaranteed. */
int
virDomainSnapshotForEachDescendant(virDomainSnapshotObjPtr snapshot,
virHashIterator iter,
void *data)
{
struct snapshot_act_on_descendant act;
act.number = 0;
act.iter = iter;
act.data = data;
virDomainSnapshotForEachChild(snapshot,
virDomainSnapshotActOnDescendant, &act);
return act.number;
}
/* Struct and callback function used as a hash table callback; each call
* inspects the pre-existing snapshot->def->parent field, and adjusts
@ -1416,33 +1358,6 @@ virDomainSnapshotUpdateRelations(virDomainSnapshotObjListPtr snapshots)
return act.err;
}
/* Prepare to reparent or delete snapshot, by removing it from its
* current listed parent. Note that when bulk removing all children
* of a parent, it is faster to just 0 the count rather than calling
* this function on each child. */
void
virDomainSnapshotDropParent(virDomainSnapshotObjPtr snapshot)
{
virDomainSnapshotObjPtr prev = NULL;
virDomainSnapshotObjPtr curr = NULL;
snapshot->parent->nchildren--;
curr = snapshot->parent->first_child;
while (curr != snapshot) {
if (!curr) {
VIR_WARN("inconsistent snapshot relations");
return;
}
prev = curr;
curr = curr->sibling;
}
if (prev)
prev->sibling = snapshot->sibling;
else
snapshot->parent->first_child = snapshot->sibling;
snapshot->parent = NULL;
snapshot->sibling = NULL;
}
int
virDomainListSnapshots(virDomainSnapshotObjListPtr snapshots,

View File

@ -24,6 +24,7 @@
# include "internal.h"
# include "domain_conf.h"
# include "virdomainsnapshotobj.h"
/* Items related to snapshot state */
@ -71,8 +72,6 @@ struct _virDomainSnapshotDiskDef {
};
/* Stores the complete snapshot metadata */
typedef struct _virDomainSnapshotDef virDomainSnapshotDef;
typedef virDomainSnapshotDef *virDomainSnapshotDefPtr;
struct _virDomainSnapshotDef {
/* Public XML. */
char *name;
@ -95,16 +94,6 @@ struct _virDomainSnapshotDef {
bool current; /* At most one snapshot in the list should have this set */
};
struct _virDomainSnapshotObj {
virDomainSnapshotDefPtr def; /* non-NULL except for metaroot */
virDomainSnapshotObjPtr parent; /* non-NULL except for metaroot, before
virDomainSnapshotUpdateRelations, or
after virDomainSnapshotDropParent */
virDomainSnapshotObjPtr sibling; /* NULL if last child of parent */
size_t nchildren;
virDomainSnapshotObjPtr first_child; /* NULL if no children */
};
virDomainSnapshotObjListPtr virDomainSnapshotObjListNew(void);
void virDomainSnapshotObjListFree(virDomainSnapshotObjListPtr snapshots);
@ -172,14 +161,7 @@ void virDomainSnapshotObjListRemove(virDomainSnapshotObjListPtr snapshots,
int virDomainSnapshotForEach(virDomainSnapshotObjListPtr snapshots,
virHashIterator iter,
void *data);
int virDomainSnapshotForEachChild(virDomainSnapshotObjPtr snapshot,
virHashIterator iter,
void *data);
int virDomainSnapshotForEachDescendant(virDomainSnapshotObjPtr snapshot,
virHashIterator iter,
void *data);
int virDomainSnapshotUpdateRelations(virDomainSnapshotObjListPtr snapshots);
void virDomainSnapshotDropParent(virDomainSnapshotObjPtr snapshot);
# define VIR_DOMAIN_SNAPSHOT_FILTERS_METADATA \
(VIR_DOMAIN_SNAPSHOT_LIST_METADATA | \

View File

@ -274,6 +274,9 @@ typedef virDomainShmemDef *virDomainShmemDefPtr;
typedef struct _virDomainSmartcardDef virDomainSmartcardDef;
typedef virDomainSmartcardDef *virDomainSmartcardDefPtr;
typedef struct _virDomainSnapshotDef virDomainSnapshotDef;
typedef virDomainSnapshotDef *virDomainSnapshotDefPtr;
typedef struct _virDomainSnapshotObj virDomainSnapshotObj;
typedef virDomainSnapshotObj *virDomainSnapshotObjPtr;

View File

@ -0,0 +1,122 @@
/*
* virdomainsnapshotobj.c: handle snapshot objects
* (derived from snapshot_conf.c)
*
* Copyright (C) 2006-2019 Red Hat, Inc.
* Copyright (C) 2006-2008 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include "internal.h"
#include "virdomainsnapshotobj.h"
#include "snapshot_conf.h"
#include "virlog.h"
#include "virerror.h"
#define VIR_FROM_THIS VIR_FROM_DOMAIN_SNAPSHOT
VIR_LOG_INIT("conf.virdomainsnapshotobj");
/* Run iter(data) on all direct children of snapshot, while ignoring all
* other entries in snapshots. Return the number of children
* visited. No particular ordering is guaranteed. */
int
virDomainSnapshotForEachChild(virDomainSnapshotObjPtr snapshot,
virHashIterator iter,
void *data)
{
virDomainSnapshotObjPtr child = snapshot->first_child;
while (child) {
virDomainSnapshotObjPtr next = child->sibling;
(iter)(child, child->def->name, data);
child = next;
}
return snapshot->nchildren;
}
struct snapshot_act_on_descendant {
int number;
virHashIterator iter;
void *data;
};
static int
virDomainSnapshotActOnDescendant(void *payload,
const void *name,
void *data)
{
virDomainSnapshotObjPtr obj = payload;
struct snapshot_act_on_descendant *curr = data;
(curr->iter)(payload, name, curr->data);
curr->number += 1 + virDomainSnapshotForEachDescendant(obj,
curr->iter,
curr->data);
return 0;
}
/* Run iter(data) on all descendants of snapshot, while ignoring all
* other entries in snapshots. Return the number of descendants
* visited. The visit is guaranteed to be topological, but no
* particular order between siblings is guaranteed. */
int
virDomainSnapshotForEachDescendant(virDomainSnapshotObjPtr snapshot,
virHashIterator iter,
void *data)
{
struct snapshot_act_on_descendant act;
act.number = 0;
act.iter = iter;
act.data = data;
virDomainSnapshotForEachChild(snapshot,
virDomainSnapshotActOnDescendant, &act);
return act.number;
}
/* Prepare to reparent or delete snapshot, by removing it from its
* current listed parent. Note that when bulk removing all children
* of a parent, it is faster to just 0 the count rather than calling
* this function on each child. */
void
virDomainSnapshotDropParent(virDomainSnapshotObjPtr snapshot)
{
virDomainSnapshotObjPtr prev = NULL;
virDomainSnapshotObjPtr curr = NULL;
snapshot->parent->nchildren--;
curr = snapshot->parent->first_child;
while (curr != snapshot) {
if (!curr) {
VIR_WARN("inconsistent snapshot relations");
return;
}
prev = curr;
curr = curr->sibling;
}
if (prev)
prev->sibling = snapshot->sibling;
else
snapshot->parent->first_child = snapshot->sibling;
snapshot->parent = NULL;
snapshot->sibling = NULL;
}

View File

@ -0,0 +1,50 @@
/*
* virdomainsnapshotobj.h: handle snapshot objects
* (derived from snapshot_conf.h)
*
* Copyright (C) 2006-2019 Red Hat, Inc.
* Copyright (C) 2006-2008 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef LIBVIRT_VIRDOMAINSNAPSHOTOBJ_H
# define LIBVIRT_VIRDOMAINSNAPSHOTOBJ_H
# include "internal.h"
# include "virconftypes.h"
# include "virhash.h"
struct _virDomainSnapshotObj {
virDomainSnapshotDefPtr def; /* non-NULL except for metaroot */
virDomainSnapshotObjPtr parent; /* non-NULL except for metaroot, before
virDomainSnapshotUpdateRelations, or
after virDomainSnapshotDropParent */
virDomainSnapshotObjPtr sibling; /* NULL if last child of parent */
size_t nchildren;
virDomainSnapshotObjPtr first_child; /* NULL if no children */
};
int virDomainSnapshotForEachChild(virDomainSnapshotObjPtr snapshot,
virHashIterator iter,
void *data);
int virDomainSnapshotForEachDescendant(virDomainSnapshotObjPtr snapshot,
virHashIterator iter,
void *data);
void virDomainSnapshotDropParent(virDomainSnapshotObjPtr snapshot);
#endif /* LIBVIRT_VIRDOMAINSNAPSHOTOBJ_H */

View File

@ -890,11 +890,8 @@ virDomainSnapshotDefFormat;
virDomainSnapshotDefFree;
virDomainSnapshotDefIsExternal;
virDomainSnapshotDefParseString;
virDomainSnapshotDropParent;
virDomainSnapshotFindByName;
virDomainSnapshotForEach;
virDomainSnapshotForEachChild;
virDomainSnapshotForEachDescendant;
virDomainSnapshotFormatConvertXMLFlags;
virDomainSnapshotIsExternal;
virDomainSnapshotLocationTypeFromString;
@ -992,6 +989,12 @@ virDomainObjListRemoveLocked;
virDomainObjListRename;
# conf/virdomainsnapshotobj.h
virDomainSnapshotDropParent;
virDomainSnapshotForEachChild;
virDomainSnapshotForEachDescendant;
# conf/virinterfaceobj.h
virInterfaceObjEndAPI;
virInterfaceObjGetDef;