
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