|
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/indexCheckpoint.c#2 $
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#include "indexCheckpoint.h"
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#include "errors.h"
|
|
Packit Service |
310c69 |
#include "logger.h"
|
|
Packit Service |
310c69 |
#include "memoryAlloc.h"
|
|
Packit Service |
310c69 |
#include "permassert.h"
|
|
Packit Service |
310c69 |
#include "threads.h"
|
|
Packit Service |
310c69 |
#include "typeDefs.h"
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* index checkpointState values
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @note The order of these values is significant,
|
|
Packit Service |
310c69 |
* see indexState.c doIndexStateCheckpointInZone().
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
typedef enum checkpointState {
|
|
Packit Service |
310c69 |
NOT_CHECKPOINTING,
|
|
Packit Service |
310c69 |
CHECKPOINT_IN_PROGRESS,
|
|
Packit Service |
310c69 |
CHECKPOINT_ABORTING
|
|
Packit Service |
310c69 |
} CheckpointState;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Private structure which tracks checkpointing.
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
struct indexCheckpoint {
|
|
Packit Service |
310c69 |
Mutex mutex; // covers this group of fields
|
|
Packit Service |
310c69 |
uint64_t chapter; // vcn of the starting chapter
|
|
Packit Service |
310c69 |
CheckpointState state; // is checkpoint in progress or aborting
|
|
Packit Service |
310c69 |
unsigned int zonesBusy; // count of zones not yet done
|
|
Packit Service |
310c69 |
unsigned int frequency; // number of chapters between checkpoints
|
|
Packit Service |
310c69 |
uint64_t checkpoints; // number of checkpoints this session
|
|
Packit Service |
310c69 |
};
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Enum return value of indexCheckpointTrigger function.
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
typedef enum indexCheckpointTriggerValue {
|
|
Packit Service |
310c69 |
ICTV_IDLE, //< no checkpointing right now
|
|
Packit Service |
310c69 |
ICTV_START, //< start a new checkpoint now
|
|
Packit Service |
310c69 |
ICTV_CONTINUE, //< continue checkpointing if needed
|
|
Packit Service |
310c69 |
ICTV_FINISH, //< finish checkpointing, next time will start new cycle
|
|
Packit Service |
310c69 |
ICTV_ABORT //< immediately abort checkpointing
|
|
Packit Service |
310c69 |
} IndexCheckpointTriggerValue;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
typedef int CheckpointFunction(Index *index, unsigned int zone);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
// These functions are called while holding the checkpoint->mutex but are
|
|
Packit Service |
310c69 |
// expected to release it.
|
|
Packit Service |
310c69 |
//
|
|
Packit Service |
310c69 |
static CheckpointFunction doCheckpointStart;
|
|
Packit Service |
310c69 |
static CheckpointFunction doCheckpointProcess;
|
|
Packit Service |
310c69 |
static CheckpointFunction doCheckpointFinish;
|
|
Packit Service |
310c69 |
static CheckpointFunction doCheckpointAbort;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
CheckpointFunction *const checkpointFuncs[] = {
|
|
Packit Service |
310c69 |
NULL,
|
|
Packit Service |
310c69 |
doCheckpointStart,
|
|
Packit Service |
310c69 |
doCheckpointProcess,
|
|
Packit Service |
310c69 |
doCheckpointFinish,
|
|
Packit Service |
310c69 |
doCheckpointAbort
|
|
Packit Service |
310c69 |
};
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
int makeIndexCheckpoint(Index *index)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
IndexCheckpoint *checkpoint;
|
|
Packit Service |
310c69 |
int result
|
|
Packit Service |
310c69 |
= ALLOCATE(1, IndexCheckpoint, "IndexCheckpoint", &checkpoint);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
result = initMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
FREE(checkpoint);
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
checkpoint->checkpoints = 0;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
index->checkpoint = checkpoint;
|
|
Packit Service |
310c69 |
return UDS_SUCCESS;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
void freeIndexCheckpoint(IndexCheckpoint *checkpoint)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
if (checkpoint != NULL) {
|
|
Packit Service |
310c69 |
destroyMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
FREE(checkpoint);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
unsigned int getIndexCheckpointFrequency(IndexCheckpoint *checkpoint)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
lockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
unsigned int frequency = checkpoint->frequency;
|
|
Packit Service |
310c69 |
unlockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
return frequency;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
unsigned int setIndexCheckpointFrequency(IndexCheckpoint *checkpoint,
|
|
Packit Service |
310c69 |
unsigned int frequency)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
lockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
unsigned int oldFrequency = checkpoint->frequency;
|
|
Packit Service |
310c69 |
checkpoint->frequency = frequency;
|
|
Packit Service |
310c69 |
unlockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
return oldFrequency;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
uint64_t getCheckpointCount(IndexCheckpoint *checkpoint)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return checkpoint->checkpoints;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static IndexCheckpointTriggerValue
|
|
Packit Service |
310c69 |
getCheckpointAction(IndexCheckpoint *checkpoint,
|
|
Packit Service |
310c69 |
uint64_t virtualChapter)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
if (checkpoint->frequency == 0) {
|
|
Packit Service |
310c69 |
return ICTV_IDLE;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
unsigned int value = virtualChapter % checkpoint->frequency;
|
|
Packit Service |
310c69 |
if (checkpoint->state == CHECKPOINT_ABORTING) {
|
|
Packit Service |
310c69 |
return ICTV_ABORT;
|
|
Packit Service |
310c69 |
} else if (checkpoint->state == CHECKPOINT_IN_PROGRESS) {
|
|
Packit Service |
310c69 |
if (value == checkpoint->frequency - 1) {
|
|
Packit Service |
310c69 |
return ICTV_FINISH;
|
|
Packit Service |
310c69 |
} else {
|
|
Packit Service |
310c69 |
return ICTV_CONTINUE;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
} else {
|
|
Packit Service |
310c69 |
if (value == 0) {
|
|
Packit Service |
310c69 |
return ICTV_START;
|
|
Packit Service |
310c69 |
} else {
|
|
Packit Service |
310c69 |
return ICTV_IDLE;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
int processCheckpointing(Index *index,
|
|
Packit Service |
310c69 |
unsigned int zone,
|
|
Packit Service |
310c69 |
uint64_t newVirtualChapter)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
IndexCheckpoint *checkpoint = index->checkpoint;
|
|
Packit Service |
310c69 |
lockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
IndexCheckpointTriggerValue ictv
|
|
Packit Service |
310c69 |
= getCheckpointAction(checkpoint, newVirtualChapter);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
if (ictv == ICTV_START) {
|
|
Packit Service |
310c69 |
checkpoint->chapter = newVirtualChapter;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
CheckpointFunction *func = checkpointFuncs[ictv];
|
|
Packit Service |
310c69 |
if (func == NULL) {
|
|
Packit Service |
310c69 |
// nothing to do in idle state
|
|
Packit Service |
310c69 |
unlockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
return UDS_SUCCESS;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
return (*func)(index, zone);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
int processChapterWriterCheckpointSaves(Index *index)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
IndexCheckpoint *checkpoint = index->checkpoint;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
int result = UDS_SUCCESS;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
lockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
if (checkpoint->state == CHECKPOINT_IN_PROGRESS) {
|
|
Packit Service |
310c69 |
result =
|
|
Packit Service |
310c69 |
performIndexStateCheckpointChapterSynchronizedSaves(index->state);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
checkpoint->state = CHECKPOINT_ABORTING;
|
|
Packit Service |
310c69 |
logInfo("checkpoint failed");
|
|
Packit Service |
310c69 |
index->lastCheckpoint = index->prevCheckpoint;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
unlockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Helper function used to abort checkpoint if an error has occurred.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param index the index
|
|
Packit Service |
310c69 |
* @param result the error result
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return result
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static int abortCheckpointing(Index *index, int result)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
if (index->checkpoint->state != NOT_CHECKPOINTING) {
|
|
Packit Service |
310c69 |
index->checkpoint->state = CHECKPOINT_ABORTING;
|
|
Packit Service |
310c69 |
logInfo("checkpoint failed");
|
|
Packit Service |
310c69 |
index->lastCheckpoint = index->prevCheckpoint;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
int finishCheckpointing(Index *index)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
IndexCheckpoint *checkpoint = index->checkpoint;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
int result = processChapterWriterCheckpointSaves(index);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
lockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
unsigned int z;
|
|
Packit Service |
310c69 |
for (z = 0; z < index->zoneCount; ++z) {
|
|
Packit Service |
310c69 |
if (checkpoint->state != CHECKPOINT_IN_PROGRESS) {
|
|
Packit Service |
310c69 |
break;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
result = doCheckpointFinish(index, z);
|
|
Packit Service |
310c69 |
// reacquire mutex released by doCheckpointFinish
|
|
Packit Service |
310c69 |
lockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
break;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
if ((result == UDS_SUCCESS) &&
|
|
Packit Service |
310c69 |
(checkpoint->state == CHECKPOINT_IN_PROGRESS)) {
|
|
Packit Service |
310c69 |
result = finishIndexStateCheckpoint(index->state);
|
|
Packit Service |
310c69 |
if (result == UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
checkpoint->state = NOT_CHECKPOINTING;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
unlockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Starts an incremental checkpoint.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* Called by the first zone to finish a chapter which starts a checkpoint.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param index the index
|
|
Packit Service |
310c69 |
* @param zone the zone number
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return UDS_SUCCESS or an error code
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static int doCheckpointStart(Index *index, unsigned int zone)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
IndexCheckpoint *checkpoint = index->checkpoint;
|
|
Packit Service |
310c69 |
beginSave(index, true, checkpoint->chapter);
|
|
Packit Service |
310c69 |
int result = startIndexStateCheckpoint(index->state);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
logErrorWithStringError(result, "cannot start index checkpoint");
|
|
Packit Service |
310c69 |
index->lastCheckpoint = index->prevCheckpoint;
|
|
Packit Service |
310c69 |
unlockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
checkpoint->state = CHECKPOINT_IN_PROGRESS;
|
|
Packit Service |
310c69 |
checkpoint->zonesBusy = index->zoneCount;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
return doCheckpointProcess(index, zone);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static int doCheckpointProcess(Index *index, unsigned int zone)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
IndexCheckpoint *checkpoint = index->checkpoint;
|
|
Packit Service |
310c69 |
unlockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
CompletionStatus status = CS_NOT_COMPLETED;
|
|
Packit Service |
310c69 |
int result = performIndexStateCheckpointInZone(index->state, zone, &status);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
lockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
logErrorWithStringError(result, "cannot continue index checkpoint");
|
|
Packit Service |
310c69 |
result = abortCheckpointing(index, result);
|
|
Packit Service |
310c69 |
unlockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
} else if (status == CS_JUST_COMPLETED) {
|
|
Packit Service |
310c69 |
lockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
if (--checkpoint->zonesBusy == 0) {
|
|
Packit Service |
310c69 |
checkpoint->checkpoints += 1;
|
|
Packit Service |
310c69 |
logInfo("finished checkpoint");
|
|
Packit Service |
310c69 |
result = finishIndexStateCheckpoint(index->state);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
logErrorWithStringError(result, "%s checkpoint finish failed",
|
|
Packit Service |
310c69 |
__func__);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
checkpoint->state = NOT_CHECKPOINTING;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
unlockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static int doCheckpointAbort(Index *index, unsigned int zone)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
IndexCheckpoint *checkpoint = index->checkpoint;
|
|
Packit Service |
310c69 |
CompletionStatus status = CS_NOT_COMPLETED;
|
|
Packit Service |
310c69 |
int result = abortIndexStateCheckpointInZone(index->state, zone, &status);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
logErrorWithStringError(result, "cannot abort index checkpoint");
|
|
Packit Service |
310c69 |
} else if (status == CS_JUST_COMPLETED) {
|
|
Packit Service |
310c69 |
if (--checkpoint->zonesBusy == 0) {
|
|
Packit Service |
310c69 |
logInfo("aborted checkpoint");
|
|
Packit Service |
310c69 |
result = abortIndexStateCheckpoint(index->state);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
logErrorWithStringError(result, "checkpoint abort failed");
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
checkpoint->state = NOT_CHECKPOINTING;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
unlockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static int doCheckpointFinish(Index *index, unsigned int zone)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
IndexCheckpoint *checkpoint = index->checkpoint;
|
|
Packit Service |
310c69 |
CompletionStatus status = CS_NOT_COMPLETED;
|
|
Packit Service |
310c69 |
unlockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
int result = finishIndexStateCheckpointInZone(index->state, zone, &status);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
logErrorWithStringError(result, "cannot finish index checkpoint");
|
|
Packit Service |
310c69 |
lockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
result = abortCheckpointing(index, result);
|
|
Packit Service |
310c69 |
unlockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
} else if (status == CS_JUST_COMPLETED) {
|
|
Packit Service |
310c69 |
lockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
if (--checkpoint->zonesBusy == 0) {
|
|
Packit Service |
310c69 |
checkpoint->checkpoints += 1;
|
|
Packit Service |
310c69 |
logInfo("finished checkpoint");
|
|
Packit Service |
310c69 |
result = finishIndexStateCheckpoint(index->state);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
logErrorWithStringError(result, "%s checkpoint finish failed",
|
|
Packit Service |
310c69 |
__func__);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
checkpoint->state = NOT_CHECKPOINTING;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
unlockMutex(&checkpoint->mutex);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|