|
Packit Service |
310c69 |
/*
|
|
Packit Service |
310c69 |
* Copyright (c) 2020 Red Hat, Inc.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* This program is free software; you can redistribute it and/or
|
|
Packit Service |
310c69 |
* modify it under the terms of the GNU General Public License
|
|
Packit Service |
310c69 |
* as published by the Free Software Foundation; either version 2
|
|
Packit Service |
310c69 |
* of the License, or (at your option) any later version.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
310c69 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
310c69 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
310c69 |
* GNU General Public License for more details.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
310c69 |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
310c69 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
310c69 |
* 02110-1301, USA.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* $Id: //eng/uds-releases/jasper/src/uds/udsMain.c#12 $
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#include "uds.h"
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#include "config.h"
|
|
Packit Service |
310c69 |
#include "geometry.h"
|
|
Packit Service |
310c69 |
#include "indexLayout.h"
|
|
Packit Service |
310c69 |
#include "indexRouter.h"
|
|
Packit Service |
310c69 |
#include "indexSession.h"
|
|
Packit Service |
310c69 |
#include "loadType.h"
|
|
Packit Service |
310c69 |
#include "logger.h"
|
|
Packit Service |
310c69 |
#include "memoryAlloc.h"
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
const UdsMemoryConfigSize UDS_MEMORY_CONFIG_MAX = 1024;
|
|
Packit Service |
310c69 |
const UdsMemoryConfigSize UDS_MEMORY_CONFIG_256MB = (UdsMemoryConfigSize) -256;
|
|
Packit Service |
310c69 |
const UdsMemoryConfigSize UDS_MEMORY_CONFIG_512MB = (UdsMemoryConfigSize) -512;
|
|
Packit Service |
310c69 |
const UdsMemoryConfigSize UDS_MEMORY_CONFIG_768MB = (UdsMemoryConfigSize) -768;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/*
|
|
Packit Service |
310c69 |
* ===========================================================================
|
|
Packit Service |
310c69 |
* UDS system management
|
|
Packit Service |
310c69 |
* ===========================================================================
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
int udsInitializeConfiguration(UdsConfiguration *userConfig,
|
|
Packit Service |
310c69 |
UdsMemoryConfigSize memGB)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
if (userConfig == NULL) {
|
|
Packit Service |
310c69 |
return logErrorWithStringError(UDS_CONF_PTR_REQUIRED,
|
|
Packit Service |
310c69 |
"received a NULL config pointer");
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/* Set the configuration parameters that change with memory size. If you
|
|
Packit Service |
310c69 |
* change these values, you should also:
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* Change Configuration_x1, which tests these values and expects to see them
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* Bump the index configuration version number. This bump ensures that
|
|
Packit Service |
310c69 |
* the test infrastructure will be forced to test the new configuration.
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
unsigned int chaptersPerVolume, recordPagesPerChapter;
|
|
Packit Service |
310c69 |
if (memGB == UDS_MEMORY_CONFIG_256MB) {
|
|
Packit Service |
310c69 |
chaptersPerVolume = DEFAULT_CHAPTERS_PER_VOLUME;
|
|
Packit Service |
310c69 |
recordPagesPerChapter = SMALL_RECORD_PAGES_PER_CHAPTER;
|
|
Packit Service |
310c69 |
} else if (memGB == UDS_MEMORY_CONFIG_512MB) {
|
|
Packit Service |
310c69 |
chaptersPerVolume = DEFAULT_CHAPTERS_PER_VOLUME;
|
|
Packit Service |
310c69 |
recordPagesPerChapter = 2 * SMALL_RECORD_PAGES_PER_CHAPTER;
|
|
Packit Service |
310c69 |
} else if (memGB == UDS_MEMORY_CONFIG_768MB) {
|
|
Packit Service |
310c69 |
chaptersPerVolume = DEFAULT_CHAPTERS_PER_VOLUME;
|
|
Packit Service |
310c69 |
recordPagesPerChapter = 3 * SMALL_RECORD_PAGES_PER_CHAPTER;
|
|
Packit Service |
310c69 |
} else if (memGB == 1) {
|
|
Packit Service |
310c69 |
chaptersPerVolume = DEFAULT_CHAPTERS_PER_VOLUME;
|
|
Packit Service |
310c69 |
recordPagesPerChapter = DEFAULT_RECORD_PAGES_PER_CHAPTER;
|
|
Packit Service |
310c69 |
} else if ((memGB > 1) && (memGB <= UDS_MEMORY_CONFIG_MAX)) {
|
|
Packit Service |
310c69 |
chaptersPerVolume = memGB * DEFAULT_CHAPTERS_PER_VOLUME;
|
|
Packit Service |
310c69 |
recordPagesPerChapter = DEFAULT_RECORD_PAGES_PER_CHAPTER;
|
|
Packit Service |
310c69 |
} else {
|
|
Packit Service |
310c69 |
return UDS_INVALID_MEMORY_SIZE;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
int result = ALLOCATE(1, struct udsConfiguration, "udsConfiguration",
|
|
Packit Service |
310c69 |
userConfig);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
(*userConfig)->recordPagesPerChapter = recordPagesPerChapter;
|
|
Packit Service |
310c69 |
(*userConfig)->chaptersPerVolume = chaptersPerVolume;
|
|
Packit Service |
310c69 |
(*userConfig)->sparseChaptersPerVolume = DEFAULT_SPARSE_CHAPTERS_PER_VOLUME;
|
|
Packit Service |
310c69 |
(*userConfig)->cacheChapters = DEFAULT_CACHE_CHAPTERS;
|
|
Packit Service |
310c69 |
(*userConfig)->checkpointFrequency = DEFAULT_CHECKPOINT_FREQUENCY;
|
|
Packit Service |
310c69 |
(*userConfig)->masterIndexMeanDelta = DEFAULT_MASTER_INDEX_MEAN_DELTA;
|
|
Packit Service |
310c69 |
(*userConfig)->bytesPerPage = DEFAULT_BYTES_PER_PAGE;
|
|
Packit Service |
310c69 |
(*userConfig)->sparseSampleRate = DEFAULT_SPARSE_SAMPLE_RATE;
|
|
Packit Service |
310c69 |
(*userConfig)->nonce = 0;
|
|
Packit Service |
310c69 |
return UDS_SUCCESS;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
void udsConfigurationSetSparse(UdsConfiguration userConfig, bool sparse)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
bool prevSparse = (userConfig->sparseChaptersPerVolume != 0);
|
|
Packit Service |
310c69 |
if (sparse == prevSparse) {
|
|
Packit Service |
310c69 |
// nothing to do
|
|
Packit Service |
310c69 |
return;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
unsigned int prevChaptersPerVolume = userConfig->chaptersPerVolume;
|
|
Packit Service |
310c69 |
if (sparse) {
|
|
Packit Service |
310c69 |
// Index 10TB with 4K blocks, 95% sparse, fit in dense (1TB) footprint
|
|
Packit Service |
310c69 |
userConfig->chaptersPerVolume = 10 * prevChaptersPerVolume;
|
|
Packit Service |
310c69 |
userConfig->sparseChaptersPerVolume = 9 * prevChaptersPerVolume
|
|
Packit Service |
310c69 |
+ prevChaptersPerVolume / 2;
|
|
Packit Service |
310c69 |
userConfig->sparseSampleRate = 32;
|
|
Packit Service |
310c69 |
} else {
|
|
Packit Service |
310c69 |
userConfig->chaptersPerVolume = prevChaptersPerVolume / 10;
|
|
Packit Service |
310c69 |
userConfig->sparseChaptersPerVolume = 0;
|
|
Packit Service |
310c69 |
userConfig->sparseSampleRate = 0;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
bool udsConfigurationGetSparse(UdsConfiguration userConfig)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return userConfig->sparseChaptersPerVolume > 0;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
void udsConfigurationSetNonce(UdsConfiguration userConfig, UdsNonce nonce)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
userConfig->nonce = nonce;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
UdsNonce udsConfigurationGetNonce(UdsConfiguration userConfig)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return userConfig->nonce;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
unsigned int udsConfigurationGetMemory(UdsConfiguration userConfig)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
enum {
|
|
Packit Service |
310c69 |
CHAPTERS = DEFAULT_CHAPTERS_PER_VOLUME,
|
|
Packit Service |
310c69 |
SMALL_PAGES = CHAPTERS * SMALL_RECORD_PAGES_PER_CHAPTER,
|
|
Packit Service |
310c69 |
LARGE_PAGES = CHAPTERS * DEFAULT_RECORD_PAGES_PER_CHAPTER
|
|
Packit Service |
310c69 |
};
|
|
Packit Service |
310c69 |
unsigned int pages = (userConfig->chaptersPerVolume
|
|
Packit Service |
310c69 |
* userConfig->recordPagesPerChapter);
|
|
Packit Service |
310c69 |
if (userConfig->sparseChaptersPerVolume != 0) {
|
|
Packit Service |
310c69 |
pages /= 10;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
switch (pages) {
|
|
Packit Service |
310c69 |
case SMALL_PAGES: return UDS_MEMORY_CONFIG_256MB;
|
|
Packit Service |
310c69 |
case 2 * SMALL_PAGES: return UDS_MEMORY_CONFIG_512MB;
|
|
Packit Service |
310c69 |
case 3 * SMALL_PAGES: return UDS_MEMORY_CONFIG_768MB;
|
|
Packit Service |
310c69 |
default: return pages / LARGE_PAGES;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
unsigned int
|
|
Packit Service |
310c69 |
udsConfigurationGetChaptersPerVolume(UdsConfiguration userConfig)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return userConfig->chaptersPerVolume;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
void udsFreeConfiguration(UdsConfiguration userConfig)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
FREE(userConfig);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
int udsCreateIndexSession(struct uds_index_session **session)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
if (session == NULL) {
|
|
Packit Service |
310c69 |
return UDS_NO_INDEXSESSION;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
struct uds_index_session *indexSession = NULL;
|
|
Packit Service |
310c69 |
int result = makeEmptyIndexSession(&indexSession);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
*session = indexSession;
|
|
Packit Service |
310c69 |
return UDS_SUCCESS;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static
|
|
Packit Service |
310c69 |
int initializeIndexSessionWithLayout(struct uds_index_session *indexSession,
|
|
Packit Service |
310c69 |
IndexLayout *layout,
|
|
Packit Service |
310c69 |
const struct uds_parameters *userParams,
|
|
Packit Service |
310c69 |
LoadType loadType)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
int result = ((loadType == LOAD_CREATE)
|
|
Packit Service |
310c69 |
? writeIndexConfig(layout, &indexSession->userConfig)
|
|
Packit Service |
310c69 |
: verifyIndexConfig(layout, &indexSession->userConfig));
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
Configuration *indexConfig;
|
|
Packit Service |
310c69 |
result = makeConfiguration(&indexSession->userConfig, &indexConfig);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
logErrorWithStringError(result, "Failed to allocate config");
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
// Zero the stats for the new index.
|
|
Packit Service |
310c69 |
memset(&indexSession->stats, 0, sizeof(indexSession->stats));
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
result = makeIndexRouter(layout, indexConfig, userParams, loadType,
|
|
Packit Service |
310c69 |
&indexSession->loadContext, enterCallbackStage,
|
|
Packit Service |
310c69 |
&indexSession->router);
|
|
Packit Service |
310c69 |
freeConfiguration(indexConfig);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
logErrorWithStringError(result, "Failed to make router");
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
logUdsConfiguration(&indexSession->userConfig);
|
|
Packit Service |
310c69 |
return UDS_SUCCESS;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static int initializeIndexSession(struct uds_index_session *indexSession,
|
|
Packit Service |
310c69 |
const char *name,
|
|
Packit Service |
310c69 |
const struct uds_parameters *userParams,
|
|
Packit Service |
310c69 |
LoadType loadType)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
IndexLayout *layout;
|
|
Packit Service |
310c69 |
int result = makeIndexLayout(name, loadType == LOAD_CREATE,
|
|
Packit Service |
310c69 |
&indexSession->userConfig, &layout);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
result = initializeIndexSessionWithLayout(indexSession, layout, userParams,
|
|
Packit Service |
310c69 |
loadType);
|
|
Packit Service |
310c69 |
putIndexLayout(&layout);
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
int udsOpenIndex(UdsOpenIndexType openType,
|
|
Packit Service |
310c69 |
const char *name,
|
|
Packit Service |
310c69 |
const struct uds_parameters *userParams,
|
|
Packit Service |
310c69 |
UdsConfiguration userConfig,
|
|
Packit Service |
310c69 |
struct uds_index_session *session)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
if (name == NULL) {
|
|
Packit Service |
310c69 |
return UDS_INDEX_NAME_REQUIRED;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
if (userConfig == NULL) {
|
|
Packit Service |
310c69 |
return UDS_CONF_REQUIRED;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
if (session == NULL) {
|
|
Packit Service |
310c69 |
return UDS_NO_INDEXSESSION;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
int result = startLoadingIndexSession(session);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
session->userConfig = *userConfig;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
// Map the external openType to the internal loadType
|
|
Packit Service |
310c69 |
LoadType loadType = openType == UDS_CREATE ? LOAD_CREATE
|
|
Packit Service |
310c69 |
: openType == UDS_NO_REBUILD ? LOAD_LOAD
|
|
Packit Service |
310c69 |
: LOAD_REBUILD;
|
|
Packit Service |
310c69 |
logNotice("%s: %s", getLoadType(loadType), name);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
result = initializeIndexSession(session, name, userParams, loadType);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
logErrorWithStringError(result, "Failed %s", getLoadType(loadType));
|
|
Packit Service |
310c69 |
saveAndFreeIndex(session);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
finishLoadingIndexSession(session, result);
|
|
Packit Service |
310c69 |
return sansUnrecoverable(result);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
const char *udsGetVersion(void)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
#ifdef UDS_VERSION
|
|
Packit Service |
310c69 |
return UDS_VERSION;
|
|
Packit Service |
310c69 |
#else
|
|
Packit Service |
310c69 |
return "internal version";
|
|
Packit Service |
310c69 |
#endif
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
const char *udsStringError(int errnum, char *buf, size_t buflen)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
if (buf == NULL) {
|
|
Packit Service |
310c69 |
return NULL;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
return stringError(errnum, buf, buflen);
|
|
Packit Service |
310c69 |
}
|