1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-09-16 09:06:18 +02:00

Improvements in C codebase:

* Update C naming conventions.
* Use int datatype wherever possible.
* Better separation of C source from Perl interface.
This commit is contained in:
David Steele
2017-09-30 10:44:03 -04:00
parent d0bf946857
commit 8efcc38304
25 changed files with 427 additions and 314 deletions

View File

@@ -22,6 +22,11 @@ use pgBackRestBuild::CodeGen::Common;
use pgBackRestBuild::CodeGen::Truth;
use pgBackRestBuild::Config::Build;
####################################################################################################################################
# Define generator used for auto generated warning messages
####################################################################################################################################
use constant GENERATOR => 'Build.pm';
####################################################################################################################################
# buildAll - execute all build functions and generate C source code
####################################################################################################################################
@@ -112,7 +117,7 @@ sub buildAll
# Build general banner
#-------------------------------------------------------------------------------------------------------------------------------
my $strBanner = cgenBanner($rhFile->{&BLD_SUMMARY});
my $strBanner = cgenBanner($rhFile->{&BLD_SUMMARY}, GENERATOR);
# Build header file
#-------------------------------------------------------------------------------------------------------------------------------
@@ -130,7 +135,7 @@ sub buildAll
{
my $rhConstantGroup = $rhFileConstant->{$strConstantGroup};
$strHeader .= "\n" . cgenBanner($rhConstantGroup->{&BLD_SUMMARY} . ' constants');
$strHeader .= "\n" . cgenBanner($rhConstantGroup->{&BLD_SUMMARY} . ' constants', GENERATOR);
# Iterate constants
foreach my $strConstant (sort(keys(%{$rhConstantGroup->{&BLD_CONSTANT}})))

View File

@@ -21,8 +21,8 @@ use constant CGEN_DATATYPE_BOOL => 'bool';
push @EXPORT, qw(CGEN_DATATYPE_BOOL);
use constant CGEN_DATATYPE_DOUBLE => 'double';
push @EXPORT, qw(CGEN_DATATYPE_DOUBLE);
use constant CGEN_DATATYPE_INT32 => 'int32';
push @EXPORT, qw(CGEN_DATATYPE_INT32);
use constant CGEN_DATATYPE_INT => 'int';
push @EXPORT, qw(CGEN_DATATYPE_INT);
use constant CGEN_DATATYPE_INT64 => 'int64';
push @EXPORT, qw(CGEN_DATATYPE_INT64);
use constant CGEN_DATATYPE_CONSTCHAR => 'const char *';
@@ -31,16 +31,38 @@ use constant CGEN_DATATYPE_CONSTCHAR => 'const ch
use constant CGEN_DATAVAL_NULL => '^^{{[[NULL]]}}^^';
push @EXPORT, qw(CGEN_DATAVAL_NULL);
####################################################################################################################################
# cgenAutoWarning - warning not to modify automatically generated files directly
####################################################################################################################################
sub cgenAutoWarning
{
my $strGenerator = shift;
return "Automatically generated by ${strGenerator} -- do not modify directly.";
}
push @EXPORT, qw(cgenAutoWarning);
####################################################################################################################################
# cgenBanner - build general banner
####################################################################################################################################
sub cgenBanner
{
my $strContent = shift;
my $strGenerator = shift;
my $strBanner =
qw{/} . (qw{*} x 131) . "\n" .
trim($strContent) . "\n" .
trim($strContent) . "\n";
if (defined($strGenerator))
{
$strBanner .=
"# \n" .
'# ' . cgenAutoWarning($strGenerator) . "\n";
}
$strBanner .=
(qw{*} x 131) . qw{/} . "\n";
return $strBanner;
@@ -93,7 +115,7 @@ sub cgenTypeFormat
{
return ($strValue == 1 ? 'true' : 'false');
}
elsif ($strType eq CGEN_DATATYPE_INT32 || $strType eq CGEN_DATATYPE_INT64 || $strType eq CGEN_DATATYPE_DOUBLE)
elsif ($strType eq CGEN_DATATYPE_INT || $strType eq CGEN_DATATYPE_INT64 || $strType eq CGEN_DATATYPE_DOUBLE)
{
return $strValue;
}
@@ -118,9 +140,9 @@ sub cgenTypeName
{
return 'bool';
}
elsif ($strType eq CGEN_DATATYPE_INT32)
elsif ($strType eq CGEN_DATATYPE_INT)
{
return 'int32';
return 'int';
}
elsif ($strType eq CGEN_DATATYPE_INT64)
{

View File

@@ -26,9 +26,11 @@ sub cgenLookupString
my $rhValue = shift;
my $strFilter = shift;
my $strLowerName = lc($strName);
# Generate list of command strings
my $strFunction =
"const char *szy${strName}Name[${strTotal}] = \n" .
"const char *${strLowerName}NameList[${strTotal}] = \n" .
"{\n";
my $bFirst = true;
@@ -46,12 +48,12 @@ sub cgenLookupString
$strFunction .=
"const char *\n" .
"cfg${strName}Name(uint32 ui${strName}Id)\n" .
"cfg${strName}Name(int ${strLowerName}Id)\n" .
"{\n" .
" if (ui${strName}Id >= ${strTotal})\n" .
" if (${strLowerName}Id < 0 || ${strLowerName}Id >= ${strTotal})\n" .
" return NULL;\n" .
"\n" .
" return szy${strName}Name[ui${strName}Id];\n" .
" return ${strLowerName}NameList[${strLowerName}Id];\n" .
"}\n";
return $strFunction;
@@ -67,13 +69,15 @@ sub cgenLookupId
my $strName = shift;
my $strTotal = shift;
my $strLowerName = lc($strName);
my $strFunction =
"int32\n" .
"cfg${strName}Id(const char *sz${strName}Name)\n" .
"int\n" .
"cfg${strName}Id(const char *${strLowerName}Name)\n" .
"{\n" .
" for (uint32 uiIndex = 0; uiIndex < ${strTotal}; uiIndex++)\n" .
" if (strcmp(sz${strName}Name, cfg${strName}Name(uiIndex)) == 0)\n" .
" return uiIndex;\n" .
" for (int nameIdx = 0; nameIdx < ${strTotal}; nameIdx++)\n" .
" if (strcmp(${strLowerName}Name, cfg${strName}Name(nameIdx)) == 0)\n" .
" return nameIdx;\n" .
"\n" .
" return -1;\n" .
"}\n";

View File

@@ -95,7 +95,7 @@ sub cgenSwitchBuild
# Construct the function based on the best switch statement
return
cgenTypeName($strType) . "\n" .
"${strName}(uint32 " . join(', uint32 ', @{$rstryParam}) . ")\n" .
"${strName}(int " . join(', int ', @{$rstryParam}) . ")\n" .
"{\n" .
"${strBestSwitch}\n" .
"}\n";

View File

@@ -32,10 +32,10 @@ use pgBackRestBuild::Config::Rule;
use constant BLDLCL_FILE_CONFIG => 'config';
use constant BLDLCL_FILE_CONFIG_RULE => BLDLCL_FILE_CONFIG . 'Rule';
use constant BLDLCL_PARAM_OPTIONID => 'uiOptionId';
use constant BLDLCL_PARAM_COMMANDID => 'uiCommandId';
use constant BLDLCL_PARAM_OPTIONID => 'optionId';
use constant BLDLCL_PARAM_COMMANDID => 'commandId';
push @EXPORT, qw(BLDLCL_PARAM_COMMANDID);
use constant BLDLCL_PARAM_VALUEID => 'uiValueId';
use constant BLDLCL_PARAM_VALUEID => 'valueId';
use constant BLDLCL_CONSTANT_COMMAND => 'CFGCMDDEF';
use constant BLDLCL_CONSTANT_COMMAND_TOTAL => BLDLCL_CONSTANT_COMMAND . '_TOTAL';
@@ -181,7 +181,7 @@ my $rhBuild =
#---------------------------------------------------------------------------------------------------------------------------
&BLDLCL_FILE_CONFIG =>
{
&BLD_SUMMARY => 'Query Configuration Settings',
&BLD_SUMMARY => 'Command and Option Configuration',
&BLD_CONSTANT_GROUP =>
{
@@ -228,7 +228,7 @@ my $rhBuild =
&BLDLCL_FUNCTION_INDEX_TOTAL =>
{
&BLD_SUMMARY => 'total index values allowed',
&BLD_RETURN_TYPE => CGEN_DATATYPE_INT32,
&BLD_RETURN_TYPE => CGEN_DATATYPE_INT,
&BLD_PARAM => [BLDLCL_PARAM_OPTIONID],
&BLD_TRUTH_DEFAULT => 1,
&BLD_FUNCTION_DEPEND => BLDLCL_FUNCTION_VALID,
@@ -245,7 +245,7 @@ my $rhBuild =
#---------------------------------------------------------------------------------------------------------------------------
&BLDLCL_FILE_CONFIG_RULE =>
{
&BLD_SUMMARY => 'Parse Configuration Settings',
&BLD_SUMMARY => 'Command and Option Configuration Rules',
&BLD_FUNCTION =>
{
@@ -276,7 +276,7 @@ my $rhBuild =
&BLDLCL_FUNCTION_ALLOW_LIST_VALUE_TOTAL =>
{
&BLD_SUMMARY => 'total number of values allowed',
&BLD_RETURN_TYPE => CGEN_DATATYPE_INT32,
&BLD_RETURN_TYPE => CGEN_DATATYPE_INT,
&BLD_PARAM => [BLDLCL_PARAM_COMMANDID, BLDLCL_PARAM_OPTIONID],
&BLD_FUNCTION_DEPEND => BLDLCL_FUNCTION_ALLOW_LIST,
&BLD_FUNCTION_DEPEND_RESULT => true,
@@ -333,7 +333,7 @@ my $rhBuild =
&BLDLCL_FUNCTION_DEPEND_OPTION =>
{
&BLD_SUMMARY => 'name of the option that this option depends in order to be set',
&BLD_RETURN_TYPE => CGEN_DATATYPE_INT32,
&BLD_RETURN_TYPE => CGEN_DATATYPE_INT,
&BLD_PARAM => [BLDLCL_PARAM_COMMANDID, BLDLCL_PARAM_OPTIONID],
&BLD_RETURN_VALUE_MAP => $rhOptionIdConstantMap,
&BLD_FUNCTION_DEPEND => BLDLCL_FUNCTION_DEPEND,
@@ -352,7 +352,7 @@ my $rhBuild =
&BLDLCL_FUNCTION_DEPEND_VALUE_TOTAL =>
{
&BLD_SUMMARY => 'total depend values for this option',
&BLD_RETURN_TYPE => CGEN_DATATYPE_INT32,
&BLD_RETURN_TYPE => CGEN_DATATYPE_INT,
&BLD_PARAM => [BLDLCL_PARAM_COMMANDID, BLDLCL_PARAM_OPTIONID],
&BLD_FUNCTION_DEPEND => BLDLCL_FUNCTION_DEPEND,
&BLD_FUNCTION_DEPEND_RESULT => true,
@@ -428,7 +428,7 @@ my $rhBuild =
&BLDLCL_FUNCTION_TYPE =>
{
&BLD_SUMMARY => 'secure options can never be passed on the commmand-line',
&BLD_RETURN_TYPE => CGEN_DATATYPE_INT32,
&BLD_RETURN_TYPE => CGEN_DATATYPE_INT,
&BLD_PARAM => [BLDLCL_PARAM_OPTIONID],
&BLD_RETURN_VALUE_MAP => $rhOptionTypeIdConstantMap,
},

View File

@@ -10,6 +10,24 @@
</intro>
<release-list>
<release date="XXXX-XX-XX" version="1.25dev" title="UNDER DEVELOPMENT">
<release-core-list>
<release-refactor-list>
<release-item>
<p>Update C naming conventions.</p>
</release-item>
<release-item>
<p>Use <id>int</id> datatype wherever possible.</p>
</release-item>
<release-item>
<p>Better separation of C source from Perl interface.</p>
</release-item>
</release-refactor-list>
</release-core-list>
</release>
<release date="2017-09-28" version="1.24" title="New Backup Exclusions">
<release-core-list>
<release-bug-list>

View File

@@ -35,7 +35,7 @@ use constant BACKREST_BIN => abs_path(
# Defines the current version of the BackRest executable. The version number is used to track features but does not affect what
# repositories or manifests can be read - that's the job of the format number.
#-----------------------------------------------------------------------------------------------------------------------------------
use constant BACKREST_VERSION => '1.24';
use constant BACKREST_VERSION => '1.25dev';
push @EXPORT, qw(BACKREST_VERSION);
# Format Format Number

View File

@@ -1,9 +0,0 @@
#ifndef LIBC_H
#define LIBC_H
#include "common/type.h"
#include "config/config.h"
#include "config/configRule.h"
#include "postgres/pageChecksum.h"
#endif

View File

@@ -1,26 +1,57 @@
/***********************************************************************************************************************************
C to Perl Interface
The following C types are mapped by the current typemap:
'AV *', 'Boolean', 'CV *', 'FILE *', 'FileHandle', 'HV *', 'I16', 'I32', 'I8', 'IV', 'InOutStream', 'InputStream', 'NV',
'OutputStream', 'PerlIO *', 'Result', 'STRLEN', 'SV *', 'SVREF', 'SysRet', 'SysRetLong', 'Time_t *', 'U16', 'U32', 'U8', 'UV',
'bool', 'bool_t', 'caddr_t', 'char', 'char *', 'char **', 'const char *', 'double', 'float', 'int', 'long', 'short', 'size_t',
'ssize_t', 'time_t', 'unsigned', 'unsigned char', 'unsigned char *', 'unsigned int', 'unsigned long', 'unsigned long *',
'unsigned short', 'void *', 'wchar_t', 'wchar_t *'
***********************************************************************************************************************************/
#define PERL_NO_GET_CONTEXT
#include "LibC.h"
#include "XSUB.h"
/***********************************************************************************************************************************
Perl includes
Order is critical here so don't change it.
***********************************************************************************************************************************/
#include <XSUB.h>
#include <EXTERN.h>
#include <perl.h>
/***********************************************************************************************************************************
C includes
These includes are from the src directory. There is no Perl-specific code in them.
***********************************************************************************************************************************/
#include "common/type.h"
#include "config/config.h"
#include "config/configRule.h"
#include "postgres/pageChecksum.h"
/***********************************************************************************************************************************
Constant include
Auto generated code that handles exporting C constants to Perl.
***********************************************************************************************************************************/
#include "const-c.inc"
/*
* The following C types are mapped by the current typemap:
* 'AV *', 'Boolean', 'CV *', 'FILE *', 'FileHandle', 'HV *', 'I16', 'I32', 'I8', 'IV', 'InOutStream', 'InputStream', 'NV',
* 'OutputStream', 'PerlIO *', 'Result', 'STRLEN', 'SV *', 'SVREF', 'SysRet', 'SysRetLong', 'Time_t *', 'U16', 'U32', 'U8', 'UV',
* 'bool', 'bool_t', 'caddr_t', 'char', 'char *', 'char **', 'const char *', 'double', 'float', 'int', 'long', 'short', 'size_t',
* 'ssize_t', 'time_t', 'unsigned', 'unsigned char', 'unsigned char *', 'unsigned int', 'unsigned long', 'unsigned long *',
* 'unsigned short', 'void *', 'wchar_t', 'wchar_t *'
*/
/***********************************************************************************************************************************
Module definition
***********************************************************************************************************************************/
MODULE = pgBackRest::LibC PACKAGE = pgBackRest::LibC
PROTOTYPES: DISABLE
# Exported constants
#
# The XS portion of the code that handles exporting C constants to Perl.
# ----------------------------------------------------------------------------------------------------------------------------------
INCLUDE: const-xs.inc
# Exported functions and modules
#
# These modules should map 1-1 with C modules in src directory.
# ----------------------------------------------------------------------------------------------------------------------------------
INCLUDE: xs/config/config.xs
INCLUDE: xs/config/configRule.xs

View File

@@ -28,6 +28,7 @@ my $oStorage = new pgBackRest::Storage::Local(
####################################################################################################################################
# Build C files required for the library
####################################################################################################################################
use pgBackRestBuild::CodeGen::Common;
use pgBackRestBuild::Build;
my $rhBuild = buildAll($strBuildPath);
@@ -150,6 +151,11 @@ sub formatText
}
my $strLibC =
('#' x 132) . "\n" .
"# C to Perl Interface\n" .
"# \n" .
'# ' . cgenAutoWarning('Makefile.PL') . "\n" .
('#' x 132) . "\n" .
'package ' . BACKREST_NAME . '::' . LIB_NAME . ";\n" .
"\n" .
"use 5.010001;\n" .

View File

@@ -11,7 +11,7 @@ use Fcntl qw(O_RDONLY);
# Set number of tests
use Test::More tests => 56;
# Load the module dynamically so it does not interfere with the test above
# Load the module
use pgBackRest::LibC qw(:config :configRule);
# Config rule functions

View File

@@ -1,5 +1,5 @@
####################################################################################################################################
# pgBackRest-LibC.t - Unit tests for the LibC module
# Page Checksum Tests
####################################################################################################################################
use strict;
use warnings;
@@ -9,17 +9,10 @@ use English '-no_match_vars';
use Fcntl qw(O_RDONLY);
# Set number of tests
use Test::More tests => 11;
use Test::More tests => 9;
# Make sure the module loads without errors
BEGIN {use_ok('pgBackRest::LibC')};
# Load the module dynamically so it does not interfere with the test above
require pgBackRest::LibC;
pgBackRest::LibC->import(qw(:debug :checksum));
# UVSIZE determines the pointer and long long int size. This needs to be 8 to indicate 64-bit types are available.
ok (&UVSIZE == 8, 'UVSIZE == 8');
# Load the module
use pgBackRest::LibC qw(:checksum);
sub pageBuild
{
@@ -88,7 +81,7 @@ sub pageBuild
ok (pageChecksumBufferTest($tBufferMulti, length($tBufferMulti), 0, $iPageSize, 0xFFFF, 0xFFFF), 'pass valid page buffer');
# Make sure that an invalid buffer size throws an exception
# Make sure that an invalid buffer size throws an error
eval
{
pageChecksumBufferTest($tBufferMulti, length($tBufferMulti) - 1, 0, $iPageSize, 0xFFFF, 0xFFFF);

22
libc/t/sanity.t Normal file
View File

@@ -0,0 +1,22 @@
####################################################################################################################################
# Sanity Tests for C Library
#
# Basic test to ensure the C library loads and has been compiled correctly.
####################################################################################################################################
use strict;
use warnings;
use Carp;
use English '-no_match_vars';
# Set number of tests
use Test::More tests => 2;
# Make sure the module loads without errors
BEGIN {use_ok('pgBackRest::LibC')};
# Load the module dynamically so it does not interfere with the test above
require pgBackRest::LibC;
pgBackRest::LibC->import(qw(:debug));
# UVSIZE determines the pointer and long long int size. This needs to be 8 to indicate 64-bit types are available.
ok (&UVSIZE == 8, 'UVSIZE == 8');

View File

@@ -5,13 +5,13 @@
MODULE = pgBackRest::LibC PACKAGE = pgBackRest::LibC
const char *
cfgCommandName(uiCommandId)
U32 uiCommandId
cfgCommandName(commandId)
U32 commandId
I32
cfgOptionIndexTotal(uiOptionId)
U32 uiOptionId
cfgOptionIndexTotal(optionId)
U32 optionId
const char *
cfgOptionName(uiOptionId)
U32 uiOptionId
cfgOptionName(optionId)
U32 optionId

View File

@@ -5,123 +5,123 @@
MODULE = pgBackRest::LibC PACKAGE = pgBackRest::LibC
I32
cfgCommandId(szCommandName)
const char *szCommandName
cfgCommandId(commandName)
const char *commandName
I32
cfgOptionId(szOptionName)
const char *szOptionName
cfgOptionId(optionName)
const char *optionName
bool
cfgRuleOptionAllowList(uiCommandId, uiOptionId)
U32 uiCommandId
U32 uiOptionId
cfgRuleOptionAllowList(commandId, optionId)
U32 commandId
U32 optionId
const char *
cfgRuleOptionAllowListValue(uiCommandId, uiOptionId, uiValueId)
U32 uiCommandId
U32 uiOptionId
U32 uiValueId
cfgRuleOptionAllowListValue(commandId, optionId, valueId)
U32 commandId
U32 optionId
U32 valueId
I32
cfgRuleOptionAllowListValueTotal(uiCommandId, uiOptionId)
U32 uiCommandId
U32 uiOptionId
cfgRuleOptionAllowListValueTotal(commandId, optionId)
U32 commandId
U32 optionId
bool
cfgRuleOptionAllowListValueValid(uiCommandId, uiOptionId, szValue);
U32 uiCommandId
U32 uiOptionId
const char *szValue
cfgRuleOptionAllowListValueValid(commandId, optionId, value);
U32 commandId
U32 optionId
const char *value
bool
cfgRuleOptionAllowRange(uiCommandId, uiOptionId)
U32 uiCommandId
U32 uiOptionId
cfgRuleOptionAllowRange(commandId, optionId)
U32 commandId
U32 optionId
double
cfgRuleOptionAllowRangeMax(uiCommandId, uiOptionId)
U32 uiCommandId
U32 uiOptionId
cfgRuleOptionAllowRangeMax(commandId, optionId)
U32 commandId
U32 optionId
double
cfgRuleOptionAllowRangeMin(uiCommandId, uiOptionId)
U32 uiCommandId
U32 uiOptionId
cfgRuleOptionAllowRangeMin(commandId, optionId)
U32 commandId
U32 optionId
const char *
cfgRuleOptionDefault(uiCommandId, uiOptionId)
U32 uiCommandId
U32 uiOptionId
cfgRuleOptionDefault(commandId, optionId)
U32 commandId
U32 optionId
bool
cfgRuleOptionDepend(uiCommandId, uiOptionId);
U32 uiCommandId
U32 uiOptionId
cfgRuleOptionDepend(commandId, optionId);
U32 commandId
U32 optionId
I32
cfgRuleOptionDependOption(uiCommandId, uiOptionId)
U32 uiCommandId
U32 uiOptionId
cfgRuleOptionDependOption(commandId, optionId)
U32 commandId
U32 optionId
const char *
cfgRuleOptionDependValue(uiCommandId, uiOptionId, uiValueId)
U32 uiCommandId
U32 uiOptionId
U32 uiValueId
cfgRuleOptionDependValue(commandId, optionId, valueId)
U32 commandId
U32 optionId
U32 valueId
I32
cfgRuleOptionDependValueTotal(uiCommandId, uiOptionId)
U32 uiCommandId
U32 uiOptionId
cfgRuleOptionDependValueTotal(commandId, optionId)
U32 commandId
U32 optionId
bool
cfgRuleOptionDependValueValid(uiCommandId, uiOptionId, szValue)
U32 uiCommandId
U32 uiOptionId
const char *szValue
cfgRuleOptionDependValueValid(commandId, optionId, value)
U32 commandId
U32 optionId
const char *value
const char *
cfgRuleOptionHint(uiCommandId, uiOptionId)
U32 uiCommandId
U32 uiOptionId
cfgRuleOptionHint(commandId, optionId)
U32 commandId
U32 optionId
const char *
cfgRuleOptionNameAlt(uiOptionId)
U32 uiOptionId
cfgRuleOptionNameAlt(optionId)
U32 optionId
bool cfgRuleOptionNegate(uiOptionId)
U32 uiOptionId
bool cfgRuleOptionNegate(optionId)
U32 optionId
const char *
cfgRuleOptionPrefix(uiOptionId)
U32 uiOptionId
cfgRuleOptionPrefix(optionId)
U32 optionId
bool
cfgRuleOptionRequired(uiCommandId, uiOptionId)
U32 uiCommandId
U32 uiOptionId
cfgRuleOptionRequired(commandId, optionId)
U32 commandId
U32 optionId
const char *
cfgRuleOptionSection(uiOptionId)
U32 uiOptionId
cfgRuleOptionSection(optionId)
U32 optionId
bool
cfgRuleOptionSecure(uiOptionId)
U32 uiOptionId
cfgRuleOptionSecure(optionId)
U32 optionId
I32
cfgRuleOptionType(uiOptionId);
U32 uiOptionId
cfgRuleOptionType(optionId);
U32 optionId
bool
cfgRuleOptionValid(uiCommandId, uiOptionId)
U32 uiCommandId
U32 uiOptionId
cfgRuleOptionValid(commandId, optionId)
U32 commandId
U32 optionId
U32
cfgOptionTotal()
bool
cfgRuleOptionValueHash(uiOptionId)
U32 uiOptionId
cfgRuleOptionValueHash(optionId)
U32 optionId

View File

@@ -5,24 +5,39 @@
MODULE = pgBackRest::LibC PACKAGE = pgBackRest::LibC
U16
pageChecksum(page, blkno, pageSize)
pageChecksum(page, blockNo, pageSize)
const char *page
U32 blkno
U32 blockNo
U32 pageSize
CODE:
RETVAL = pageChecksum(
(const unsigned char *)page, blockNo, pageSize);
OUTPUT:
RETVAL
bool
pageChecksumTest(szPage, uiBlockNo, uiPageSize, uiIgnoreWalId, uiIgnoreWalOffset)
const char *szPage
U32 uiBlockNo
U32 uiPageSize
U32 uiIgnoreWalId
U32 uiIgnoreWalOffset
pageChecksumTest(page, blockNo, pageSize, ignoreWalId, ignoreWalOffset)
const char *page
U32 blockNo
U32 pageSize
U32 ignoreWalId
U32 ignoreWalOffset
CODE:
RETVAL = pageChecksumTest(
(const unsigned char *)page, blockNo, pageSize, ignoreWalId, ignoreWalOffset);
OUTPUT:
RETVAL
bool
pageChecksumBufferTest(szPageBuffer, uiBufferSize, uiBlockNoStart, uiPageSize, uiIgnoreWalId, uiIgnoreWalOffset)
const char *szPageBuffer
U32 uiBufferSize
U32 uiBlockNoStart
U32 uiPageSize
U32 uiIgnoreWalId
U32 uiIgnoreWalOffset
pageChecksumBufferTest(pageBuffer, pageBufferSize, blockNoBegin, pageSize, ignoreWalId, ignoreWalOffset)
const char *pageBuffer
U32 pageBufferSize
U32 blockNoBegin
U32 pageSize
U32 ignoreWalId
U32 ignoreWalOffset
CODE:
RETVAL = pageChecksumBufferTest(
(const unsigned char *)pageBuffer, pageBufferSize, blockNoBegin, pageSize, ignoreWalId, ignoreWalOffset);
OUTPUT:
RETVAL

View File

@@ -1,31 +1,30 @@
/***********************************************************************************************************************************
Common Types
***********************************************************************************************************************************/
#ifndef TYPE_H
#define TYPE_H
#include "EXTERN.h"
#include "perl.h"
/***********************************************************************************************************************************
Include true/false
***********************************************************************************************************************************/
#include <stdbool.h>
/***********************************************************************************************************************************
Older compilers do not define true/false
Include NULL
***********************************************************************************************************************************/
#ifndef false
#define false 0
#endif
#ifndef true
#define true 1
#endif
#include <stdio.h>
/***********************************************************************************************************************************
Define integer types based on Perl portability
Define standard integer types for portability
***********************************************************************************************************************************/
typedef U8 uint8; /* == 8 bits */
typedef U16 uint16; /* == 16 bits */
typedef U32 uint32; /* == 32 bits */
typedef UV uint64; /* == 64 bits */
#include <stdint.h>
typedef I8 int8; /* == 8 bits */
typedef I16 int16; /* == 16 bits */
typedef I32 int32; /* == 32 bits */
typedef IV int64; /* == 64 bits */
typedef uint16_t uint16;
typedef uint32_t uint32;
typedef uint64_t uint64;
typedef int16_t int16;
typedef int32_t int32;
typedef int64_t int64;
#endif

View File

@@ -1,4 +1,4 @@
# Query Configuration Settings
# Command and Option Configuration
## cfgOptionIndexTotal
@@ -8,8 +8,8 @@ Total index values allowed.
This function is valid when `cfgRuleOptionValid()` = `true`. Permutations that return `1` are excluded for brevity.
| Function | uiOptionId | Result |
| -------- | ---------- | ------ |
| Function | optionId | Result |
| -------- | -------- | ------ |
| cfgOptionIndexTotal | `CFGOPT_DB1_CMD` | `8` |
| cfgOptionIndexTotal | `CFGOPT_DB1_CONFIG` | `8` |
| cfgOptionIndexTotal | `CFGOPT_DB1_HOST` | `8` |

View File

@@ -1,7 +1,6 @@
/***********************************************************************************************************************************
Command and Option Rules
Command and Option Configuration
***********************************************************************************************************************************/
#include "LibC.h"
#include "config/config.h"
#include "config.auto.c"

View File

@@ -1,3 +1,6 @@
/***********************************************************************************************************************************
Command and Option Configuration
***********************************************************************************************************************************/
#ifndef CONFIG_H
#define CONFIG_H
@@ -7,8 +10,8 @@
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
const char *cfgCommandName(uint32 uiCommandId);
int32 cfgOptionIndexTotal(uint32 uiOptionId);
const char *cfgOptionName(uint32 uiCommandId);
const char *cfgCommandName(int commandId);
int cfgOptionIndexTotal(int optionId);
const char *cfgOptionName(int commandId);
#endif

View File

@@ -1,4 +1,4 @@
# Parse Configuration Settings
# Command and Option Configuration Rules
## cfgRuleOptionAllowList
@@ -8,8 +8,8 @@ Is there an allow list for this option?
This function is valid when `cfgRuleOptionValid()` = `true`. Permutations that return `false` are excluded for brevity.
| Function | uiCommandId | uiOptionId | Result |
| -------- | ----------- | ---------- | ------ |
| Function | commandId | optionId | Result |
| -------- | --------- | -------- | ------ |
| cfgRuleOptionAllowList | _\<ANY\>_ | `CFGOPT_BUFFER_SIZE` | `true` |
| cfgRuleOptionAllowList | _\<ANY\>_ | `CFGOPT_LOG_LEVEL_CONSOLE` | `true` |
| cfgRuleOptionAllowList | _\<ANY\>_ | `CFGOPT_LOG_LEVEL_FILE` | `true` |
@@ -28,8 +28,8 @@ Get value from allowed list.
This function is valid when `cfgRuleOptionAllowList()` = `true`.
| Function | uiCommandId | uiOptionId | uiValueId | Result |
| -------- | ----------- | ---------- | --------- | ------ |
| Function | commandId | optionId | valueId | Result |
| -------- | --------- | -------- | ------- | ------ |
| cfgRuleOptionAllowListValue | `CFGCMD_BACKUP` | `CFGOPT_TYPE` | `0` | `"full"` |
| cfgRuleOptionAllowListValue | `CFGCMD_BACKUP` | `CFGOPT_TYPE` | `1` | `"diff"` |
| cfgRuleOptionAllowListValue | `CFGCMD_BACKUP` | `CFGOPT_TYPE` | `2` | `"incr"` |
@@ -96,8 +96,8 @@ Total number of values allowed.
This function is valid when `cfgRuleOptionAllowList()` = `true`.
| Function | uiCommandId | uiOptionId | Result |
| -------- | ----------- | ---------- | ------ |
| Function | commandId | optionId | Result |
| -------- | --------- | -------- | ------ |
| cfgRuleOptionAllowListValueTotal | `CFGCMD_BACKUP` | `CFGOPT_TYPE` | `3` |
| cfgRuleOptionAllowListValueTotal | `CFGCMD_LOCAL` | `CFGOPT_TYPE` | `2` |
| cfgRuleOptionAllowListValueTotal | `CFGCMD_REMOTE` | `CFGOPT_TYPE` | `2` |
@@ -119,8 +119,8 @@ Is the option constrained to a range?
This function is valid when `cfgRuleOptionValid()` = `true`. Permutations that return `false` are excluded for brevity.
| Function | uiCommandId | uiOptionId | Result |
| -------- | ----------- | ---------- | ------ |
| Function | commandId | optionId | Result |
| -------- | --------- | -------- | ------ |
| cfgRuleOptionAllowRange | _\<ANY\>_ | `CFGOPT_ARCHIVE_TIMEOUT` | `true` |
| cfgRuleOptionAllowRange | _\<ANY\>_ | `CFGOPT_COMPRESS_LEVEL` | `true` |
| cfgRuleOptionAllowRange | _\<ANY\>_ | `CFGOPT_COMPRESS_LEVEL_NETWORK` | `true` |
@@ -139,8 +139,8 @@ Maximum value allowed (if the option is constrained to a range).
This function is valid when `cfgRuleOptionAllowRange()` = `true`.
| Function | uiCommandId | uiOptionId | Result |
| -------- | ----------- | ---------- | ------ |
| Function | commandId | optionId | Result |
| -------- | --------- | -------- | ------ |
| cfgRuleOptionAllowRangeMax | _\<ANY\>_ | `CFGOPT_ARCHIVE_TIMEOUT` | `86400` |
| cfgRuleOptionAllowRangeMax | _\<ANY\>_ | `CFGOPT_COMPRESS_LEVEL` | `9` |
| cfgRuleOptionAllowRangeMax | _\<ANY\>_ | `CFGOPT_COMPRESS_LEVEL_NETWORK` | `9` |
@@ -159,8 +159,8 @@ Minimum value allowed (if the option is constrained to a range).
This function is valid when `cfgRuleOptionAllowRange()` = `true`.
| Function | uiCommandId | uiOptionId | Result |
| -------- | ----------- | ---------- | ------ |
| Function | commandId | optionId | Result |
| -------- | --------- | -------- | ------ |
| cfgRuleOptionAllowRangeMin | _\<ANY\>_ | `CFGOPT_ARCHIVE_TIMEOUT` | `0.1` |
| cfgRuleOptionAllowRangeMin | _\<ANY\>_ | `CFGOPT_COMPRESS_LEVEL` | `0` |
| cfgRuleOptionAllowRangeMin | _\<ANY\>_ | `CFGOPT_COMPRESS_LEVEL_NETWORK` | `0` |
@@ -179,8 +179,8 @@ Default value.
This function is valid when `cfgRuleOptionValid()` = `true`. Permutations that return `NULL` are excluded for brevity.
| Function | uiCommandId | uiOptionId | Result |
| -------- | ----------- | ---------- | ------ |
| Function | commandId | optionId | Result |
| -------- | --------- | -------- | ------ |
| cfgRuleOptionDefault | `CFGCMD_BACKUP` | `CFGOPT_TYPE` | `"incr"` |
| cfgRuleOptionDefault | `CFGCMD_RESTORE` | `CFGOPT_TYPE` | `"default"` |
| cfgRuleOptionDefault | _\<ANY\>_ | `CFGOPT_ARCHIVE_ASYNC` | `"0"` |
@@ -259,8 +259,8 @@ Does the option have a dependency on another option?
This function is valid when `cfgRuleOptionValid()` = `true`. Permutations that return `false` are excluded for brevity.
| Function | uiCommandId | uiOptionId | Result |
| -------- | ----------- | ---------- | ------ |
| Function | commandId | optionId | Result |
| -------- | --------- | -------- | ------ |
| cfgRuleOptionDepend | `CFGCMD_BACKUP` | `CFGOPT_FORCE` | `true` |
| cfgRuleOptionDepend | _\<ANY\>_ | `CFGOPT_ARCHIVE_CHECK` | `true` |
| cfgRuleOptionDepend | _\<ANY\>_ | `CFGOPT_ARCHIVE_COPY` | `true` |
@@ -326,8 +326,8 @@ Name of the option that this option depends in order to be set.
This function is valid when `cfgRuleOptionDepend()` = `true`.
| Function | uiCommandId | uiOptionId | Result |
| -------- | ----------- | ---------- | ------ |
| Function | commandId | optionId | Result |
| -------- | --------- | -------- | ------ |
| cfgRuleOptionDependOption | _\<ANY\>_ | `CFGOPT_ARCHIVE_CHECK` | `CFGOPT_ONLINE` |
| cfgRuleOptionDependOption | _\<ANY\>_ | `CFGOPT_ARCHIVE_COPY` | `CFGOPT_ARCHIVE_CHECK` |
| cfgRuleOptionDependOption | _\<ANY\>_ | `CFGOPT_BACKUP_CMD` | `CFGOPT_BACKUP_HOST` |
@@ -393,8 +393,8 @@ The depend option must have one of these values before this option is set.
This function is valid when `cfgRuleOptionDepend()` = `true`.
| Function | uiCommandId | uiOptionId | uiValueId | Result |
| -------- | ----------- | ---------- | --------- | ------ |
| Function | commandId | optionId | valueId | Result |
| -------- | --------- | -------- | ------- | ------ |
| cfgRuleOptionDependValue | _\<ANY\>_ | `CFGOPT_ARCHIVE_CHECK` | `0` | `"1"` |
| cfgRuleOptionDependValue | _\<ANY\>_ | `CFGOPT_ARCHIVE_COPY` | `0` | `"1"` |
| cfgRuleOptionDependValue | _\<ANY\>_ | `CFGOPT_FORCE` | `0` | `"0"` |
@@ -435,8 +435,8 @@ Total depend values for this option.
This function is valid when `cfgRuleOptionDepend()` = `true`.
| Function | uiCommandId | uiOptionId | Result |
| -------- | ----------- | ---------- | ------ |
| Function | commandId | optionId | Result |
| -------- | --------- | -------- | ------ |
| cfgRuleOptionDependValueTotal | _\<ANY\>_ | `CFGOPT_ARCHIVE_CHECK` | `1` |
| cfgRuleOptionDependValueTotal | _\<ANY\>_ | `CFGOPT_ARCHIVE_COPY` | `1` |
| cfgRuleOptionDependValueTotal | _\<ANY\>_ | `CFGOPT_BACKUP_CMD` | `0` |
@@ -502,8 +502,8 @@ Some clue as to what value the user should provide when the option is missing bu
This function is valid when `cfgRuleOptionValid()` = `true`. Permutations that return `NULL` are excluded for brevity.
| Function | uiCommandId | uiOptionId | Result |
| -------- | ----------- | ---------- | ------ |
| Function | commandId | optionId | Result |
| -------- | --------- | -------- | ------ |
| cfgRuleOptionHint | _\<ANY\>_ | `CFGOPT_DB1_PATH` | `"does this stanza exist?"` |
| cfgRuleOptionHint | _\<ANY\>_ | `CFGOPT_DB2_PATH` | `"does this stanza exist?"` |
| cfgRuleOptionHint | _\<ANY\>_ | `CFGOPT_DB3_PATH` | `"does this stanza exist?"` |
@@ -521,8 +521,8 @@ Alternate name for the option primarily used for deprecated names.
This function is valid when `cfgRuleOptionValid()` = `true`. Permutations that return `NULL` are excluded for brevity.
| Function | uiOptionId | Result |
| -------- | ---------- | ------ |
| Function | optionId | Result |
| -------- | -------- | ------ |
| cfgRuleOptionNameAlt | `CFGOPT_DB1_CMD` | `"db-cmd"` |
| cfgRuleOptionNameAlt | `CFGOPT_DB1_CONFIG` | `"db-config"` |
| cfgRuleOptionNameAlt | `CFGOPT_DB1_HOST` | `"db-host"` |
@@ -541,8 +541,8 @@ Can the boolean option be negated?
Permutations that return `false` are excluded for brevity.
| Function | uiOptionId | Result |
| -------- | ---------- | ------ |
| Function | optionId | Result |
| -------- | -------- | ------ |
| cfgRuleOptionNegate | `CFGOPT_ARCHIVE_ASYNC` | `true` |
| cfgRuleOptionNegate | `CFGOPT_ARCHIVE_CHECK` | `true` |
| cfgRuleOptionNegate | `CFGOPT_ARCHIVE_COPY` | `true` |
@@ -568,8 +568,8 @@ Prefix when the option has an index > 1 (e.g. "db").
Permutations that return `NULL` are excluded for brevity.
| Function | uiOptionId | Result |
| -------- | ---------- | ------ |
| Function | optionId | Result |
| -------- | -------- | ------ |
| cfgRuleOptionPrefix | `CFGOPT_DB1_CMD` | `"db"` |
| cfgRuleOptionPrefix | `CFGOPT_DB1_CONFIG` | `"db"` |
| cfgRuleOptionPrefix | `CFGOPT_DB1_HOST` | `"db"` |
@@ -643,8 +643,8 @@ Is the option required?
This function is valid when `cfgRuleOptionValid()` = `true`. Permutations that return `false` are excluded for brevity.
| Function | uiCommandId | uiOptionId | Result |
| -------- | ----------- | ---------- | ------ |
| Function | commandId | optionId | Result |
| -------- | --------- | -------- | ------ |
| cfgRuleOptionRequired | `CFGCMD_ARCHIVE_GET` | `CFGOPT_STANZA` | `true` |
| cfgRuleOptionRequired | `CFGCMD_ARCHIVE_PUSH` | `CFGOPT_STANZA` | `true` |
| cfgRuleOptionRequired | `CFGCMD_BACKUP` | `CFGOPT_DB1_PATH` | `true` |
@@ -720,8 +720,8 @@ Section that the option belongs in, NULL means command-line only.
Permutations that return `NULL` are excluded for brevity.
| Function | uiOptionId | Result |
| -------- | ---------- | ------ |
| Function | optionId | Result |
| -------- | -------- | ------ |
| cfgRuleOptionSection | `CFGOPT_ARCHIVE_ASYNC` | `"global"` |
| cfgRuleOptionSection | `CFGOPT_ARCHIVE_CHECK` | `"global"` |
| cfgRuleOptionSection | `CFGOPT_ARCHIVE_COPY` | `"global"` |
@@ -850,8 +850,8 @@ Secure options can never be passed on the commmand-line.
Permutations that return `false` are excluded for brevity.
| Function | uiOptionId | Result |
| -------- | ---------- | ------ |
| Function | optionId | Result |
| -------- | -------- | ------ |
| cfgRuleOptionSecure | `CFGOPT_REPO_S3_KEY` | `true` |
| cfgRuleOptionSecure | `CFGOPT_REPO_S3_KEY_SECRET` | `true` |
@@ -861,8 +861,8 @@ Secure options can never be passed on the commmand-line.
### Truth Table:
| Function | uiOptionId | Result |
| -------- | ---------- | ------ |
| Function | optionId | Result |
| -------- | -------- | ------ |
| cfgRuleOptionType | `CFGOPT_ARCHIVE_ASYNC` | `CFGOPTDEF_TYPE_BOOLEAN` |
| cfgRuleOptionType | `CFGOPT_ARCHIVE_CHECK` | `CFGOPTDEF_TYPE_BOOLEAN` |
| cfgRuleOptionType | `CFGOPT_ARCHIVE_COPY` | `CFGOPTDEF_TYPE_BOOLEAN` |
@@ -1009,8 +1009,8 @@ Is the option valid for this command?
Permutations that return `false` are excluded for brevity.
| Function | uiCommandId | uiOptionId | Result |
| -------- | ----------- | ---------- | ------ |
| Function | commandId | optionId | Result |
| -------- | --------- | -------- | ------ |
| cfgRuleOptionValid | `CFGCMD_ARCHIVE_GET` | `CFGOPT_BACKUP_CMD` | `true` |
| cfgRuleOptionValid | `CFGCMD_ARCHIVE_GET` | `CFGOPT_BACKUP_CONFIG` | `true` |
| cfgRuleOptionValid | `CFGCMD_ARCHIVE_GET` | `CFGOPT_BACKUP_HOST` | `true` |
@@ -1924,8 +1924,8 @@ Is the option a true hash or just a list of keys?
Permutations that return `false` are excluded for brevity.
| Function | uiOptionId | Result |
| -------- | ---------- | ------ |
| Function | optionId | Result |
| -------- | -------- | ------ |
| cfgRuleOptionValueHash | `CFGOPT_LINK_MAP` | `true` |
| cfgRuleOptionValueHash | `CFGOPT_RECOVERY_OPTION` | `true` |
| cfgRuleOptionValueHash | `CFGOPT_TABLESPACE_MAP` | `true` |

View File

@@ -1,6 +1,8 @@
/***********************************************************************************************************************************
Command and Option Rules
Command and Option Configuration Rules
***********************************************************************************************************************************/
#include <string.h>
#include "config.h"
#include "configRule.h"
@@ -9,7 +11,7 @@ Command and Option Rules
/***********************************************************************************************************************************
cfgCommandTotal - total number of commands
***********************************************************************************************************************************/
uint32
int
cfgCommandTotal()
{
return CFGCMDDEF_TOTAL;
@@ -18,7 +20,7 @@ cfgCommandTotal()
/***********************************************************************************************************************************
cfgOptionTotal - total number of configuration options
***********************************************************************************************************************************/
uint32
int
cfgOptionTotal()
{
return CFGOPTDEF_TOTAL;
@@ -28,12 +30,12 @@ cfgOptionTotal()
cfgRuleOptionAllowListValueValid - check if the value matches a value in the allow list
***********************************************************************************************************************************/
bool
cfgRuleOptionAllowListValueValid(uint32 uiCommandId, uint32 uiOptionId, const char *szValue)
cfgRuleOptionAllowListValueValid(int commandId, int optionId, const char *value)
{
if (szValue != NULL)
if (value != NULL)
{
for (uint32 uiIndex = 0; uiIndex < cfgRuleOptionAllowListValueTotal(uiCommandId, uiOptionId); uiIndex++)
if (strcmp(szValue, cfgRuleOptionAllowListValue(uiCommandId, uiOptionId, uiIndex)) == 0)
for (int valueIdx = 0; valueIdx < cfgRuleOptionAllowListValueTotal(commandId, optionId); valueIdx++)
if (strcmp(value, cfgRuleOptionAllowListValue(commandId, optionId, valueIdx)) == 0)
return true;
}
@@ -44,12 +46,12 @@ cfgRuleOptionAllowListValueValid(uint32 uiCommandId, uint32 uiOptionId, const ch
cfgRuleOptionDependValueValid - check if the value matches a value in the allow list
***********************************************************************************************************************************/
bool
cfgRuleOptionDependValueValid(uint32 uiCommandId, uint32 uiOptionId, const char *szValue)
cfgRuleOptionDependValueValid(int commandId, int optionId, const char *value)
{
if (szValue != NULL)
if (value != NULL)
{
for (uint32 uiIndex = 0; uiIndex < cfgRuleOptionDependValueTotal(uiCommandId, uiOptionId); uiIndex++)
if (strcmp(szValue, cfgRuleOptionDependValue(uiCommandId, uiOptionId, uiIndex)) == 0)
for (int valueIdx = 0; valueIdx < cfgRuleOptionDependValueTotal(commandId, optionId); valueIdx++)
if (strcmp(value, cfgRuleOptionDependValue(commandId, optionId, valueIdx)) == 0)
return true;
}

View File

@@ -1,3 +1,6 @@
/***********************************************************************************************************************************
Command and Option Configuration Rules
***********************************************************************************************************************************/
#ifndef CONFIG_RULE_H
#define CONFIG_RULE_H
@@ -6,35 +9,35 @@
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
int32 cfgCommandId(const char *szCommandName);
int32 cfgOptionId(const char *szOptionName);
bool cfgRuleOptionAllowListValueValid(uint32 uiCommandId, uint32 uiOptionId, const char *szValue);
bool cfgRuleOptionDependValueValid(uint32 uiCommandId, uint32 uiOptionId, const char *szValue);
uint32 cfgOptionTotal();
int cfgCommandId(const char *commandName);
int cfgOptionId(const char *optionName);
bool cfgRuleOptionAllowListValueValid(int commandId, int optionId, const char *value);
bool cfgRuleOptionDependValueValid(int commandId, int optionId, const char *value);
int cfgOptionTotal();
/***********************************************************************************************************************************
Auto-Generated Functions
***********************************************************************************************************************************/
bool cfgRuleOptionAllowList(uint32 uiCommandId, uint32 uiOptionId);
const char * cfgRuleOptionAllowListValue(uint32 uiCommandId, uint32 uiOptionId, uint32 uiValueId);
int32 cfgRuleOptionAllowListValueTotal(uint32 uiCommandId, uint32 uiOptionId);
bool cfgRuleOptionAllowRange(uint32 uiCommandId, uint32 uiOptionId);
double cfgRuleOptionAllowRangeMax(uint32 uiCommandId, uint32 uiOptionId);
double cfgRuleOptionAllowRangeMin(uint32 uiCommandId, uint32 uiOptionId);
const char * cfgRuleOptionDefault(uint32 uiCommandId, uint32 uiOptionId);
bool cfgRuleOptionDepend(uint32 uiCommandId, uint32 uiOptionId);
int32 cfgRuleOptionDependOption(uint32 uiCommandId, uint32 uiOptionId);
const char *cfgRuleOptionDependValue(uint32 uiCommandId, uint32 uiOptionId, uint32 uiValueId);
int32 cfgRuleOptionDependValueTotal(uint32 uiCommandId, uint32 uiOptionId);
const char *cfgRuleOptionHint(uint32 uiCommandId, uint32 uiOptionId);
const char *cfgRuleOptionNameAlt(uint32 uiOptionId);
bool cfgRuleOptionNegate(uint32 uiOptionId);
const char *cfgRuleOptionPrefix(uint32 uiOptionId);
bool cfgRuleOptionRequired(uint32 uiCommandId, uint32 uiOptionId);
const char *cfgRuleOptionSection(uint32 uiOptionId);
bool cfgRuleOptionSecure(uint32 uiOptionId);
int32 cfgRuleOptionType(uint32 uiOptionId);
bool cfgRuleOptionValid(uint32 uiCommandId, uint32 uiOptionId);
bool cfgRuleOptionValueHash(uint32 uiOptionId);
bool cfgRuleOptionAllowList(int commandId, int optionId);
const char * cfgRuleOptionAllowListValue(int commandId, int optionId, int valueId);
int cfgRuleOptionAllowListValueTotal(int commandId, int optionId);
bool cfgRuleOptionAllowRange(int commandId, int optionId);
double cfgRuleOptionAllowRangeMax(int commandId, int optionId);
double cfgRuleOptionAllowRangeMin(int commandId, int optionId);
const char * cfgRuleOptionDefault(int commandId, int optionId);
bool cfgRuleOptionDepend(int commandId, int optionId);
int cfgRuleOptionDependOption(int commandId, int optionId);
const char *cfgRuleOptionDependValue(int commandId, int optionId, int valueId);
int cfgRuleOptionDependValueTotal(int commandId, int optionId);
const char *cfgRuleOptionHint(int commandId, int optionId);
const char *cfgRuleOptionNameAlt(int optionId);
bool cfgRuleOptionNegate(int optionId);
const char *cfgRuleOptionPrefix(int optionId);
bool cfgRuleOptionRequired(int commandId, int optionId);
const char *cfgRuleOptionSection(int optionId);
bool cfgRuleOptionSecure(int optionId);
int cfgRuleOptionType(int optionId);
bool cfgRuleOptionValid(int commandId, int optionId);
bool cfgRuleOptionValueHash(int optionId);
#endif

View File

@@ -1,7 +1,5 @@
/***********************************************************************************************************************************
pageChecksum.c
Checksum implementation for data pages.
Checksum Implementation for Data Pages
Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
Portions Copyright (c) 1994, Regents of the University of California
@@ -64,15 +62,20 @@ calculate a subset of the columns at a time and perform multiple passes to avoid
is not used. Current coding also assumes that the compiler has the ability to unroll the inner loop to avoid loop overhead and
minimize register spilling. For less sophisticated compilers it might be beneficial to manually unroll the inner loop.
***********************************************************************************************************************************/
#include "LibC.h"
#include "EXTERN.h"
#include "perl.h"
#include <string.h>
#include "common/type.h"
/***********************************************************************************************************************************
For historical reasons, the 64-bit LSN value is stored as two 32-bit values.
***********************************************************************************************************************************/
typedef struct
{
uint32 walid; /* high bits */
uint32 xrecoff; /* low bits */
uint32 walid; // high bits
uint32 xrecoff; // low bits
} PageWalRecPtr;
/***********************************************************************************************************************************
@@ -104,9 +107,9 @@ typedef struct PageHeaderData
typedef PageHeaderData *PageHeader;
/***********************************************************************************************************************************
pageChecksumBlock
pageChecksumBlock - block checksum algorithm
Block checksum algorithm. The data argument must be aligned on a 4-byte boundary.
The data argument must be aligned on a 4-byte boundary.
***********************************************************************************************************************************/
// number of checksums to calculate in parallel
#define N_SUMS 32
@@ -115,7 +118,7 @@ Block checksum algorithm. The data argument must be aligned on a 4-byte boundar
#define FNV_PRIME 16777619
// Base offsets to initialize each of the parallel FNV hashes into a different initial state.
static const uint32 uiyChecksumBaseOffsets[N_SUMS] =
static const uint32 checksumBaseOffsets[N_SUMS] =
{
0x5B1F36E9, 0xB8525960, 0x02AB50AA, 0x1DE66D2A, 0x79FF467A, 0x9BB9F8A3, 0x217E7CD2, 0x83E13D2C,
0xF8D4474F, 0xE39EB970, 0x42C6AE16, 0x993216FA, 0x7B093B5D, 0x98DAFF3C, 0xF718902A, 0x0B1C9CDB,
@@ -124,107 +127,101 @@ static const uint32 uiyChecksumBaseOffsets[N_SUMS] =
};
// Calculate one round of the checksum.
#define CHECKSUM_COMP(uiChecksum, uiValue) \
#define CHECKSUM_COMP(checksum, value) \
do { \
uint32 uiTemp = (uiChecksum) ^ (uiValue); \
(uiChecksum) = uiTemp * FNV_PRIME ^ (uiTemp >> 17); \
uint32 temp = (checksum) ^ (value); \
(checksum) = temp * FNV_PRIME ^ (temp >> 17); \
} while (0)
static uint32
pageChecksumBlock(const char *szData, uint32 uiSize)
pageChecksumBlock(const unsigned char *data, uint32 size)
{
uint32 uiySums[N_SUMS];
uint32 (*puiyDataArray)[N_SUMS] = (uint32 (*)[N_SUMS])szData;
uint32 uiResult = 0;
uint32 sums[N_SUMS];
uint32 (*dataArray)[N_SUMS] = (uint32 (*)[N_SUMS])data;
uint32 result = 0;
uint32 i, j;
/* initialize partial checksums to their corresponding offsets */
memcpy(uiySums, uiyChecksumBaseOffsets, sizeof(uiyChecksumBaseOffsets));
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets));
/* main checksum calculation */
for (i = 0; i < uiSize / sizeof(uint32) / N_SUMS; i++)
for (i = 0; i < size / sizeof(uint32) / N_SUMS; i++)
for (j = 0; j < N_SUMS; j++)
CHECKSUM_COMP(uiySums[j], puiyDataArray[i][j]);
CHECKSUM_COMP(sums[j], dataArray[i][j]);
/* finally add in two rounds of zeroes for additional mixing */
for (i = 0; i < 2; i++)
for (j = 0; j < N_SUMS; j++)
CHECKSUM_COMP(uiySums[j], 0);
CHECKSUM_COMP(sums[j], 0);
// xor fold partial checksums together
for (i = 0; i < N_SUMS; i++)
uiResult ^= uiySums[i];
result ^= sums[i];
return uiResult;
return result;
}
/***********************************************************************************************************************************
pageChecksum
Compute the checksum for a Postgres page. The page must be aligned on a 4-byte boundary.
pageChecksum - compute the checksum for a PostgreSQL page
The checksum includes the block number (to detect the case where a page is somehow moved to a different location), the page header
(excluding the checksum itself), and the page data.
***********************************************************************************************************************************/
uint16
pageChecksum(const char *szPage, uint32 uiBlockNo, uint32 uiPageSize)
pageChecksum(const unsigned char *page, int blockNo, int pageSize)
{
// Save pd_checksum and temporarily set it to zero, so that the checksum calculation isn't affected by the old checksum stored
// on the page. Restore it after, because actually updating the checksum is NOT part of the API of this function.
PageHeader pxPageHeader = (PageHeader)szPage;
PageHeader pageHeader = (PageHeader)page;
uint usOriginalChecksum = pxPageHeader->pd_checksum;
pxPageHeader->pd_checksum = 0;
uint uiChecksum = pageChecksumBlock(szPage, uiPageSize);
pxPageHeader->pd_checksum = usOriginalChecksum;
uint32 originalChecksum = pageHeader->pd_checksum;
pageHeader->pd_checksum = 0;
uint32 checksum = pageChecksumBlock(page, pageSize);
pageHeader->pd_checksum = originalChecksum;
// Mix in the block number to detect transposed pages
uiChecksum ^= uiBlockNo;
checksum ^= blockNo;
// Reduce to a uint16 with an offset of one. That avoids checksums of zero, which seems like a good idea.
return (uiChecksum % 65535) + 1;
return (checksum % 65535) + 1;
}
/***********************************************************************************************************************************
pageChecksumTest
Test if checksum is valid for a single page.
pageChecksumTest - test if checksum is valid for a single page
***********************************************************************************************************************************/
bool
pageChecksumTest(const char *szPage, uint32 uiBlockNo, uint32 uiPageSize, uint32 uiIgnoreWalId, uint32 uiIgnoreWalOffset)
pageChecksumTest(const unsigned char *page, int blockNo, int pageSize, uint32 ignoreWalId, uint32 ignoreWalOffset)
{
return
// This is a new page so don't test checksum
((PageHeader)szPage)->pd_upper == 0 ||
((PageHeader)page)->pd_upper == 0 ||
// LSN is after the backup started so checksum is not tested because pages may be torn
(((PageHeader)szPage)->pd_lsn.walid >= uiIgnoreWalId && ((PageHeader)szPage)->pd_lsn.xrecoff >= uiIgnoreWalOffset) ||
(((PageHeader)page)->pd_lsn.walid >= ignoreWalId && ((PageHeader)page)->pd_lsn.xrecoff >= ignoreWalOffset) ||
// Checksum is valid
((PageHeader)szPage)->pd_checksum == pageChecksum(szPage, uiBlockNo, uiPageSize);
((PageHeader)page)->pd_checksum == pageChecksum(page, blockNo, pageSize);
}
/***********************************************************************************************************************************
pageChecksumBufferTest
Test if checksums are valid for all pages in a buffer.
pageChecksumBufferTest - test if checksums are valid for all pages in a buffer
***********************************************************************************************************************************/
bool
pageChecksumBufferTest(
const char *szPageBuffer, uint32 uiBufferSize, uint32 uiBlockNoStart, uint32 uiPageSize, uint32 uiIgnoreWalId,
uint32 uiIgnoreWalOffset)
const unsigned char *pageBuffer, int pageBufferSize, int blockNoBegin, int pageSize, uint32 ignoreWalId,
uint32 ignoreWalOffset)
{
// If the buffer does not represent an even number of pages then error
if (uiBufferSize % uiPageSize != 0 || uiBufferSize / uiPageSize == 0)
if (pageBufferSize % pageSize != 0 || pageBufferSize / pageSize == 0)
{
croak("buffer size %lu, page size %lu are not divisible", uiBufferSize, uiPageSize);
croak("buffer size %lu, page size %lu are not divisible", pageBufferSize, pageSize);
}
// Loop through all pages in the buffer
for (uint32 uiIndex = 0; uiIndex < uiBufferSize / uiPageSize; uiIndex++)
for (int pageIdx = 0; pageIdx < pageBufferSize / pageSize; pageIdx++)
{
const char *szPage = szPageBuffer + (uiIndex * uiPageSize);
const unsigned char *page = pageBuffer + (pageIdx * pageSize);
// Return false if the checksums do not match
if (!pageChecksumTest(szPage, uiBlockNoStart + uiIndex, uiPageSize, uiIgnoreWalId, uiIgnoreWalOffset))
if (!pageChecksumTest(page, blockNoBegin + pageIdx, pageSize, ignoreWalId, ignoreWalOffset))
return false;
}

View File

@@ -1,3 +1,6 @@
/***********************************************************************************************************************************
Checksum Implementation for Data Pages
***********************************************************************************************************************************/
#ifndef PAGE_CHECKSUM_H
#define PAGE_CHECKSUM_H
@@ -6,10 +9,10 @@
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
uint16 pageChecksum(const char *szPage, uint32 uiBlockNo, uint32 uiPageSize);
bool pageChecksumTest(const char *szPage, uint32 uiBlockNo, uint32 uiPageSize, uint32 uiIgnoreWalId, uint32 uiIgnoreWalOffset);
uint16 pageChecksum(const unsigned char *page, int blockNo, int pageSize);
bool pageChecksumTest(const unsigned char *page, int blockNo, int pageSize, uint32 ignoreWalId, uint32 ignoreWalOffset);
bool pageChecksumBufferTest(
const char *szPageBuffer, uint32 uiBufferSize, uint32 uiBlockNoStart, uint32 uiPageSize, uint32 uiIgnoreWalId,
uint32 uiIgnoreWalOffset);
const unsigned char *pageBuffer, int pageBufferSize, int blockNoBegin, int pageSize, uint32 ignoreWalId,
uint32 ignoreWalOffset);
#endif