Skip to content

Commit

Permalink
storage: Add support for volume snapshots
Browse files Browse the repository at this point in the history
NOTE: THIS DOES NOT WORK YET, PURE PROTOTYPE

This patch adds support for creating, deleting, reverting and listing
snapshots of storage volumes.

This allows for snapshotting volumes managed by libvirt without talking
directly to the backing storage.
  • Loading branch information
wido committed Dec 25, 2015
1 parent 7bf3c13 commit 4483ab2
Show file tree
Hide file tree
Showing 8 changed files with 489 additions and 0 deletions.
38 changes: 38 additions & 0 deletions include/libvirt/libvirt-storage.h
Expand Up @@ -177,6 +177,31 @@ typedef enum {
VIR_STORAGE_XML_INACTIVE = (1 << 0), /* dump inactive pool/volume information */
} virStorageXMLFlags;


/**
* virStorageVolSnap:
*
* a virStorageVolSnap is a private structure representing a storage volume snapshot
*/
typedef struct _virStorageVolSnap virStorageVolSnap;

/**
* virStorageVolSnapPtr:
*
* a virStorageVolSnapPtr is pointer to a virStorageVolSnap private structure, this is the
* type used to reference a volume snapshot in the API.
*/
typedef virStorageVolSnap *virStorageVolSnapPtr;

typedef struct _virStorageVolSnapInfo virStorageVolSnapInfo;

struct _virStorageVolSnapInfo {
int type; /* virStorageVolType flags */
unsigned long long allocated; /* Current size of snapshot in bytes */
};

typedef virStorageVolSnapInfo *virStorageVolSnapInfoPtr;

/*
* Get connection from pool.
*/
Expand Down Expand Up @@ -350,6 +375,19 @@ int virStorageVolWipe (virStorageVolPtr vol,
int virStorageVolWipePattern (virStorageVolPtr vol,
unsigned int algorithm,
unsigned int flags);
virStorageVolSnapPtr virStorageVolSnapCreate (virStorageVolPtr vol,
const char *xmldesc,
unsigned int flags);
int virStorageVolSnapDelete (virStorageVolSnapPtr snap,
unsigned int flags);
int virStorageVolSnapRevert (virStorageVolSnapPtr snap,
unsigned int flags);
int virStorageVolSnapList (virStorageVolPtr vol,
virStorageVolSnapPtr **snaps,
unsigned int flags);
int virStorageVolSnapGetInfo (virStorageVolSnapPtr snap,
virStorageVolSnapInfoPtr info,
unsigned int flags);
int virStorageVolRef (virStorageVolPtr vol);
int virStorageVolFree (virStorageVolPtr vol);

Expand Down
111 changes: 111 additions & 0 deletions src/conf/storage_conf.c
Expand Up @@ -326,6 +326,18 @@ virStorageVolDefFree(virStorageVolDefPtr def)
VIR_FREE(def);
}

void
virStorageVolSnapDefFree(virStorageVolSnapDefPtr def)
{
if (!def)
return;

VIR_FREE(def->name);
VIR_FREE(def->key);

VIR_FREE(def);
}

static void
virStoragePoolSourceAdapterClear(virStoragePoolSourceAdapterPtr adapter)
{
Expand Down Expand Up @@ -1484,6 +1496,105 @@ virStorageVolDefParseFile(virStoragePoolDefPtr pool,
return virStorageVolDefParse(pool, NULL, filename, flags);
}

static virStorageVolSnapDefPtr
virStorageVolSnapDefParseXML(virStoragePoolDefPtr pool,
xmlXPathContextPtr ctxt,
unsigned int flags)
{
virStorageVolSnapDefPtr ret;

virCheckFlags(0, NULL);

if (VIR_ALLOC(ret) < 0)
return NULL;

if (pool == NULL)
return NULL;

ret->name = virXPathString("string(./name)", ctxt);
if (ret->name == NULL) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("missing snapshot name element"));
goto error;
}

ret->key = virXPathString("string(./key)", ctxt);


cleanup:
return ret;

error:
virStorageVolSnapDefFree(ret);
ret = NULL;
goto cleanup;
}

virStorageVolSnapDefPtr
virStorageVolSnapDefParseNode(virStoragePoolDefPtr pool,
xmlDocPtr xml,
xmlNodePtr root,
unsigned int flags)
{
xmlXPathContextPtr ctxt = NULL;
virStorageVolSnapDefPtr def = NULL;

if (!xmlStrEqual(root->name, BAD_CAST "snapshot")) {
virReportError(VIR_ERR_XML_ERROR,
_("unexpected root element <%s>, "
"expecting <snapshot>"),
root->name);
goto cleanup;
}

ctxt = xmlXPathNewContext(xml);
if (ctxt == NULL) {
virReportOOMError();
goto cleanup;
}

ctxt->node = root;
def = virStorageVolSnapDefParseXML(pool, ctxt, flags);

cleanup:
xmlXPathFreeContext(ctxt);
return def;
}

static virStorageVolSnapDefPtr
virStorageVolSnapDefParse(virStoragePoolDefPtr pool,
const char *xmlStr,
const char *filename,
unsigned int flags)
{
virStorageVolSnapDefPtr ret = NULL;
xmlDocPtr xml;

if ((xml = virXMLParse(filename, xmlStr, _("(storage_volume_snapshot_definition)")))) {
ret = virStorageVolSnapDefParseNode(pool, xml, xmlDocGetRootElement(xml), flags);
xmlFreeDoc(xml);
}

return ret;
}

