Hi everyone!
Half a year ago we started discussion about filesystem pools:
https://www.redhat.com/archives/libvir-list/2016-April/msg01941.html
https://www.redhat.com/archives/libvir-list/2016-May/msg00208.html
https://www.redhat.com/archives/libvir-list/2016-September/msg00463.html
At the end we have decided not to use copy/paste and try to merge code:
https://www.redhat.com/archives/libvir-list/2016-December/msg00051.html
However, after first try it had became obvious (the discussion is in the link above)
that pools can be describe as a separate object, that later will be used in storage pool,
filesystem pool, vgpu pool, etc. This latter is an extension of previous discussion;
I just want to separate refactoring of storage pools and the implementation of
filesystem pools a bit.
Before sending any patch with such huge refactoring I want to agree about pools
Here is an example of pool structures and prototypes of some management functions
that were discussed before (thanks a lot to John Ferlan for good advice).
I tried to tie everything together and here it is:
/*
* virpool.h: pool utility to manage structures commonly used for pools.
*
*/
/* The dscription of pool element
* For storage pool it used to be virStorageVolDef
* instead of key we use uuid, because key is specific
* for storage pools, and for other pool types (filesystem pools)
* or gpu pool we do nor have key.
* type field is also specific - that is why we put it into
* void* ElementTypeDef.
* ElementTypeDef - stores internal information about pool element(volume, item, etc)
* (the same as privateData for virConnectPtr)
* For example, for storage pool voluems it consists from:
* int type;
* virStorageVolSource source;
* virStorageSource target;
*/
#include "virhash.h"
typedef enum {
VIR_POOL_ELEMENT_VOLUME,
VIR_POOL_ELEMENT_FILESYSTEM,
VIR_POOL_ELEMENT_LAST,
} virPoolElemenType;
VIR_ENUM_DECL(virPoolElementType)
typedef void (*virPoolElementTypeDefFree) (void *PoolElementDef);
typedef struct _virPoolElementDef virPoolElementDef;
typedef virPoolElementDef *virPoolElementDefPtr;
struct _virPoolElementDef {
char *name;
char *uuid;
bool building;
unsigned int in_use;
int type;
void* ElementTypeDef;
virPoolElementTypeDefFree PoolElementDefFree;
};
typedef struct _virPoolElementDefList virPoolElementDefList;
typedef virPoolElementDefList *virPoolElementDefListPtr;
struct _virPoolElementDefList {
size_t count;
virPoolElementDefPtr *elements;
};
/* General information about pool source*/
typedef struct _virPoolSourceHost virPoolSourceHost;
typedef virPoolSourceHost *virPoolSourceHostPtr;
struct _virPoolSourceHost {
char *name;
int port;
};
typedef struct _virPoolAuthDef virPoolAuthDef;
typedef virPoolAuthDef *virPoolAuthDefPtr;
struct _virPoolAuthDef {
char *username;
char *secrettype; /* <secret type='%s' for disk source */
int authType; /* virStorageAuthType */
virSecretLookupTypeDef seclookupdef;
};
typedef enum {
VIR_POOL_SOURCE_DIR,
VIR_POOL_SOURCE_DEVICE,
VIR_POOL_SOURCE_NAME,
VIR_POOL_SOURCE_LAST,
} virPoolSourcePathType;
VIR_ENUM_DECL(virPoolSourcePathType)
typedef struct _virPoolSourcePath virPoolSourcePath;
typedef virPoolSourcePath *virPoolSourcePathPtr;
struct _virPoolSourcePath {
virPoolSourcePathType sourcetype;
char *path;
};
typedef void(*virPoolPrivDataFree) (void *privePoolData);
typedef struct _virPoolSource virPoolSource;
typedef virPoolSource *virPoolSourcePtr;
struct _virPoolSource{
/* One or more host definitions */
size_t nhost;
virPoolSourceHostPtr hosts;
/* Authentication information */
virPoolAuthDefPtr auth;
/* One or more devices */
size_t nsrcpath;
virPoolSourcePathPtr srcpaths;
/* Name of the source */
char *name;
/* Vendor of the source */
char *vendor;
/* Product name of the source */
char *product;
/*Some private data */
void *privatePoolData;
virPoolPrivDataFree privDataFree;
};
typedef struct _virPoolPathPerms virPoolPathPerms;
typedef virPoolPathPerms *virPoolPathPermsPtr;
struct _virPoolPathPerms {
mode_t mode;
uid_t uid;
gid_t gid;
char *label;
}
typedef struct _virPoolTarget virPoolTarget;
typedef virPoolTarget *virPoolTargetPtr;
struct _virPoolTarget{
char *path; /* Optional path to target */
virPoolPathPerms perms; /* Default permissions for path */
};
typedef struct _virPoolDef virPoolDef;
typedef virPoolDef *virPoolDefPtr;
struct _virPoolDef {
char *name;
unsigned char uuid[VIR_UUID_BUFLEN];
virPoolSource source;
virPoolTarget target;
};
typedef struct _virPoolInfo virPoolInfo; // used to be virPoolObj
typedef virPoolInfo *virPoolInfoPtr;
struct _virPoolInfo {
char *configFile;
char *autostartLink;
bool active;
int autostart;
unsigned int asyncjobs;
virPoolDefPtr def;
virPoolDefPtr newDef;
virPoolElementDefList elementsdef;
};
/* Used to be PoolObjList
* Separate struct - in case we will need additional info
* upon the hash table.
*/
typedef struct _virPoolStore virPoolStore;
typedef virPoolStore *virPoolStorePtr;
struct _virPoolStore {
size_t count;
virHashAtomicPtr *pools; //Used to be objects obj
};
/*
* Pool hash and pool elements managment operations
*/
void virPoolElementDefFree (virPoolElementDefPtr def);
void virPoolClearElements(virPoolInfoPtr poolinfo);
void virPoolAuthDefFree(virPoolAuthDefPtr authdef);
virPoolSourcePtr
virPoolSourceNew (virPoolPrivDataFree privDataFree);
void virPoolSourceClear(virPoolSourcePtr source);
void virPoolDefFree(virPoolDefPtr def);
void virPoolInfoFree(virPoolInfoPtr pool);
virPoolStorePtr virPoolStoreNew();
*
* Functions to manage pool as an object.
* */
// It is reference implementation.
#include "virpool.h"
VIR_ENUM_IMPL(virPoolElementType,
VIR_POOL_ELEMNT_LAST,
"volume", "filesystem");
void
virPoolElementDefFree(virPoolElementDefPtr def)
{
if (!def)
return;
VIR_FREE(def->name);
VIR_FREE(def->uuid);
if (def->PoolElementDefFree)
def->PoolElementDefFree(def->ElementTypeDef);
}
void
virPoolClearElements(virPoolInfoPtr poolinfo)
{
size_t i;
for (i = 0; i < poolinfo->elementsdef.count; i++)
virPoolElementDefFree(poolinfo->elementsdef.elements[i]);
VIR_FREE(poolinfo->elementdef.elements);
poolindo->elementsdef.count = 0;
}
/* General functions to work with pool */
VIR_ENUM_IMPL(virPoolSourcePathType,
VIR_POOL_SOURCE_LAST,
"dir", "device", "name");
void
virPoolAuthDefFree(virPoolAuthDefPtr authdef)
{
if (!authdef)
return;
VIR_FREE(authdef->username);
VIR_FREE(authdef->secrettype);
VIR_FREE(authdef);
}
virPoolSourcePtr
virPoolSourceNew(virPoolPrivDataFree privDataFree)
{
virPoolSourcePtr source;
if (VIR_ALLOC(source) < 0)
return -1;
source->privDataFree = privDataFree;
return source;
}
void
virPoolSourceClear(virPoolSourcePtr source)
{
size_t i;
if (!source)
return;
/* Free hosts */
for (i = 0; i < source->nhosts; i++)
VIR_FREE(source->hosts[i].name);
VIR_FREE(source->hosts);
/* Free auth information
* empty at the moment*/
virPoolAuthDefFree(source->auth);
/* Free dev path*/
for (i = 0; i < source->nsrcpath; i++)
VIR_FREE(source->srcpath[i].name);
VIR_FREE(source->srcpath);
VIR_FREE(source->name);
VIR_FREE(source->vendor);
VIR_FREE(source->product);
if (source->privDataFree)
source->privDataFree(source->privatePoolData);
}
void
virPoolDefFree(virPoolDefPtr def)
{
if (!def)
return;
VIR_FREE(def->name);
/*Free other fields*/
virPoolSourceClear(def->source);
VIR_FREE(def->target.path);
VIR_FREE(def->target.perms.lable);
VIR_FREE(def);
}
void
virPoolInfoFree(virPoolInfoPtr pool)
{
if (!pool)
return;
VIR_FREE(pool->configFile);
VIR_FREE(pool->autostartLink);
virPoolDefFree(pool->def);
virPoolDefFree(pool->newDef);
virPoolClearElements(pool);
}
virPoolStorePtr
virPoolStoreNew()
{
virPoolStorePtr poolstore;
if (VIR_ALLOC(poolstore) < 0)
return NULL;
poolstore->count = 0;
poolstore->pools = virHashAtomicNew(0, virPoolInfoFree);
return poolstore;
}
I will be glad to here any ideas and advises.
--
Best regards,
Olga
--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list