|
Packit Service |
75d76b |
/*
|
|
Packit Service |
75d76b |
* Copyright (c) 2020 Red Hat, Inc.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* This program is free software; you can redistribute it and/or
|
|
Packit Service |
75d76b |
* modify it under the terms of the GNU General Public License
|
|
Packit Service |
75d76b |
* as published by the Free Software Foundation; either version 2
|
|
Packit Service |
75d76b |
* of the License, or (at your option) any later version.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
75d76b |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
75d76b |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
75d76b |
* GNU General Public License for more details.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
75d76b |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
75d76b |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
75d76b |
* 02110-1301, USA.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/errors.c#2 $
|
|
Packit Service |
75d76b |
*/
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
#include "errors.h"
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
#include <linux/kernel.h>
|
|
Packit Service |
75d76b |
#include <linux/module.h>
|
|
Packit Service |
75d76b |
#include <linux/string.h>
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
#include "permassert.h"
|
|
Packit Service |
75d76b |
#include "statusCodes.h"
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
static const struct errorInfo errorList[] = {
|
|
Packit Service |
75d76b |
{ "UDS_UNINITIALIZED", "UDS library is not initialized" },
|
|
Packit Service |
75d76b |
{ "UDS_SHUTTINGDOWN", "UDS library is shutting down" },
|
|
Packit Service |
75d76b |
{ "UDS_EMODULE_LOAD", "Could not load modules" },
|
|
Packit Service |
75d76b |
{ "UDS_ENOTHREADS", "Could not create a new thread" },
|
|
Packit Service |
75d76b |
{ "UDS_NOCONTEXT", "Could not find the requested library context" },
|
|
Packit Service |
75d76b |
{ "UDS_DISABLED", "UDS library context is disabled" },
|
|
Packit Service |
75d76b |
{ "UDS_CORRUPT_FILE", "Corrupt file" },
|
|
Packit Service |
75d76b |
{ "UDS_UNKNOWN_ERROR", "Unknown error" },
|
|
Packit Service |
75d76b |
{ "UDS_GRID_NO_SERVERS", "No servers in grid configuration" },
|
|
Packit Service |
75d76b |
{ "UDS_GRID_CONFIG_INCONSISTENT", "Grid configuration inconsistent" },
|
|
Packit Service |
75d76b |
{ "UDS_UNSUPPORTED_VERSION", "Unsupported version" },
|
|
Packit Service |
75d76b |
{ "UDS_NO_INDEXSESSION", "Index session not known" },
|
|
Packit Service |
75d76b |
{ "UDS_CORRUPT_DATA", "Index data in memory is corrupt" },
|
|
Packit Service |
75d76b |
{ "UDS_SHORT_READ", "Could not read requested number of bytes" },
|
|
Packit Service |
75d76b |
{ "UDS_AI_ERROR", "Network address and service translation error" },
|
|
Packit Service |
75d76b |
{ "UDS_RESOURCE_LIMIT_EXCEEDED", "Internal resource limits exceeded" },
|
|
Packit Service |
75d76b |
{ "UDS_WRONG_CONTEXT_TYPE", "Context type mismatch" },
|
|
Packit Service |
75d76b |
{ "UDS_BLOCK_ADDRESS_REQUIRED", "A block address is required" },
|
|
Packit Service |
75d76b |
{ "UDS_CHUNK_DATA_REQUIRED", "Block data is required" },
|
|
Packit Service |
75d76b |
{ "UDS_CHUNK_NAME_REQUIRED", "A chunk name is required" },
|
|
Packit Service |
75d76b |
{ "UDS_CONF_PTR_REQUIRED", "A configuration pointer is required" },
|
|
Packit Service |
75d76b |
{ "UDS_INDEX_STATS_PTR_REQUIRED", "An index stats pointer is required" },
|
|
Packit Service |
75d76b |
{ "UDS_CONTEXT_STATS_PTR_REQUIRED", "A context stats pointer is required" },
|
|
Packit Service |
75d76b |
{ "UDS_CONTEXT_PTR_REQUIRED", "A context pointer is required" },
|
|
Packit Service |
75d76b |
{ "UDS_FILEID_REQUIRED", "A file ID is required" },
|
|
Packit Service |
75d76b |
{ "UDS_STREAM_REQUIRED", "A stream is required" },
|
|
Packit Service |
75d76b |
{ "UDS_STREAMID_REQUIRED", "A stream ID is required" },
|
|
Packit Service |
75d76b |
{ "UDS_STREAM_PTR_REQUIRED", "A stream pointer is required" },
|
|
Packit Service |
75d76b |
{ "UDS_INVALID_MEMORY_SIZE",
|
|
Packit Service |
75d76b |
"Configured memory too small or unsupported size" },
|
|
Packit Service |
75d76b |
{ "UDS_INVALID_METADATA_SIZE", "Invalid metadata size" },
|
|
Packit Service |
75d76b |
{ "UDS_INDEX_NAME_REQUIRED", "An index name is required" },
|
|
Packit Service |
75d76b |
{ "UDS_CONF_REQUIRED", "A configuration is required" },
|
|
Packit Service |
75d76b |
{ "UDS_BAD_FILE_DESCRIPTOR", "Bad file descriptor" },
|
|
Packit Service |
75d76b |
{ "UDS_INDEX_EXISTS", "Index already exists" },
|
|
Packit Service |
75d76b |
{ "UDS_REQUESTS_OUT_OF_RANGE", "Maximum request value out of range" },
|
|
Packit Service |
75d76b |
{ "UDS_BAD_NAMESPACE", "Bad namespace" },
|
|
Packit Service |
75d76b |
{ "UDS_MIGRATOR_MISMATCH",
|
|
Packit Service |
75d76b |
"Migrator arguments do not match reader arguments" },
|
|
Packit Service |
75d76b |
{ "UDS_NO_INDEX", "No index found" },
|
|
Packit Service |
75d76b |
{ "UDS_BAD_CHECKPOINT_FREQUENCY", "Checkpoint frequency out of range" },
|
|
Packit Service |
75d76b |
{ "UDS_WRONG_INDEX_CONFIG", "Wrong type of index configuration" },
|
|
Packit Service |
75d76b |
{ "UDS_INDEX_PATH_NOT_DIR", "Index path does not point to a directory" },
|
|
Packit Service |
75d76b |
{ "UDS_ALREADY_OPEN", "Open invoked on already opened connection" },
|
|
Packit Service |
75d76b |
{ "UDS_CALLBACK_ALREADY_REGISTERED", "Callback already registered" },
|
|
Packit Service |
75d76b |
{ "UDS_INDEX_PATH_TOO_LONG", "Index path too long" },
|
|
Packit Service |
75d76b |
{ "UDS_END_OF_FILE", "Unexpected end of file" },
|
|
Packit Service |
75d76b |
{ "UDS_INDEX_NOT_SAVED_CLEANLY", "Index not saved cleanly" },
|
|
Packit Service |
75d76b |
};
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
static const struct errorInfo internalErrorList[] = {
|
|
Packit Service |
75d76b |
{ "UDS_PROTOCOL_ERROR", "Client/server protocol error" },
|
|
Packit Service |
75d76b |
{ "UDS_OVERFLOW", "Index overflow" },
|
|
Packit Service |
75d76b |
{ "UDS_FILLDONE", "Fill phase done" },
|
|
Packit Service |
75d76b |
{ "UDS_INVALID_ARGUMENT", "Invalid argument passed to internal routine" },
|
|
Packit Service |
75d76b |
{ "UDS_BAD_STATE", "UDS data structures are in an invalid state" },
|
|
Packit Service |
75d76b |
{ "UDS_DUPLICATE_NAME",
|
|
Packit Service |
75d76b |
"Attempt to enter the same name into a delta index twice" },
|
|
Packit Service |
75d76b |
{ "UDS_UNEXPECTED_RESULT", "Unexpected result from internal routine" },
|
|
Packit Service |
75d76b |
{ "UDS_INJECTED_ERROR", "Injected error" },
|
|
Packit Service |
75d76b |
{ "UDS_ASSERTION_FAILED", "Assertion failed" },
|
|
Packit Service |
75d76b |
{ "UDS_UNSCANNABLE", "Unscannable" },
|
|
Packit Service |
75d76b |
{ "UDS_QUEUED", "Request queued" },
|
|
Packit Service |
75d76b |
{ "UDS_QUEUE_ALREADY_CONNECTED", "Queue already connected" },
|
|
Packit Service |
75d76b |
{ "UDS_BAD_FILL_PHASE", "Fill phase not supported" },
|
|
Packit Service |
75d76b |
{ "UDS_BUFFER_ERROR", "Buffer error" },
|
|
Packit Service |
75d76b |
{ "UDS_CONNECTION_LOST", "Lost connection to peer" },
|
|
Packit Service |
75d76b |
{ "UDS_TIMEOUT", "A time out has occurred" },
|
|
Packit Service |
75d76b |
{ "UDS_NO_DIRECTORY", "Expected directory is missing" },
|
|
Packit Service |
75d76b |
{ "UDS_CHECKPOINT_INCOMPLETE", "Checkpoint not completed" },
|
|
Packit Service |
75d76b |
{ "UDS_INVALID_RUN_ID", "Invalid albGenTest server run ID" },
|
|
Packit Service |
75d76b |
{ "UDS_RUN_CANCELED", "albGenTest server run canceled" },
|
|
Packit Service |
75d76b |
{ "UDS_ALREADY_REGISTERED", "error range already registered" },
|
|
Packit Service |
75d76b |
};
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/** Error attributes - or into top half of error code */
|
|
Packit Service |
75d76b |
enum {
|
|
Packit Service |
75d76b |
UDS_UNRECOVERABLE = (1 << 17)
|
|
Packit Service |
75d76b |
};
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
typedef struct errorBlock {
|
|
Packit Service |
75d76b |
const char *name;
|
|
Packit Service |
75d76b |
int base;
|
|
Packit Service |
75d76b |
int last;
|
|
Packit Service |
75d76b |
int max;
|
|
Packit Service |
75d76b |
const ErrorInfo *infos;
|
|
Packit Service |
75d76b |
} ErrorBlock;
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
enum {
|
|
Packit Service |
75d76b |
MAX_ERROR_BLOCKS = 6 // needed for testing
|
|
Packit Service |
75d76b |
};
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
static struct errorInformation {
|
|
Packit Service |
75d76b |
int allocated;
|
|
Packit Service |
75d76b |
int count;
|
|
Packit Service |
75d76b |
ErrorBlock blocks[MAX_ERROR_BLOCKS];
|
|
Packit Service |
75d76b |
} registeredErrors;
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/**********************************************************************/
|
|
Packit Service |
75d76b |
void initializeStandardErrorBlocks(void)
|
|
Packit Service |
75d76b |
{
|
|
Packit Service |
75d76b |
registeredErrors.allocated = MAX_ERROR_BLOCKS;
|
|
Packit Service |
75d76b |
registeredErrors.count = 0;
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
registeredErrors.blocks[registeredErrors.count++] = (ErrorBlock) {
|
|
Packit Service |
75d76b |
.name = "UDS Error",
|
|
Packit Service |
75d76b |
.base = UDS_ERROR_CODE_BASE,
|
|
Packit Service |
75d76b |
.last = UDS_ERROR_CODE_LAST,
|
|
Packit Service |
75d76b |
.max = UDS_ERROR_CODE_BLOCK_END,
|
|
Packit Service |
75d76b |
.infos = errorList,
|
|
Packit Service |
75d76b |
};
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
registeredErrors.blocks[registeredErrors.count++] = (ErrorBlock) {
|
|
Packit Service |
75d76b |
.name = "UDS Internal Error",
|
|
Packit Service |
75d76b |
.base = UDS_INTERNAL_ERROR_CODE_BASE,
|
|
Packit Service |
75d76b |
.last = UDS_INTERNAL_ERROR_CODE_LAST,
|
|
Packit Service |
75d76b |
.max = UDS_INTERNAL_ERROR_CODE_BLOCK_END,
|
|
Packit Service |
75d76b |
.infos = internalErrorList,
|
|
Packit Service |
75d76b |
};
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
registeredErrors.blocks[registeredErrors.count++] = (ErrorBlock) {
|
|
Packit Service |
75d76b |
.name = THIS_MODULE->name,
|
|
Packit Service |
75d76b |
.base = VDO_BLOCK_START,
|
|
Packit Service |
75d76b |
.last = VDO_STATUS_CODE_LAST,
|
|
Packit Service |
75d76b |
.max = VDO_BLOCK_END,
|
|
Packit Service |
75d76b |
.infos = vdoStatusList,
|
|
Packit Service |
75d76b |
};
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/**
|
|
Packit Service |
75d76b |
* Fetch the error info (if any) for the error number.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* @param errnum the error number
|
|
Packit Service |
75d76b |
* @param infoPtr the place to store the info for this error (if known),
|
|
Packit Service |
75d76b |
* otherwise set to NULL
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* @return the name of the error block (if known), NULL otherwise
|
|
Packit Service |
75d76b |
**/
|
|
Packit Service |
75d76b |
static const char *getErrorInfo(int errnum, const ErrorInfo **infoPtr)
|
|
Packit Service |
75d76b |
{
|
|
Packit Service |
75d76b |
for (ErrorBlock *block = registeredErrors.blocks;
|
|
Packit Service |
75d76b |
block < registeredErrors.blocks + registeredErrors.count;
|
|
Packit Service |
75d76b |
++block) {
|
|
Packit Service |
75d76b |
if ((errnum >= block->base) && (errnum < block->last)) {
|
|
Packit Service |
75d76b |
if (infoPtr != NULL) {
|
|
Packit Service |
75d76b |
*infoPtr = block->infos + (errnum - block->base);
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
return block->name;
|
|
Packit Service |
75d76b |
} else if ((errnum >= block->last) && (errnum < block->max)) {
|
|
Packit Service |
75d76b |
if (infoPtr != NULL) {
|
|
Packit Service |
75d76b |
*infoPtr = NULL;
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
return block->name;
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
if (infoPtr != NULL) {
|
|
Packit Service |
75d76b |
*infoPtr = NULL;
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
return NULL;
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/*****************************************************************************/
|
|
Packit Service |
75d76b |
const char *stringError(int errnum, char *buf, size_t buflen)
|
|
Packit Service |
75d76b |
{
|
|
Packit Service |
75d76b |
if (buf == NULL) {
|
|
Packit Service |
75d76b |
return NULL;
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
const ErrorInfo *info = NULL;
|
|
Packit Service |
75d76b |
const char *blockName = getErrorInfo(errnum, &info;;
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
if (blockName != NULL) {
|
|
Packit Service |
75d76b |
if (info != NULL) {
|
|
Packit Service |
75d76b |
snprintf(buf, buflen, "%s: %s", blockName, info->message);
|
|
Packit Service |
75d76b |
} else {
|
|
Packit Service |
75d76b |
snprintf(buf, buflen, "Unknown %s %d", blockName, errnum);
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
} else {
|
|
Packit Service |
75d76b |
snprintf(buf, buflen, "System error %d", errnum);
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
return buf;
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/*****************************************************************************/
|
|
Packit Service |
75d76b |
const char *stringErrorName(int errnum, char *buf, size_t buflen)
|
|
Packit Service |
75d76b |
{
|
|
Packit Service |
75d76b |
const ErrorInfo *info = NULL;
|
|
Packit Service |
75d76b |
const char *blockName = getErrorInfo(errnum, &info;;
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
if (blockName != NULL) {
|
|
Packit Service |
75d76b |
if (info != NULL) {
|
|
Packit Service |
75d76b |
snprintf(buf, buflen, "%s: %s", blockName, info->name);
|
|
Packit Service |
75d76b |
} else {
|
|
Packit Service |
75d76b |
snprintf(buf, buflen, "Unknown %s %d", blockName, errnum);
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
} else {
|
|
Packit Service |
75d76b |
snprintf(buf, buflen, "System error %d", errnum);
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
return buf;
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/*****************************************************************************/
|
|
Packit Service |
75d76b |
int makeUnrecoverable(int resultCode)
|
|
Packit Service |
75d76b |
{
|
|
Packit Service |
75d76b |
return ((resultCode == UDS_SUCCESS)
|
|
Packit Service |
75d76b |
? resultCode
|
|
Packit Service |
75d76b |
: (resultCode | UDS_UNRECOVERABLE));
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/*****************************************************************************/
|
|
Packit Service |
75d76b |
int sansUnrecoverable(int resultCode)
|
|
Packit Service |
75d76b |
{
|
|
Packit Service |
75d76b |
return resultCode & ~UDS_UNRECOVERABLE;
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/*****************************************************************************/
|
|
Packit Service |
75d76b |
bool isUnrecoverable(int resultCode)
|
|
Packit Service |
75d76b |
{
|
|
Packit Service |
75d76b |
return (bool)(resultCode & UDS_UNRECOVERABLE);
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/*****************************************************************************/
|
|
Packit Service |
75d76b |
int registerErrorBlock(const char *blockName,
|
|
Packit Service |
75d76b |
int firstError,
|
|
Packit Service |
75d76b |
int lastReservedError,
|
|
Packit Service |
75d76b |
const ErrorInfo *infos,
|
|
Packit Service |
75d76b |
size_t infoSize)
|
|
Packit Service |
75d76b |
{
|
|
Packit Service |
75d76b |
int result = ASSERT(firstError < lastReservedError,
|
|
Packit Service |
75d76b |
"bad error block range");
|
|
Packit Service |
75d76b |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
75d76b |
return result;
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
if (registeredErrors.count == registeredErrors.allocated) {
|
|
Packit Service |
75d76b |
// could reallocate and grow, but should never happen
|
|
Packit Service |
75d76b |
return UDS_OVERFLOW;
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
for (ErrorBlock *block = registeredErrors.blocks;
|
|
Packit Service |
75d76b |
block < registeredErrors.blocks + registeredErrors.count;
|
|
Packit Service |
75d76b |
++block) {
|
|
Packit Service |
75d76b |
if (strcmp(blockName, block->name) == 0) {
|
|
Packit Service |
75d76b |
return UDS_DUPLICATE_NAME;
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
// check for overlap in error ranges
|
|
Packit Service |
75d76b |
if ((firstError < block->max) && (lastReservedError > block->base)) {
|
|
Packit Service |
75d76b |
return UDS_ALREADY_REGISTERED;
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
registeredErrors.blocks[registeredErrors.count++] = (ErrorBlock) {
|
|
Packit Service |
75d76b |
.name = blockName,
|
|
Packit Service |
75d76b |
.base = firstError,
|
|
Packit Service |
75d76b |
.last = firstError + (infoSize / sizeof(ErrorInfo)),
|
|
Packit Service |
75d76b |
.max = lastReservedError,
|
|
Packit Service |
75d76b |
.infos = infos
|
|
Packit Service |
75d76b |
};
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
return UDS_SUCCESS;
|
|
Packit Service |
75d76b |
}
|