virStorageVolSnapDefPtr
virStorageVolSnapDefParseString(virStoragePoolDefPtr pool,
const char *xmlStr,
unsigned int flags)
{
return virStorageVolSnapDefParse(pool, xmlStr, NULL, flags);
}

virStorageVolSnapDefPtr
virStorageVolSnapDefParseFile(virStoragePoolDefPtr pool,
const char *filename,
unsigned int flags)
{
return virStorageVolSnapDefParse(pool, NULL, filename, flags);
}


static void
virStorageVolTimestampFormat(virBufferPtr buf, const char *name,
struct timespec *ts)
Expand Down
30 changes: 30 additions & 0 deletions src/conf/storage_conf.h
Expand Up @@ -79,6 +79,22 @@ struct _virStorageVolDefList {
virStorageVolDefPtr *objs;
};

typedef struct _virStorageVolSnapDef virStorageVolSnapDef;
typedef virStorageVolSnapDef *virStorageVolSnapDefPtr;
struct _virStorageVolSnapDef {
char *name;
char *key;

virStorageVolDef vol;
};

typedef struct _virStorageVolSnapDefList virStorageVolSnapDefList;
typedef virStorageVolSnapDefList *virStorageVolSnapDefListPtr;
struct _virStorageVolSnapDefList {
size_t count;
virStorageVolSnapDefPtr *objs;
};

VIR_ENUM_DECL(virStorageVol)

typedef enum {
Expand Down Expand Up @@ -363,15 +379,28 @@ virStorageVolDefPtr
virStorageVolDefParseString(virStoragePoolDefPtr pool,
const char *xml,
unsigned int flags);
virStorageVolSnapDefPtr
virStorageVolSnapDefParseString(virStoragePoolDefPtr pool,
const char *xml,
unsigned int flags);
virStorageVolDefPtr
virStorageVolDefParseFile(virStoragePoolDefPtr pool,
const char *filename,
unsigned int flags);
virStorageVolSnapDefPtr
virStorageVolSnapDefParseFile(virStoragePoolDefPtr pool,
const char *filename,
unsigned int flags);
virStorageVolDefPtr
virStorageVolDefParseNode(virStoragePoolDefPtr pool,
xmlDocPtr xml,
xmlNodePtr root,
unsigned int flags);
virStorageVolSnapDefPtr
virStorageVolSnapDefParseNode(virStoragePoolDefPtr pool,
xmlDocPtr xml,
xmlNodePtr root,
unsigned int flags);
char *virStorageVolDefFormat(virStoragePoolDefPtr pool,
virStorageVolDefPtr def);

Expand All @@ -389,6 +418,7 @@ int virStoragePoolObjSaveDef(virStorageDriverStatePtr driver,
int virStoragePoolObjDeleteDef(virStoragePoolObjPtr pool);

void virStorageVolDefFree(virStorageVolDefPtr def);
void virStorageVolSnapDefFree(virStorageVolSnapDefPtr def);
void virStoragePoolSourceClear(virStoragePoolSourcePtr source);
void virStoragePoolSourceDeviceClear(virStoragePoolSourceDevicePtr dev);
void virStoragePoolSourceFree(virStoragePoolSourcePtr source);
Expand Down
16 changes: 16 additions & 0 deletions src/datatypes.h
Expand Up @@ -494,6 +494,22 @@ struct _virStorageVol {
virFreeCallback privateDataFreeFunc;
};

/**
* _virStorageVolSnap:
*
* Internal structure associated to a storage volume snapshot
*/
struct _virStorageVolSnap {
virObject object;
virConnectPtr conn;
char *vol; /* Name of the parent volume */
char *name; /* Name of the snapshot */
char *key; /* unique key of the snapshot */

void *privateData;
virFreeCallback privateDataFreeFunc;
};

/**
* _virNodeDevice:
*
Expand Down
28 changes: 28 additions & 0 deletions src/driver-storage.h
Expand Up @@ -154,6 +154,29 @@ typedef int
unsigned int algorithm,
unsigned int flags);

typedef virStorageVolSnapPtr
(*virDrvStorageVolSnapCreate)(virStorageVolPtr vol,
const char *xmldesc,
unsigned int flags);

typedef int
(*virDrvStorageVolSnapDelete)(virStorageVolSnapPtr snap,
unsigned int flags);

typedef int
(*virDrvStorageVolSnapRevert)(virStorageVolSnapPtr snap,
unsigned int flags);

typedef int
(*virDrvStorageVolSnapList)(virStorageVolPtr vol,
virStorageVolSnapPtr **snaps,
unsigned int flags);

typedef int
(*virDrvStorageVolSnapGetInfo)(virStorageVolSnapPtr snap,
virStorageVolSnapInfoPtr info,
unsigned int flags);

typedef int
(*virDrvStorageVolGetInfo)(virStorageVolPtr vol,
virStorageVolInfoPtr info);
Expand Down Expand Up @@ -243,6 +266,11 @@ struct _virStorageDriver {
virDrvStorageVolDelete storageVolDelete;
virDrvStorageVolWipe storageVolWipe;
virDrvStorageVolWipePattern storageVolWipePattern;
virDrvStorageVolSnapCreate storageVolSnapCreate;
virDrvStorageVolSnapDelete storageVolSnapDelete;
virDrvStorageVolSnapRevert storageVolSnapRevert;
virDrvStorageVolSnapList storageVolSnapList;
virDrvStorageVolSnapGetInfo storageVolSnapGetInfo;
virDrvStorageVolGetInfo storageVolGetInfo;
virDrvStorageVolGetXMLDesc storageVolGetXMLDesc;
virDrvStorageVolGetPath storageVolGetPath;
Expand Down

0 comments on commit 4483ab2

Please sign in to comment.