[libvirt] Refactoring of storage pool

Olga Krishtal okrishtal at virtuozzo.com
Wed Jan 25 17:02:30 UTC 2017


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




More information about the libvir-list mailing list