You've already forked pgbackrest
							
							
				mirror of
				https://github.com/pgbackrest/pgbackrest.git
				synced 2025-10-30 23:37:45 +02:00 
			
		
		
		
	Add LSTDEF() macro.
This macro allows static List objects to be created which simplifies usage when passing lists to functions. Also, since List objects are commonly used this makes the code base a bit more consistent. For now skip static lists that are only used locally within a function since the benefit is not as clear.
This commit is contained in:
		| @@ -319,12 +319,9 @@ static const ManifestBlockIncrChecksumSizeMap manifestBlockIncrChecksumSizeMapDe | ||||
| // All maps | ||||
| static const ManifestBlockIncrMap manifestBlockIncrMap = | ||||
| { | ||||
|     .sizeMap = manifestBlockIncrSizeMapDefault, | ||||
|     .sizeMapSize = LENGTH_OF(manifestBlockIncrSizeMapDefault), | ||||
|     .ageMap = manifestBlockIncrAgeMapDefault, | ||||
|     .ageMapSize = LENGTH_OF(manifestBlockIncrAgeMapDefault), | ||||
|     .checksumSizeMap = manifestBlockIncrChecksumSizeMapDefault, | ||||
|     .checksumSizeMapSize = LENGTH_OF(manifestBlockIncrChecksumSizeMapDefault), | ||||
|     .sizeMap = LSTDEF(manifestBlockIncrSizeMapDefault), | ||||
|     .ageMap = LSTDEF(manifestBlockIncrAgeMapDefault), | ||||
|     .checksumSizeMap = LSTDEF(manifestBlockIncrChecksumSizeMapDefault), | ||||
| }; | ||||
|  | ||||
| // Convert map size | ||||
| @@ -428,8 +425,7 @@ backupBlockIncrMap(void) | ||||
|  | ||||
|             lstSort(map, sortOrderDesc); | ||||
|  | ||||
|             result.sizeMap = lstGet(map, 0); | ||||
|             result.sizeMapSize = lstSize(map); | ||||
|             result.sizeMap = map; | ||||
|         } | ||||
|  | ||||
|         // Build age map | ||||
| @@ -455,8 +451,7 @@ backupBlockIncrMap(void) | ||||
|  | ||||
|             lstSort(map, sortOrderDesc); | ||||
|  | ||||
|             result.ageMap = lstGet(map, 0); | ||||
|             result.ageMapSize = lstSize(map); | ||||
|             result.ageMap = map; | ||||
|         } | ||||
|  | ||||
|         // Build checksum size map | ||||
| @@ -485,8 +480,7 @@ backupBlockIncrMap(void) | ||||
|  | ||||
|             lstSort(map, sortOrderDesc); | ||||
|  | ||||
|             result.checksumSizeMap = lstGet(map, 0); | ||||
|             result.checksumSizeMapSize = lstSize(map); | ||||
|             result.checksumSizeMap = map; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -19,7 +19,7 @@ Local Command | ||||
| /*********************************************************************************************************************************** | ||||
| Command handlers | ||||
| ***********************************************************************************************************************************/ | ||||
| static const ProtocolServerHandler commandLocalHandlerList[] = | ||||
| static const ProtocolServerHandler commandLocalHandler[] = | ||||
| { | ||||
|     PROTOCOL_SERVER_HANDLER_ARCHIVE_GET_LIST | ||||
|     PROTOCOL_SERVER_HANDLER_ARCHIVE_PUSH_LIST | ||||
| @@ -28,6 +28,8 @@ static const ProtocolServerHandler commandLocalHandlerList[] = | ||||
|     PROTOCOL_SERVER_HANDLER_VERIFY_LIST | ||||
| }; | ||||
|  | ||||
| static const List *const commandLocalHandlerList = LSTDEF(commandLocalHandler); | ||||
|  | ||||
| /**********************************************************************************************************************************/ | ||||
| FN_EXTERN void | ||||
| cmdLocal(ProtocolServer *const server) | ||||
| @@ -36,7 +38,7 @@ cmdLocal(ProtocolServer *const server) | ||||
|  | ||||
|     MEM_CONTEXT_TEMP_BEGIN() | ||||
|     { | ||||
|         protocolServerProcess(server, cfgCommandJobRetry(), commandLocalHandlerList, LENGTH_OF(commandLocalHandlerList)); | ||||
|         protocolServerProcess(server, cfgCommandJobRetry(), commandLocalHandlerList); | ||||
|     } | ||||
|     MEM_CONTEXT_TEMP_END(); | ||||
|  | ||||
|   | ||||
| @@ -27,17 +27,19 @@ Remote Command | ||||
| /*********************************************************************************************************************************** | ||||
| Command handlers | ||||
| ***********************************************************************************************************************************/ | ||||
| static const ProtocolServerHandler commandRemoteHandlerList[] = | ||||
| static const ProtocolServerHandler commandRemoteHandler[] = | ||||
| { | ||||
|     PROTOCOL_SERVER_HANDLER_DB_LIST | ||||
|     PROTOCOL_SERVER_HANDLER_OPTION_LIST | ||||
|     PROTOCOL_SERVER_HANDLER_STORAGE_REMOTE_LIST | ||||
| }; | ||||
|  | ||||
| static const List *const commandRemoteHandlerList = LSTDEF(commandRemoteHandler); | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Filter handlers | ||||
| ***********************************************************************************************************************************/ | ||||
| static const StorageRemoteFilterHandler storageRemoteFilterHandlerList[] = | ||||
| static const StorageRemoteFilterHandler storageRemoteFilterHandler[] = | ||||
| { | ||||
|     {.type = BLOCK_CHECKSUM_FILTER_TYPE, .handlerParam = blockChecksumNewPack}, | ||||
|     {.type = BLOCK_INCR_FILTER_TYPE, .handlerParam = blockIncrNewPack}, | ||||
| @@ -48,6 +50,8 @@ static const StorageRemoteFilterHandler storageRemoteFilterHandlerList[] = | ||||
|     {.type = SIZE_FILTER_TYPE, .handlerNoParam = ioSizeNew}, | ||||
| }; | ||||
|  | ||||
| static const List *const storageRemoteFilterHandlerList = LSTDEF(storageRemoteFilterHandler); | ||||
|  | ||||
| /**********************************************************************************************************************************/ | ||||
| FN_EXTERN void | ||||
| cmdRemote(ProtocolServer *const server) | ||||
| @@ -55,7 +59,7 @@ cmdRemote(ProtocolServer *const server) | ||||
|     FUNCTION_LOG_VOID(logLevelDebug); | ||||
|  | ||||
|     // Set filter handlers | ||||
|     storageRemoteFilterHandlerSet(storageRemoteFilterHandlerList, LENGTH_OF(storageRemoteFilterHandlerList)); | ||||
|     storageRemoteFilterHandlerSet(storageRemoteFilterHandlerList); | ||||
|  | ||||
|     MEM_CONTEXT_TEMP_BEGIN() | ||||
|     { | ||||
| @@ -95,7 +99,7 @@ cmdRemote(ProtocolServer *const server) | ||||
|  | ||||
|         // If not successful we'll just exit | ||||
|         if (success) | ||||
|             protocolServerProcess(server, NULL, commandRemoteHandlerList, LENGTH_OF(commandRemoteHandlerList)); | ||||
|             protocolServerProcess(server, NULL, commandRemoteHandlerList); | ||||
|     } | ||||
|     MEM_CONTEXT_TEMP_END(); | ||||
|  | ||||
|   | ||||
| @@ -16,11 +16,9 @@ Object type | ||||
| struct List | ||||
| { | ||||
|     ListPub pub;                                                    // Publicly accessible variables | ||||
|     size_t itemSize; | ||||
|     unsigned int listSizeMax; | ||||
|     SortOrder sortOrder; | ||||
|     unsigned char *listAlloc;                                       // Pointer to memory allocated for the list | ||||
|     unsigned char *list;                                            // Pointer to the current start of the list | ||||
|     ListComparator *comparator; | ||||
| }; | ||||
|  | ||||
| @@ -37,7 +35,10 @@ lstNew(const size_t itemSize, const ListParam param) | ||||
|     { | ||||
|         *this = (List) | ||||
|         { | ||||
|             .itemSize = itemSize, | ||||
|             .pub = | ||||
|             { | ||||
|                 .itemSize = itemSize, | ||||
|             }, | ||||
|             .sortOrder = param.sortOrder, | ||||
|             .comparator = param.comparator, | ||||
|         }; | ||||
| @@ -57,11 +58,11 @@ lstClear(List *const this) | ||||
|  | ||||
|     ASSERT(this != NULL); | ||||
|  | ||||
|     if (this->list != NULL) | ||||
|     if (this->pub.list != NULL) | ||||
|     { | ||||
|         MEM_CONTEXT_BEGIN(lstMemContext(this)) | ||||
|         { | ||||
|             memFree(this->list); | ||||
|             memFree(this->pub.list); | ||||
|         } | ||||
|         MEM_CONTEXT_END(); | ||||
|  | ||||
| @@ -165,7 +166,7 @@ lstGet(const List *const this, const unsigned int listIdx) | ||||
|         THROW_FMT(AssertError, "cannot get index %u from list with %u value(s)", listIdx, lstSize(this)); | ||||
|  | ||||
|     // Return pointer to list item | ||||
|     FUNCTION_TEST_RETURN_P(VOID, this->list + (listIdx * this->itemSize)); | ||||
|     FUNCTION_TEST_RETURN_P(VOID, this->pub.list + (listIdx * this->pub.itemSize)); | ||||
| } | ||||
|  | ||||
| FN_EXTERN void * | ||||
| @@ -198,16 +199,16 @@ lstFind(const List *const this, const void *const item) | ||||
|     ASSERT(this->comparator != NULL); | ||||
|     ASSERT(item != NULL); | ||||
|  | ||||
|     if (this->list != NULL) | ||||
|     if (this->pub.list != NULL) | ||||
|     { | ||||
|         if (this->sortOrder == sortOrderAsc) | ||||
|             FUNCTION_TEST_RETURN_P(VOID, bsearch(item, this->list, lstSize(this), this->itemSize, this->comparator)); | ||||
|             FUNCTION_TEST_RETURN_P(VOID, bsearch(item, this->pub.list, lstSize(this), this->pub.itemSize, this->comparator)); | ||||
|         else if (this->sortOrder == sortOrderDesc) | ||||
|         { | ||||
|             // Assign the list for the descending comparator to use | ||||
|             comparatorDescList = this; | ||||
|  | ||||
|             FUNCTION_TEST_RETURN_P(VOID, bsearch(item, this->list, lstSize(this), this->itemSize, lstComparatorDesc)); | ||||
|             FUNCTION_TEST_RETURN_P(VOID, bsearch(item, this->pub.list, lstSize(this), this->pub.itemSize, lstComparatorDesc)); | ||||
|         } | ||||
|  | ||||
|         // Fall back on an iterative search | ||||
| @@ -267,9 +268,9 @@ lstIdx(const List *const this, const void *const item) | ||||
|     ASSERT(item != NULL); | ||||
|  | ||||
|     // Item pointers should always be aligned with the beginning of an item in the list | ||||
|     ASSERT((size_t)((const unsigned char *const)item - this->list) % this->itemSize == 0); | ||||
|     ASSERT((size_t)((const unsigned char *const)item - this->pub.list) % this->pub.itemSize == 0); | ||||
|  | ||||
|     const size_t result = (size_t)((const unsigned char *const)item - this->list) / this->itemSize; | ||||
|     const size_t result = (size_t)((const unsigned char *const)item - this->pub.list) / this->pub.itemSize; | ||||
|  | ||||
|     // Item pointers should always be in range | ||||
|     ASSERT(result < lstSize(this)); | ||||
| @@ -299,38 +300,38 @@ lstInsert(List *const this, const unsigned int listIdx, const void *const item) | ||||
|             if (this->listSizeMax == 0) | ||||
|             { | ||||
|                 this->listSizeMax = LIST_INITIAL_SIZE; | ||||
|                 this->list = memNew(this->listSizeMax * this->itemSize); | ||||
|                 this->pub.list = memNew(this->listSizeMax * this->pub.itemSize); | ||||
|             } | ||||
|             // Else the list needs to be extended | ||||
|             else | ||||
|             { | ||||
|                 this->listSizeMax *= 2; | ||||
|                 this->list = memResize(this->list, this->listSizeMax * this->itemSize); | ||||
|                 this->pub.list = memResize(this->pub.list, this->listSizeMax * this->pub.itemSize); | ||||
|             } | ||||
|  | ||||
|             this->listAlloc = this->list; | ||||
|             this->listAlloc = this->pub.list; | ||||
|         } | ||||
|         MEM_CONTEXT_END(); | ||||
|     } | ||||
|     // Else if there is space before the beginning of the list then move the list down | ||||
|     else if ( | ||||
|         (this->list != this->listAlloc) && | ||||
|         (lstSize(this) + ((uintptr_t)(this->list - this->listAlloc) / this->itemSize) == this->listSizeMax)) | ||||
|         (this->pub.list != this->listAlloc) && | ||||
|         (lstSize(this) + ((uintptr_t)(this->pub.list - this->listAlloc) / this->pub.itemSize) == this->listSizeMax)) | ||||
|     { | ||||
|         memmove(this->listAlloc, this->list, lstSize(this) * this->itemSize); | ||||
|         this->list = this->listAlloc; | ||||
|         memmove(this->listAlloc, this->pub.list, lstSize(this) * this->pub.itemSize); | ||||
|         this->pub.list = this->listAlloc; | ||||
|     } | ||||
|  | ||||
|     // Calculate the position where this item will be copied | ||||
|     void *const itemPtr = this->list + (listIdx * this->itemSize); | ||||
|     void *const itemPtr = this->pub.list + (listIdx * this->pub.itemSize); | ||||
|  | ||||
|     // If not inserting at the end then move items down to make space | ||||
|     if (listIdx != lstSize(this)) | ||||
|         memmove(this->list + ((listIdx + 1) * this->itemSize), itemPtr, (lstSize(this) - listIdx) * this->itemSize); | ||||
|         memmove(this->pub.list + ((listIdx + 1) * this->pub.itemSize), itemPtr, (lstSize(this) - listIdx) * this->pub.itemSize); | ||||
|  | ||||
|     // Copy item into the list | ||||
|     this->sortOrder = sortOrderNone; | ||||
|     memcpy(itemPtr, item, this->itemSize); | ||||
|     memcpy(itemPtr, item, this->pub.itemSize); | ||||
|     this->pub.listSize++; | ||||
|  | ||||
|     FUNCTION_TEST_RETURN_P(VOID, itemPtr); | ||||
| @@ -354,14 +355,14 @@ lstRemoveIdx(List *const this, const unsigned int listIdx) | ||||
|     // If this is the first item then move the list pointer up to avoid moving all the items | ||||
|     if (listIdx == 0) | ||||
|     { | ||||
|         this->list += this->itemSize; | ||||
|         this->pub.list += this->pub.itemSize; | ||||
|     } | ||||
|     // Else remove the item by moving the items after it down | ||||
|     else | ||||
|     { | ||||
|         memmove( | ||||
|             this->list + (listIdx * this->itemSize), this->list + ((listIdx + 1) * this->itemSize), | ||||
|             (lstSize(this) - listIdx) * this->itemSize); | ||||
|             this->pub.list + (listIdx * this->pub.itemSize), this->pub.list + ((listIdx + 1) * this->pub.itemSize), | ||||
|             (lstSize(this) - listIdx) * this->pub.itemSize); | ||||
|     } | ||||
|  | ||||
|     FUNCTION_TEST_RETURN(LIST, this); | ||||
| @@ -416,12 +417,12 @@ lstSort(List *const this, const SortOrder sortOrder) | ||||
|     ASSERT(this != NULL); | ||||
|     ASSERT(this->comparator != NULL); | ||||
|  | ||||
|     if (this->list != NULL) | ||||
|     if (this->pub.list != NULL) | ||||
|     { | ||||
|         switch (sortOrder) | ||||
|         { | ||||
|             case sortOrderAsc: | ||||
|                 qsort(this->list, lstSize(this), this->itemSize, this->comparator); | ||||
|                 qsort(this->pub.list, lstSize(this), this->pub.itemSize, this->comparator); | ||||
|                 break; | ||||
|  | ||||
|             case sortOrderDesc: | ||||
| @@ -429,7 +430,7 @@ lstSort(List *const this, const SortOrder sortOrder) | ||||
|                 // Assign the list that will be sorted for the comparator function to use | ||||
|                 comparatorDescList = this; | ||||
|  | ||||
|                 qsort(this->list, lstSize(this), this->itemSize, lstComparatorDesc); | ||||
|                 qsort(this->pub.list, lstSize(this), this->pub.itemSize, lstComparatorDesc); | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|   | ||||
| @@ -80,6 +80,8 @@ Getters/Setters | ||||
| typedef struct ListPub | ||||
| { | ||||
|     unsigned int listSize;                                          // List size | ||||
|     size_t itemSize;                                                // Size of item stored in the list | ||||
|     unsigned char *list;                                            // Pointer to the current start of the list | ||||
| } ListPub; | ||||
|  | ||||
| // Set a new comparator | ||||
| @@ -165,6 +167,29 @@ lstFree(List *const this) | ||||
|     objFree(this); | ||||
| } | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Macros for constant lists | ||||
|  | ||||
| Frequently used constant lists can be declared with these macros at compile time rather than dynamically at run time. | ||||
|  | ||||
| Note that lists created in this way are declared as const so can't be modified or freed by the lst*() methods. Casting to List * | ||||
| will result in a segfault due to modifying read-only memory. | ||||
|  | ||||
| By convention all List constant identifiers are appended with _LST. | ||||
| ***********************************************************************************************************************************/ | ||||
| // This struct must be kept in sync with ListPub (except for const qualifiers) | ||||
| typedef struct ListPubConst | ||||
| { | ||||
|     unsigned int listSize;                                          // List size | ||||
|     size_t itemSize;                                                // Size of item stored in the list | ||||
|     const unsigned char *list;                                      // Pointer to the current start of the list | ||||
| } ListPubConst; | ||||
|  | ||||
| // Create a List constant inline from a constant array | ||||
| #define LSTDEF(listParam)                                                                                                          \ | ||||
|     (const List *)&(ListPubConst){                                                                                                 \ | ||||
|         .list = (const unsigned char *)listParam, .itemSize = sizeof((listParam)[0]), .listSize = LENGTH_OF(listParam)} | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Macros for function logging | ||||
| ***********************************************************************************************************************************/ | ||||
|   | ||||
| @@ -804,11 +804,13 @@ manifestBuildBlockIncrSize(const ManifestBuildData *const buildData, const Manif | ||||
|     size_t result = 0; | ||||
|  | ||||
|     // Search size map for the appropriate block size | ||||
|     for (unsigned int sizeIdx = 0; sizeIdx < buildData->blockIncrMap->sizeMapSize; sizeIdx++) | ||||
|     for (unsigned int sizeIdx = 0; sizeIdx < lstSize(buildData->blockIncrMap->sizeMap); sizeIdx++) | ||||
|     { | ||||
|         if (file->size >= buildData->blockIncrMap->sizeMap[sizeIdx].fileSize) | ||||
|         const ManifestBlockIncrSizeMap *const sizeMap = lstGet(buildData->blockIncrMap->sizeMap, sizeIdx); | ||||
|  | ||||
|         if (file->size >= sizeMap->fileSize) | ||||
|         { | ||||
|             result = buildData->blockIncrMap->sizeMap[sizeIdx].blockSize; | ||||
|             result = sizeMap->blockSize; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| @@ -818,11 +820,13 @@ manifestBuildBlockIncrSize(const ManifestBuildData *const buildData, const Manif | ||||
|     { | ||||
|         const time_t fileAge = buildData->manifest->pub.data.backupTimestampStart - file->timestamp; | ||||
|  | ||||
|         for (unsigned int timeIdx = 0; timeIdx < buildData->blockIncrMap->ageMapSize; timeIdx++) | ||||
|         for (unsigned int ageIdx = 0; ageIdx < lstSize(buildData->blockIncrMap->ageMap); ageIdx++) | ||||
|         { | ||||
|             if (fileAge >= (time_t)buildData->blockIncrMap->ageMap[timeIdx].fileAge) | ||||
|             const ManifestBlockIncrAgeMap *const ageMap = lstGet(buildData->blockIncrMap->ageMap, ageIdx); | ||||
|  | ||||
|             if (fileAge >= (time_t)ageMap->fileAge) | ||||
|             { | ||||
|                 result *= buildData->blockIncrMap->ageMap[timeIdx].blockMultiplier; | ||||
|                 result *= ageMap->blockMultiplier; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
| @@ -846,11 +850,13 @@ manifestBuildBlockIncrChecksumSize(const ManifestBuildData *const buildData, con | ||||
|     size_t result = BLOCK_INCR_CHECKSUM_SIZE_MIN; | ||||
|  | ||||
|     // Search checksum size map for larger value | ||||
|     for (unsigned int sizeIdx = 0; sizeIdx < buildData->blockIncrMap->checksumSizeMapSize; sizeIdx++) | ||||
|     for (unsigned int sizeIdx = 0; sizeIdx < lstSize(buildData->blockIncrMap->checksumSizeMap); sizeIdx++) | ||||
|     { | ||||
|         if (blockSize >= buildData->blockIncrMap->checksumSizeMap[sizeIdx].blockSize) | ||||
|         const ManifestBlockIncrChecksumSizeMap *const sizeMap = lstGet(buildData->blockIncrMap->checksumSizeMap, sizeIdx); | ||||
|  | ||||
|         if (blockSize >= sizeMap->blockSize) | ||||
|         { | ||||
|             result = buildData->blockIncrMap->checksumSizeMap[sizeIdx].checksumSize; | ||||
|             result = sizeMap->checksumSize; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -116,12 +116,9 @@ typedef struct ManifestBlockIncrChecksumSizeMap | ||||
|  | ||||
| typedef struct ManifestBlockIncrMap | ||||
| { | ||||
|     const ManifestBlockIncrSizeMap *sizeMap;                        // Block size map | ||||
|     unsigned int sizeMapSize;                                       // Block size map size | ||||
|     const ManifestBlockIncrAgeMap *ageMap;                          // File age map | ||||
|     unsigned int ageMapSize;                                        // File age map size | ||||
|     const ManifestBlockIncrChecksumSizeMap *checksumSizeMap;        // Checksum size map | ||||
|     unsigned int checksumSizeMapSize;                               // Checksum size map size | ||||
|     const List *sizeMap;                                            // Block size map | ||||
|     const List *ageMap;                                             // File age map | ||||
|     const List *checksumSizeMap;                                    // Checksum size map | ||||
| } ManifestBlockIncrMap; | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
|   | ||||
| @@ -192,20 +192,17 @@ protocolServerRequest(ProtocolServer *const this) | ||||
|  | ||||
| /**********************************************************************************************************************************/ | ||||
| FN_EXTERN void | ||||
| protocolServerProcess( | ||||
|     ProtocolServer *const this, const VariantList *const retryInterval, const ProtocolServerHandler *const handlerList, | ||||
|     const unsigned int handlerListSize) | ||||
| protocolServerProcess(ProtocolServer *const this, const VariantList *const retryInterval, const List *const handlerList) | ||||
| { | ||||
|     FUNCTION_LOG_BEGIN(logLevelDebug); | ||||
|         FUNCTION_LOG_PARAM(PROTOCOL_SERVER, this); | ||||
|         FUNCTION_LOG_PARAM(VARIANT_LIST, retryInterval); | ||||
|         FUNCTION_LOG_PARAM_P(VOID, handlerList); | ||||
|         FUNCTION_LOG_PARAM(UINT, handlerListSize); | ||||
|         FUNCTION_LOG_PARAM(LIST, handlerList); | ||||
|     FUNCTION_LOG_END(); | ||||
|  | ||||
|     ASSERT(this != NULL); | ||||
|     ASSERT(handlerList != NULL); | ||||
|     ASSERT(handlerListSize > 0); | ||||
|     ASSERT(!lstEmpty(handlerList)); | ||||
|  | ||||
|     // Loop until exit request is received | ||||
|     bool exit = false; | ||||
| @@ -222,11 +219,13 @@ protocolServerProcess( | ||||
|                 // Find the handler | ||||
|                 const ProtocolServerHandler *handler = NULL; | ||||
|  | ||||
|                 for (unsigned int handlerIdx = 0; handlerIdx < handlerListSize; handlerIdx++) | ||||
|                 for (unsigned int handlerIdx = 0; handlerIdx < lstSize(handlerList); handlerIdx++) | ||||
|                 { | ||||
|                     if (request.id == handlerList[handlerIdx].command) | ||||
|                     const ProtocolServerHandler *const handlerMatch = lstGet(handlerList, handlerIdx); | ||||
|  | ||||
|                     if (request.id == handlerMatch->command) | ||||
|                     { | ||||
|                         handler = &handlerList[handlerIdx]; | ||||
|                         handler = handlerMatch; | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|   | ||||
| @@ -75,9 +75,7 @@ FN_EXTERN void protocolServerResponse(ProtocolServer *const this, ProtocolServer | ||||
| FN_EXTERN void protocolServerError(ProtocolServer *this, int code, const String *message, const String *stack); | ||||
|  | ||||
| // Process requests | ||||
| FN_EXTERN void protocolServerProcess( | ||||
|     ProtocolServer *this, const VariantList *retryInterval, const ProtocolServerHandler *handlerList, | ||||
|     const unsigned int handlerListSize); | ||||
| FN_EXTERN void protocolServerProcess(ProtocolServer *this, const VariantList *retryInterval, const List *handlerList); | ||||
|  | ||||
| // Move to a new parent mem context | ||||
| FN_INLINE_ALWAYS ProtocolServer * | ||||
|   | ||||
| @@ -23,26 +23,23 @@ static struct | ||||
|     MemContext *memContext;                                         // Mem context | ||||
|     void *driver;                                                   // Storage driver used for requests | ||||
|  | ||||
|     const StorageRemoteFilterHandler *filterHandler;                // Filter handler list | ||||
|     unsigned int filterHandlerSize;                                 // Filter handler list size | ||||
|     const List *filterHandler;                                      // Filter handler list | ||||
| } storageRemoteProtocolLocal; | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Set filter handlers | ||||
| ***********************************************************************************************************************************/ | ||||
| FN_EXTERN void | ||||
| storageRemoteFilterHandlerSet(const StorageRemoteFilterHandler *const filterHandler, const unsigned int filterHandlerSize) | ||||
| storageRemoteFilterHandlerSet(const List *const filterHandler) | ||||
| { | ||||
|     FUNCTION_TEST_BEGIN(); | ||||
|         FUNCTION_TEST_PARAM_P(VOID, filterHandler); | ||||
|         FUNCTION_TEST_PARAM(UINT, filterHandlerSize); | ||||
|         FUNCTION_TEST_PARAM(VOID, filterHandler); | ||||
|     FUNCTION_TEST_END(); | ||||
|  | ||||
|     ASSERT(filterHandler != NULL); | ||||
|     ASSERT(filterHandlerSize > 0); | ||||
|     ASSERT(!lstEmpty(filterHandler)); | ||||
|  | ||||
|     storageRemoteProtocolLocal.filterHandler = filterHandler; | ||||
|     storageRemoteProtocolLocal.filterHandlerSize = filterHandlerSize; | ||||
|  | ||||
|     FUNCTION_TEST_RETURN_VOID(); | ||||
| } | ||||
| @@ -85,26 +82,28 @@ storageRemoteFilterGroup(IoFilterGroup *const filterGroup, const Pack *const fil | ||||
|                 // Search for a filter handler | ||||
|                 unsigned int filterIdx = 0; | ||||
|  | ||||
|                 for (; filterIdx < storageRemoteProtocolLocal.filterHandlerSize; filterIdx++) | ||||
|                 for (; filterIdx < lstSize(storageRemoteProtocolLocal.filterHandler); filterIdx++) | ||||
|                 { | ||||
|                     const StorageRemoteFilterHandler *const filterHandler = lstGet( | ||||
|                         storageRemoteProtocolLocal.filterHandler, filterIdx); | ||||
|  | ||||
|                     // If a match create the filter | ||||
|                     if (storageRemoteProtocolLocal.filterHandler[filterIdx].type == filterKey) | ||||
|                     if (filterHandler->type == filterKey) | ||||
|                     { | ||||
|                         // Create a filter with parameters | ||||
|                         if (storageRemoteProtocolLocal.filterHandler[filterIdx].handlerParam != NULL) | ||||
|                         if (filterHandler->handlerParam != NULL) | ||||
|                         { | ||||
|                             ASSERT(filterParam != NULL); | ||||
|  | ||||
|                             ioFilterGroupAdd( | ||||
|                                 filterGroup, storageRemoteProtocolLocal.filterHandler[filterIdx].handlerParam(filterParam)); | ||||
|                             ioFilterGroupAdd(filterGroup, filterHandler->handlerParam(filterParam)); | ||||
|                         } | ||||
|                         // Else create a filter without parameters | ||||
|                         else | ||||
|                         { | ||||
|                             ASSERT(storageRemoteProtocolLocal.filterHandler[filterIdx].handlerNoParam != NULL); | ||||
|                             ASSERT(filterHandler->handlerNoParam != NULL); | ||||
|                             ASSERT(filterParam == NULL); | ||||
|  | ||||
|                             ioFilterGroupAdd(filterGroup, storageRemoteProtocolLocal.filterHandler[filterIdx].handlerNoParam()); | ||||
|                             ioFilterGroupAdd(filterGroup, filterHandler->handlerNoParam()); | ||||
|                         } | ||||
|  | ||||
|                         // Break on filter match | ||||
| @@ -113,7 +112,7 @@ storageRemoteFilterGroup(IoFilterGroup *const filterGroup, const Pack *const fil | ||||
|                 } | ||||
|  | ||||
|                 // Error when the filter was not found | ||||
|                 if (filterIdx == storageRemoteProtocolLocal.filterHandlerSize) | ||||
|                 if (filterIdx == lstSize(storageRemoteProtocolLocal.filterHandler)) | ||||
|                     THROW_FMT(AssertError, "unable to add filter '%s'", strZ(strIdToStr(filterKey))); | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -65,6 +65,6 @@ typedef struct StorageRemoteFilterHandler | ||||
|     StorageRemoteFilterHandlerNoParam handlerNoParam;               // Handler with no parameters | ||||
| } StorageRemoteFilterHandler; | ||||
|  | ||||
| FN_EXTERN void storageRemoteFilterHandlerSet(const StorageRemoteFilterHandler *filterHandler, unsigned int filterHandlerSize); | ||||
| FN_EXTERN void storageRemoteFilterHandlerSet(const List *filterHandler); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -27,13 +27,11 @@ static struct | ||||
| { | ||||
|     // Local process shim | ||||
|     bool localShim; | ||||
|     const ProtocolServerHandler *localHandlerList; | ||||
|     unsigned int localHandlerListSize; | ||||
|     const List *localHandlerList; | ||||
|  | ||||
|     // Remote process shim | ||||
|     bool remoteShim; | ||||
|     const ProtocolServerHandler *remoteHandlerList; | ||||
|     unsigned int remoteHandlerListSize; | ||||
|     const List *remoteHandlerList; | ||||
| } hrnProtocolStatic; | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| @@ -112,8 +110,7 @@ protocolLocalExec( | ||||
|             ProtocolServer *server = protocolServerNew( | ||||
|                 name, PROTOCOL_SERVICE_LOCAL_STR, ioFdReadNewOpen(name, pipeWrite[0], 5000), | ||||
|                 ioFdWriteNewOpen(name, pipeRead[1], 5000)); | ||||
|             protocolServerProcess( | ||||
|                 server, cfgCommandJobRetry(), hrnProtocolStatic.localHandlerList, hrnProtocolStatic.localHandlerListSize); | ||||
|             protocolServerProcess(server, cfgCommandJobRetry(), hrnProtocolStatic.localHandlerList); | ||||
|  | ||||
|             // Exit when done | ||||
|             exit(0); | ||||
| @@ -141,16 +138,14 @@ protocolLocalExec( | ||||
|  | ||||
| /**********************************************************************************************************************************/ | ||||
| void | ||||
| hrnProtocolLocalShimInstall(const ProtocolServerHandler *const handlerList, const unsigned int handlerListSize) | ||||
| hrnProtocolLocalShimInstall(const List *const handlerList) | ||||
| { | ||||
|     FUNCTION_HARNESS_BEGIN(); | ||||
|         FUNCTION_HARNESS_PARAM_P(VOID, handlerList); | ||||
|         FUNCTION_HARNESS_PARAM(UINT, handlerListSize); | ||||
|         FUNCTION_HARNESS_PARAM(LIST, handlerList); | ||||
|     FUNCTION_HARNESS_END(); | ||||
|  | ||||
|     hrnProtocolStatic.localShim = true; | ||||
|     hrnProtocolStatic.localHandlerList = handlerList; | ||||
|     hrnProtocolStatic.localHandlerListSize = handlerListSize; | ||||
|  | ||||
|     FUNCTION_HARNESS_RETURN_VOID(); | ||||
| } | ||||
| @@ -210,7 +205,7 @@ protocolRemoteExec( | ||||
|             ProtocolServer *server = protocolServerNew( | ||||
|                 name, PROTOCOL_SERVICE_REMOTE_STR, ioFdReadNewOpen(name, pipeWrite[0], 10000), | ||||
|                 ioFdWriteNewOpen(name, pipeRead[1], 10000)); | ||||
|             protocolServerProcess(server, NULL, hrnProtocolStatic.remoteHandlerList, hrnProtocolStatic.remoteHandlerListSize); | ||||
|             protocolServerProcess(server, NULL, hrnProtocolStatic.remoteHandlerList); | ||||
|  | ||||
|             // Put an end message here to sync with the client to ensure that coverage data is written before exiting | ||||
|             protocolServerResponseP(server); | ||||
| @@ -241,16 +236,14 @@ protocolRemoteExec( | ||||
|  | ||||
| /**********************************************************************************************************************************/ | ||||
| void | ||||
| hrnProtocolRemoteShimInstall(const ProtocolServerHandler *const handlerList, const unsigned int handlerListSize) | ||||
| hrnProtocolRemoteShimInstall(const List *const handlerList) | ||||
| { | ||||
|     FUNCTION_HARNESS_BEGIN(); | ||||
|         FUNCTION_HARNESS_PARAM_P(VOID, handlerList); | ||||
|         FUNCTION_HARNESS_PARAM(UINT, handlerListSize); | ||||
|         FUNCTION_HARNESS_PARAM(LIST, handlerList); | ||||
|     FUNCTION_HARNESS_END(); | ||||
|  | ||||
|     hrnProtocolStatic.remoteShim = true; | ||||
|     hrnProtocolStatic.remoteHandlerList = handlerList; | ||||
|     hrnProtocolStatic.remoteHandlerListSize = handlerListSize; | ||||
|  | ||||
|     FUNCTION_HARNESS_RETURN_VOID(); | ||||
| } | ||||
|   | ||||
| @@ -9,10 +9,10 @@ Functions | ||||
| // Install/uninstall the shim that allows protocolLocalGet() to start a local in a forked process rather than being exec'd. The main | ||||
| // benefit is that code running in the forked process will be included in coverage so no separate tests for the local protocol | ||||
| // functions should be required. A side benefit is that the pgbackrest binary does not need to be built since there is no exec. | ||||
| void hrnProtocolLocalShimInstall(const ProtocolServerHandler *const handlerList, const unsigned int handlerListSize); | ||||
| void hrnProtocolLocalShimInstall(const List *const handlerList); | ||||
| void hrnProtocolLocalShimUninstall(void); | ||||
|  | ||||
| // Install/uninstall the shim that allows protocolRemoteGet() to start a remote in a forked process rather than being exec'd via | ||||
| // SSH. The benefits are the same as hrnProtocolLocalShimInstall(). | ||||
| void hrnProtocolRemoteShimInstall(const ProtocolServerHandler *const handlerList, const unsigned int handlerListSize); | ||||
| void hrnProtocolRemoteShimInstall(const List *const handlerList); | ||||
| void hrnProtocolRemoteShimUninstall(void); | ||||
|   | ||||
| @@ -98,7 +98,7 @@ testRun(void) | ||||
|  | ||||
|         // Install local command handler shim | ||||
|         static const ProtocolServerHandler testLocalHandlerList[] = {PROTOCOL_SERVER_HANDLER_ARCHIVE_GET_LIST}; | ||||
|         hrnProtocolLocalShimInstall(testLocalHandlerList, LENGTH_OF(testLocalHandlerList)); | ||||
|         hrnProtocolLocalShimInstall(LSTDEF(testLocalHandlerList)); | ||||
|  | ||||
|         // Arguments that must be included | ||||
|         StringList *argBaseList = strLstNew(); | ||||
|   | ||||
| @@ -651,7 +651,7 @@ testRun(void) | ||||
|  | ||||
|         // Install local command handler shim | ||||
|         static const ProtocolServerHandler testLocalHandlerList[] = {PROTOCOL_SERVER_HANDLER_ARCHIVE_PUSH_LIST}; | ||||
|         hrnProtocolLocalShimInstall(testLocalHandlerList, LENGTH_OF(testLocalHandlerList)); | ||||
|         hrnProtocolLocalShimInstall(LSTDEF(testLocalHandlerList)); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         TEST_TITLE("command must be run on the pg host"); | ||||
|   | ||||
| @@ -559,7 +559,7 @@ testRun(void) | ||||
|  | ||||
|     // Install local command handler shim | ||||
|     static const ProtocolServerHandler testLocalHandlerList[] = {PROTOCOL_SERVER_HANDLER_BACKUP_LIST}; | ||||
|     hrnProtocolLocalShimInstall(testLocalHandlerList, LENGTH_OF(testLocalHandlerList)); | ||||
|     hrnProtocolLocalShimInstall(LSTDEF(testLocalHandlerList)); | ||||
|  | ||||
|     // The tests expect the timezone to be UTC | ||||
|     hrnTzSet("UTC"); | ||||
|   | ||||
| @@ -27,7 +27,7 @@ testRun(void) | ||||
|  | ||||
|     // Install local command handler shim | ||||
|     static const ProtocolServerHandler testLocalHandlerList[] = {PROTOCOL_SERVER_HANDLER_BACKUP_LIST}; | ||||
|     hrnProtocolLocalShimInstall(testLocalHandlerList, LENGTH_OF(testLocalHandlerList)); | ||||
|     hrnProtocolLocalShimInstall(LSTDEF(testLocalHandlerList)); | ||||
|  | ||||
|     // Test storage | ||||
|     const Storage *const storageTest = storagePosixNewP(TEST_PATH_STR, .write = true); | ||||
|   | ||||
| @@ -155,7 +155,7 @@ testRun(void) | ||||
|         PROTOCOL_SERVER_HANDLER_RESTORE_LIST | ||||
|     }; | ||||
|  | ||||
|     hrnProtocolLocalShimInstall(testLocalHandlerList, LENGTH_OF(testLocalHandlerList)); | ||||
|     hrnProtocolLocalShimInstall(LSTDEF(testLocalHandlerList)); | ||||
|  | ||||
|     // Create default storage object for testing | ||||
|     Storage *storageTest = storagePosixNewP(TEST_PATH_STR, .write = true); | ||||
|   | ||||
| @@ -32,7 +32,7 @@ testRun(void) | ||||
|         PROTOCOL_SERVER_HANDLER_BACKUP_LIST | ||||
|         PROTOCOL_SERVER_HANDLER_VERIFY_LIST | ||||
|     }; | ||||
|     hrnProtocolLocalShimInstall(testLocalHandlerList, LENGTH_OF(testLocalHandlerList)); | ||||
|     hrnProtocolLocalShimInstall(LSTDEF(testLocalHandlerList)); | ||||
|  | ||||
|     StringList *argListBase = strLstNew(); | ||||
|     hrnCfgArgRawZ(argListBase, cfgOptStanza, "db"); | ||||
|   | ||||
| @@ -26,7 +26,7 @@ testRun(void) | ||||
|         char logBuf[STACK_TRACE_PARAM_MAX]; | ||||
|         List *list = lstNewP(sizeof(void *)); | ||||
|  | ||||
|         TEST_RESULT_UINT(list->itemSize, sizeof(void *), "item size"); | ||||
|         TEST_RESULT_UINT(list->pub.itemSize, sizeof(void *), "item size"); | ||||
|         TEST_RESULT_UINT(list->pub.listSize, 0, "list size"); | ||||
|         TEST_RESULT_UINT(list->listSizeMax, 0, "list size max"); | ||||
|         TEST_RESULT_PTR(lstMemContext(list), objMemContext(list), "list mem context"); | ||||
|   | ||||
| @@ -35,7 +35,7 @@ testRun(void) | ||||
|                     STRDEF("test"), STRDEF("config"), HRN_FORK_CHILD_READ(), HRN_FORK_CHILD_WRITE()); | ||||
|  | ||||
|                 static const ProtocolServerHandler commandHandler[] = {PROTOCOL_SERVER_HANDLER_OPTION_LIST}; | ||||
|                 protocolServerProcess(server, NULL, commandHandler, LENGTH_OF(commandHandler)); | ||||
|                 protocolServerProcess(server, NULL, LSTDEF(commandHandler)); | ||||
|             } | ||||
|             HRN_FORK_CHILD_END(); | ||||
|  | ||||
|   | ||||
| @@ -113,8 +113,7 @@ testRun(void) | ||||
|                     PROTOCOL_SERVER_HANDLER_STORAGE_REMOTE_LIST | ||||
|                 }; | ||||
|  | ||||
|                 TEST_RESULT_VOID( | ||||
|                     protocolServerProcess(server, NULL, commandHandler, LENGTH_OF(commandHandler)), "run process loop"); | ||||
|                 TEST_RESULT_VOID(protocolServerProcess(server, NULL, LSTDEF(commandHandler)), "run process loop"); | ||||
|                 TEST_RESULT_VOID(protocolServerFree(server), "free server"); | ||||
|             } | ||||
|             HRN_FORK_CHILD_END(); | ||||
|   | ||||
| @@ -765,14 +765,11 @@ testRun(void) | ||||
|             {.blockSize = 32 * 1024, .checksumSize = BLOCK_INCR_CHECKSUM_SIZE_MIN + 1}, | ||||
|         }; | ||||
|  | ||||
|         static const ManifestBlockIncrMap manifestBuildBlockIncrMap = | ||||
|         const ManifestBlockIncrMap manifestBuildBlockIncrMap = | ||||
|         { | ||||
|             .sizeMap = manifestBlockIncrSizeMap, | ||||
|             .sizeMapSize = LENGTH_OF(manifestBlockIncrSizeMap), | ||||
|             .ageMap = manifestBlockIncrAgeMap, | ||||
|             .ageMapSize = LENGTH_OF(manifestBlockIncrAgeMap), | ||||
|             .checksumSizeMap = manifestBlockIncrChecksumSizeMap, | ||||
|             .checksumSizeMapSize = LENGTH_OF(manifestBlockIncrChecksumSizeMap), | ||||
|             .sizeMap = LSTDEF(manifestBlockIncrSizeMap), | ||||
|             .ageMap = LSTDEF(manifestBlockIncrAgeMap), | ||||
|             .checksumSizeMap = LSTDEF(manifestBlockIncrChecksumSizeMap), | ||||
|         }; | ||||
|  | ||||
|         // pg_wal not ignored | ||||
|   | ||||
| @@ -166,7 +166,7 @@ testRun(void) | ||||
|                     STRDEF("storage test server"), STRDEF("test"), HRN_FORK_CHILD_READ(), HRN_FORK_CHILD_WRITE()); | ||||
|  | ||||
|                 static const ProtocolServerHandler commandHandler[] = {PROTOCOL_SERVER_HANDLER_STORAGE_REMOTE_LIST}; | ||||
|                 protocolServerProcess(server, NULL, commandHandler, LENGTH_OF(commandHandler)); | ||||
|                 protocolServerProcess(server, NULL, LSTDEF(commandHandler)); | ||||
|             } | ||||
|             HRN_FORK_CHILD_END(); | ||||
|  | ||||
|   | ||||
| @@ -560,7 +560,7 @@ testRun(void) | ||||
|                 const ProtocolServerHandler commandHandler[] = {TEST_PROTOCOL_SERVER_HANDLER_LIST}; | ||||
|  | ||||
|                 TEST_ERROR( | ||||
|                     protocolServerProcess(server, NULL, commandHandler, LENGTH_OF(commandHandler)), ProtocolError, | ||||
|                     protocolServerProcess(server, NULL, LSTDEF(commandHandler)), ProtocolError, | ||||
|                     "invalid request 'BOGUS' (0x38eacd271)"); | ||||
|  | ||||
|                 // ----------------------------------------------------------------------------------------------------------------- | ||||
| @@ -568,13 +568,13 @@ testRun(void) | ||||
|  | ||||
|                 // This does not run in a TEST* macro because tests are run by the command handlers | ||||
|                 TEST_ERROR( | ||||
|                     protocolServerProcess(server, NULL, commandHandler, LENGTH_OF(commandHandler)), AssertError, "ERR_MESSAGE"); | ||||
|                     protocolServerProcess(server, NULL, LSTDEF(commandHandler)), AssertError, "ERR_MESSAGE"); | ||||
|  | ||||
|                 // ----------------------------------------------------------------------------------------------------------------- | ||||
|                 TEST_TITLE("server restart"); | ||||
|  | ||||
|                 // This does not run in a TEST* macro because tests are run by the command handlers | ||||
|                 protocolServerProcess(server, NULL, commandHandler, LENGTH_OF(commandHandler)); | ||||
|                 protocolServerProcess(server, NULL, LSTDEF(commandHandler)); | ||||
|  | ||||
|                 // ----------------------------------------------------------------------------------------------------------------- | ||||
|                 TEST_TITLE("server with retries"); | ||||
| @@ -588,7 +588,7 @@ testRun(void) | ||||
|                     "new server"); | ||||
|  | ||||
|                 // This does not run in a TEST* macro because tests are run by the command handlers | ||||
|                 protocolServerProcess(server, retryList, commandHandler, LENGTH_OF(commandHandler)); | ||||
|                 protocolServerProcess(server, retryList, LSTDEF(commandHandler)); | ||||
|             } | ||||
|             HRN_FORK_CHILD_END(); | ||||
|  | ||||
|   | ||||
| @@ -32,7 +32,7 @@ testRun(void) | ||||
|         PROTOCOL_SERVER_HANDLER_STORAGE_REMOTE_LIST | ||||
|     }; | ||||
|  | ||||
|     hrnProtocolRemoteShimInstall(testRemoteHandlerList, LENGTH_OF(testRemoteHandlerList)); | ||||
|     hrnProtocolRemoteShimInstall(LSTDEF(testRemoteHandlerList)); | ||||
|  | ||||
|     // Set filter handlers | ||||
|     static const StorageRemoteFilterHandler storageRemoteFilterHandlerList[] = | ||||
| @@ -43,7 +43,7 @@ testRun(void) | ||||
|         {.type = SIZE_FILTER_TYPE, .handlerNoParam = ioSizeNew}, | ||||
|     }; | ||||
|  | ||||
|     storageRemoteFilterHandlerSet(storageRemoteFilterHandlerList, LENGTH_OF(storageRemoteFilterHandlerList)); | ||||
|     storageRemoteFilterHandlerSet(LSTDEF(storageRemoteFilterHandlerList)); | ||||
|  | ||||
|     // Test storage | ||||
|     Storage *storageTest = storagePosixNewP(TEST_PATH_STR, .write = true); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user