Blame source/uds/udsMain.c

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
}