You've already forked pgbackrest
							
							
				mirror of
				https://github.com/pgbackrest/pgbackrest.git
				synced 2025-10-30 23:37:45 +02:00 
			
		
		
		
	Improved lock implementation written in C.
Now only two types of locks can be taken: archive and backup. Most commands use one or the other but the stanza-* commands acquire both locks. This provides better protection than the old command-based locking scheme.
This commit is contained in:
		| @@ -38,7 +38,6 @@ use constant BLDLCL_DATA_OPTION                                     => '02-optio | ||||
| use constant BLDLCL_ENUM_COMMAND                                    => '01-enumCommand'; | ||||
| use constant BLDLCL_ENUM_OPTION                                     => '02-enumOption'; | ||||
|  | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # Definitions for constants and data to build | ||||
| #################################################################################################################################### | ||||
| @@ -147,6 +146,8 @@ sub buildConfig | ||||
|             "        CONFIG_COMMAND_LOG_LEVEL_DEFAULT(logLevel" . ucfirst(lc($rhCommand->{&CFGDEF_LOG_LEVEL_DEFAULT})) . ")\n" . | ||||
|             "        CONFIG_COMMAND_LOG_LEVEL_STDERR_MAX(logLevel" . | ||||
|                 ucfirst(lc($rhCommand->{&CFGDEF_LOG_LEVEL_STDERR_MAX})) . ")\n" . | ||||
|             "        CONFIG_COMMAND_LOCK_REQUIRED(" . ($rhCommand->{&CFGDEF_LOCK_REQUIRED} ? 'true' : 'false') . ")\n" . | ||||
|             "        CONFIG_COMMAND_LOCK_TYPE(lockType" . ucfirst(lc($rhCommand->{&CFGDEF_LOCK_TYPE})) . ")\n" . | ||||
|             "    )\n"; | ||||
|  | ||||
|         $iCommandTotal++; | ||||
|   | ||||
| @@ -453,6 +453,24 @@ use constant CFGDEF_LOG_LEVEL_DEFAULT                               => 'log-leve | ||||
| use constant CFGDEF_LOG_LEVEL_STDERR_MAX                            => 'log-level-stderr-max'; | ||||
|     push @EXPORT, qw(CFGDEF_LOG_LEVEL_STDERR_MAX); | ||||
|  | ||||
| # Does the command require a lock?  This doesn't mean a lock can't be taken explicitly later, just controls whether a lock will be | ||||
| # acquired as soon at the command starts. | ||||
| use constant CFGDEF_LOCK_REQUIRED                                   => 'lock-required'; | ||||
|     push @EXPORT, qw(CFGDEF_LOCK_REQUIRED); | ||||
|  | ||||
| # What type of lock is required? | ||||
| use constant CFGDEF_LOCK_TYPE                                       => 'lock-type'; | ||||
|     push @EXPORT, qw(CFGDEF_LOCK_TYPE); | ||||
|  | ||||
| use constant CFGDEF_LOCK_TYPE_ARCHIVE                               => 'archive'; | ||||
|     push @EXPORT, qw(CFGDEF_LOCK_TYPE_ARCHIVE); | ||||
| use constant CFGDEF_LOCK_TYPE_BACKUP                                => 'backup'; | ||||
|     push @EXPORT, qw(CFGDEF_LOCK_TYPE_BACKUP); | ||||
| use constant CFGDEF_LOCK_TYPE_ALL                                   => 'all'; | ||||
|     push @EXPORT, qw(CFGDEF_LOCK_TYPE_ALL); | ||||
| use constant CFGDEF_LOCK_TYPE_NONE                                  => 'none'; | ||||
|     push @EXPORT, qw(CFGDEF_LOCK_TYPE_NONE); | ||||
|  | ||||
| # Option defines | ||||
| #----------------------------------------------------------------------------------------------------------------------------------- | ||||
| use constant CFGDEF_ALLOW_LIST                                      => 'allow-list'; | ||||
| @@ -529,10 +547,13 @@ my $rhCommandDefine = | ||||
|     &CFGCMD_ARCHIVE_PUSH => | ||||
|     { | ||||
|         &CFGDEF_LOG_FILE => false, | ||||
|         &CFGDEF_LOCK_TYPE => CFGDEF_LOCK_TYPE_ARCHIVE, | ||||
|     }, | ||||
|  | ||||
|     &CFGCMD_BACKUP => | ||||
|     { | ||||
|         &CFGDEF_LOCK_REQUIRED => true, | ||||
|         &CFGDEF_LOCK_TYPE => CFGDEF_LOCK_TYPE_BACKUP, | ||||
|     }, | ||||
|  | ||||
|     &CFGCMD_CHECK => | ||||
| @@ -542,6 +563,8 @@ my $rhCommandDefine = | ||||
|  | ||||
|     &CFGCMD_EXPIRE => | ||||
|     { | ||||
|         &CFGDEF_LOCK_REQUIRED => true, | ||||
|         &CFGDEF_LOCK_TYPE => CFGDEF_LOCK_TYPE_BACKUP, | ||||
|     }, | ||||
|  | ||||
|     &CFGCMD_HELP => | ||||
| @@ -574,14 +597,20 @@ my $rhCommandDefine = | ||||
|  | ||||
|     &CFGCMD_STANZA_CREATE => | ||||
|     { | ||||
|         &CFGDEF_LOCK_REQUIRED => true, | ||||
|         &CFGDEF_LOCK_TYPE => CFGDEF_LOCK_TYPE_ALL, | ||||
|     }, | ||||
|  | ||||
|     &CFGCMD_STANZA_DELETE => | ||||
|     { | ||||
|         &CFGDEF_LOCK_REQUIRED => true, | ||||
|         &CFGDEF_LOCK_TYPE => CFGDEF_LOCK_TYPE_ALL, | ||||
|     }, | ||||
|  | ||||
|     &CFGCMD_STANZA_UPGRADE => | ||||
|     { | ||||
|         &CFGDEF_LOCK_REQUIRED => true, | ||||
|         &CFGDEF_LOCK_TYPE => CFGDEF_LOCK_TYPE_ALL, | ||||
|     }, | ||||
|  | ||||
|     &CFGCMD_START => | ||||
| @@ -2207,6 +2236,32 @@ foreach my $strCommand (sort(keys(%{$rhCommandDefine}))) | ||||
|     { | ||||
|         $rhCommandDefine->{$strCommand}{&CFGDEF_LOG_LEVEL_STDERR_MAX} = TRACE; | ||||
|     } | ||||
|  | ||||
|     # Default lock required is false | ||||
|     if (!defined($rhCommandDefine->{$strCommand}{&CFGDEF_LOCK_REQUIRED})) | ||||
|     { | ||||
|         $rhCommandDefine->{$strCommand}{&CFGDEF_LOCK_REQUIRED} = false; | ||||
|     } | ||||
|  | ||||
|     # Lock type must be set if a lock is required | ||||
|     if (!defined($rhCommandDefine->{$strCommand}{&CFGDEF_LOCK_TYPE})) | ||||
|     { | ||||
|         # Is a lock type required? | ||||
|         if ($rhCommandDefine->{$strCommand}{&CFGDEF_LOCK_REQUIRED}) | ||||
|         { | ||||
|             confess &log(ERROR, "lock type is required for command '${strCommand}'"); | ||||
|         } | ||||
|  | ||||
|         $rhCommandDefine->{$strCommand}{&CFGDEF_LOCK_TYPE} = CFGDEF_LOCK_TYPE_NONE; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if ($rhCommandDefine->{$strCommand}{&CFGDEF_LOCK_REQUIRED} && | ||||
|             $rhCommandDefine->{$strCommand}{&CFGDEF_LOCK_TYPE} eq CFGDEF_LOCK_TYPE_NONE) | ||||
|         { | ||||
|             confess &log(ERROR, "lock type is required for command '${strCommand}' and cannot be 'none'"); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #################################################################################################################################### | ||||
|   | ||||
| @@ -35,6 +35,10 @@ | ||||
|                         <p>Make <path>backup.history</path> sync more efficient.  Only the <path>backup.history/[year]</path> directory was being synced, so check if the <path>backup.history</path> is newly created and sync it as well.</p> | ||||
|                     </release-item> | ||||
|  | ||||
|                     <release-item> | ||||
|                         <p>Improved lock implementation written in C.  Now only two types of locks can be taken: <id>archive</id> and <id>backup</id>.  Most commands use one or the other but the <cmd>stanza-*</cmd> commands acquire both locks.  This provides better protection than the old command-based locking scheme.</p> | ||||
|                     </release-item> | ||||
|  | ||||
|                     <release-item> | ||||
|                         <p>Storage object improvements.  Convert all functions to variadic functions.  Enforce read-only storage. Add <code>storageLocalWrite()</code> helper function.  Add <code>storageExists()</code>, <code>storagePathCreate()</code>, and <code>storageRemove()</code>.  Add <code>StorageFile</code> object and <code>storageOpenRead()</code>/<code>storageOpenWrite()</code>.  Abstract Posix driver code into a separate module.  Add <code>storagePathRemove()</code> and use it in the Perl Posix driver.</p> | ||||
|                     </release-item> | ||||
|   | ||||
| @@ -28,6 +28,7 @@ use pgBackRest::Common::Wait; | ||||
| use pgBackRest::Config::Config; | ||||
| use pgBackRest::Db; | ||||
| use pgBackRest::DbVersion; | ||||
| use pgBackRest::LibC qw(:lock); | ||||
| use pgBackRest::Protocol::Local::Process; | ||||
| use pgBackRest::Protocol::Helper; | ||||
| use pgBackRest::Storage::Helper; | ||||
| @@ -81,14 +82,17 @@ sub process | ||||
|  | ||||
|     my $bClient = true; | ||||
|  | ||||
|     # Check if processes have been stopped | ||||
|     lockStopTest(); | ||||
|  | ||||
|     # This first lock request is a quick test to see if the async process is running.  If the lock is successful we need to release | ||||
|     # the lock, fork, and then let the async process acquire its own lock.  Otherwise the lock will be held by the client process | ||||
|     # which will soon exit and leave the async process unlocked. | ||||
|     if (lockAcquire(cfgCommandName(cfgCommandGet()), false)) | ||||
|     if (lockAcquire(cfgOption(CFGOPT_LOCK_PATH), cfgCommandName(cfgCommandGet()), cfgOption(CFGOPT_STANZA), 30, false)) | ||||
|     { | ||||
|         &log(TEST, TEST_ARCHIVE_PUSH_ASYNC_START); | ||||
|  | ||||
|         lockRelease(cfgCommandName(cfgCommandGet())); | ||||
|         lockRelease(true); | ||||
|         $bClient = fork() == 0 ? false : true; | ||||
|     } | ||||
|     else | ||||
| @@ -100,7 +104,7 @@ sub process | ||||
|     if (!$bClient) | ||||
|     { | ||||
|         # uncoverable branch false - reacquire the lock since it was released by the client process above | ||||
|         if (lockAcquire(cfgCommandName(cfgCommandGet()), false)) | ||||
|         if (lockAcquire(cfgOption(CFGOPT_LOCK_PATH), cfgCommandName(cfgCommandGet()), cfgOption(CFGOPT_STANZA), 30, false)) | ||||
|         { | ||||
|             # uncoverable branch true - chdir to / | ||||
|             chdir '/' | ||||
|   | ||||
| @@ -16,6 +16,7 @@ use pgBackRest::Common::Exception; | ||||
| use pgBackRest::Common::Lock; | ||||
| use pgBackRest::Common::Log; | ||||
| use pgBackRest::Config::Config; | ||||
| use pgBackRest::LibC qw(:lock); | ||||
| use pgBackRest::Protocol::Helper; | ||||
|  | ||||
| #################################################################################################################################### | ||||
|   | ||||
| @@ -19,28 +19,6 @@ use pgBackRest::Common::Wait; | ||||
| use pgBackRest::Config::Config; | ||||
| use pgBackRest::Storage::Helper; | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # Global lock type and handle | ||||
| #################################################################################################################################### | ||||
| my $strCurrentLockType; | ||||
| my $strCurrentLockFile; | ||||
| my $hCurrentLockHandle; | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # lockFileName | ||||
| # | ||||
| # Get the lock file name. | ||||
| #################################################################################################################################### | ||||
| sub lockFileName | ||||
| { | ||||
|     my $strLockType = shift; | ||||
|     my $strStanza = shift; | ||||
|     my $bRemote = shift; | ||||
|  | ||||
|     return cfgOption(CFGOPT_LOCK_PATH) . '/' . (defined($strStanza) ? $strStanza : 'global') . "_${strLockType}" . | ||||
|            (defined($bRemote) && $bRemote ? '_remote' : '') . '.lock'; | ||||
| } | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # lockPathCreate | ||||
| # | ||||
| @@ -51,140 +29,6 @@ sub lockPathCreate | ||||
|     storageLocal()->pathCreate(cfgOption(CFGOPT_LOCK_PATH), {strMode => '770', bIgnoreExists => true, bCreateParent => true}); | ||||
| } | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # lockAcquire | ||||
| # | ||||
| # Attempt to acquire the specified lock.  If the lock is taken by another process return false, else take the lock and return true. | ||||
| #################################################################################################################################### | ||||
| sub lockAcquire | ||||
| { | ||||
|     # Assign function parameters, defaults, and log debug info | ||||
|     my | ||||
|     ( | ||||
|         $strOperation, | ||||
|         $strLockType, | ||||
|         $bFailOnNoLock, | ||||
|         $bRemote, | ||||
|     ) = | ||||
|         logDebugParam | ||||
|         ( | ||||
|             __PACKAGE__ . '::lockAcquire', \@_, | ||||
|             {name => 'strLockType'}, | ||||
|             {name => 'bFailOnNoLock', default => true}, | ||||
|             {name => 'bRemote', default => false}, | ||||
|         ); | ||||
|  | ||||
|     my $bResult = false; | ||||
|  | ||||
|     # Cannot proceed if a lock is currently held | ||||
|     if (defined($strCurrentLockType)) | ||||
|     { | ||||
|         if (!defined($bFailOnNoLock) || $bFailOnNoLock) | ||||
|         { | ||||
|             confess &log(ASSERT, "${strCurrentLockType} lock is already held"); | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         # Check if processes are currently stopped | ||||
|         lockStopTest(); | ||||
|  | ||||
|         # Create the lock path | ||||
|         lockPathCreate(); | ||||
|  | ||||
|         # Loop until the lock can be acquired or timeout.  This is to prevent race conditions where another process is shutting down | ||||
|         # but has not yet released its lock. | ||||
|         $strCurrentLockFile = lockFileName($strLockType, cfgOption(CFGOPT_STANZA, false), $bRemote); | ||||
|         my $oWait = waitInit(!defined($bFailOnNoLock) || $bFailOnNoLock ? 30 : 0); | ||||
|  | ||||
|         do | ||||
|         { | ||||
|             # Attempt to open the lock file | ||||
|             next if !sysopen($hCurrentLockHandle, $strCurrentLockFile, O_WRONLY | O_CREAT, oct(640)); | ||||
|  | ||||
|             # Attempt to lock the lock file | ||||
|             if (!flock($hCurrentLockHandle, LOCK_EX | LOCK_NB)) | ||||
|             { | ||||
|                 close($hCurrentLockHandle); | ||||
|                 undef($hCurrentLockHandle); | ||||
|             } | ||||
|         } | ||||
|         while (!defined($hCurrentLockHandle) && defined($oWait) && waitMore($oWait)); | ||||
|  | ||||
|         # Attempt to lock the lock file | ||||
|         if (!defined($hCurrentLockHandle)) | ||||
|         { | ||||
|             if (!defined($bFailOnNoLock) || $bFailOnNoLock) | ||||
|             { | ||||
|                 confess &log(ERROR, "unable to acquire ${strLockType} lock on file ${strCurrentLockFile}", ERROR_LOCK_ACQUIRE); | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             # Write pid into the lock file.  This is used stop terminate processes on a stop --force. | ||||
|             syswrite($hCurrentLockHandle, "$$\n") | ||||
|                 or confess(ERROR, "unable to write process id into lock file ${strCurrentLockFile}", ERROR_FILE_WRITE); | ||||
|  | ||||
|             # Set current lock type so we know we have a lock | ||||
|             $strCurrentLockType = $strLockType; | ||||
|  | ||||
|             # Lock was successful | ||||
|             $bResult = true; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     # Return from function and log return values if any | ||||
|     return logDebugReturn | ||||
|     ( | ||||
|         $strOperation, | ||||
|         {name => 'bResult', value => $bResult} | ||||
|     ); | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(lockAcquire); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # lockRelease | ||||
| #################################################################################################################################### | ||||
| sub lockRelease | ||||
| { | ||||
|     # Assign function parameters, defaults, and log debug info | ||||
|     my | ||||
|     ( | ||||
|         $strOperation, | ||||
|         $bFailOnNoLock | ||||
|     ) = | ||||
|         logDebugParam | ||||
|         ( | ||||
|             __PACKAGE__ . '::lockRelease', \@_, | ||||
|             {name => 'bFailOnNoLock', default => true} | ||||
|         ); | ||||
|  | ||||
|     # Fail if there is no lock | ||||
|     if (!defined($strCurrentLockType)) | ||||
|     { | ||||
|         if ($bFailOnNoLock) | ||||
|         { | ||||
|             confess &log(ASSERT, 'no lock is currently held'); | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         # Remove the file | ||||
|         unlink($strCurrentLockFile); | ||||
|         close($hCurrentLockHandle); | ||||
|  | ||||
|         # Undef lock variables | ||||
|         undef($strCurrentLockType); | ||||
|         undef($hCurrentLockHandle); | ||||
|     } | ||||
|  | ||||
|     # Return from function and log return values if any | ||||
|     logDebugReturn($strOperation); | ||||
| } | ||||
|  | ||||
| push @EXPORT, qw(lockRelease); | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # lockStopFileName | ||||
| # | ||||
|   | ||||
| @@ -115,20 +115,8 @@ sub main | ||||
|             my $oRemote = new pgBackRest::Protocol::Remote::Minion( | ||||
|                 cfgOption(CFGOPT_BUFFER_SIZE), cfgOption(CFGOPT_PROTOCOL_TIMEOUT)); | ||||
|  | ||||
|             # Acquire a remote lock (except for commands that are read-only or local processes) | ||||
|             my $strLockName; | ||||
|  | ||||
|             if (!(cfgOptionTest(CFGOPT_COMMAND, cfgCommandName(CFGCMD_ARCHIVE_GET)) || | ||||
|                   cfgOptionTest(CFGOPT_COMMAND, cfgCommandName(CFGCMD_INFO)) || | ||||
|                   cfgOptionTest(CFGOPT_COMMAND, cfgCommandName(CFGCMD_RESTORE)) || | ||||
|                   cfgOptionTest(CFGOPT_COMMAND, cfgCommandName(CFGCMD_CHECK)) || | ||||
|                   cfgOptionTest(CFGOPT_COMMAND, cfgCommandName(CFGCMD_LOCAL)))) | ||||
|             { | ||||
|                 $strLockName = cfgOption(CFGOPT_COMMAND); | ||||
|             } | ||||
|  | ||||
|             # Process remote requests | ||||
|             exitSafe($oRemote->process($strLockName)); | ||||
|             exitSafe($oRemote->process(cfgOption(CFGOPT_LOCK_PATH), cfgOption(CFGOPT_COMMAND), cfgOption(CFGOPT_STANZA, false))); | ||||
|         } | ||||
|  | ||||
|         ############################################################################################################################ | ||||
| @@ -218,9 +206,9 @@ sub main | ||||
|         } | ||||
|  | ||||
|         ############################################################################################################################ | ||||
|         # Acquire the command lock | ||||
|         # Check if processes have been stopped | ||||
|         ############################################################################################################################ | ||||
|         lockAcquire(cfgCommandName(cfgCommandGet())); | ||||
|         lockStopTest(); | ||||
|  | ||||
|         ############################################################################################################################ | ||||
|         # Open the log file | ||||
| @@ -306,7 +294,7 @@ sub main | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         lockRelease(); | ||||
|         # Exit with success | ||||
|         exitSafe(0); | ||||
|  | ||||
|         # uncoverable statement - exit should happen above | ||||
|   | ||||
| @@ -17,6 +17,7 @@ use pgBackRest::Common::Ini; | ||||
| use pgBackRest::Common::Lock; | ||||
| use pgBackRest::Common::Log; | ||||
| use pgBackRest::Common::String; | ||||
| use pgBackRest::LibC qw(:lock); | ||||
| use pgBackRest::Protocol::Base::Master; | ||||
| use pgBackRest::Protocol::Helper; | ||||
| use pgBackRest::Version; | ||||
| @@ -134,7 +135,9 @@ sub cmdRead | ||||
| sub process | ||||
| { | ||||
|     my $self = shift; | ||||
|     my $strLockName = shift; | ||||
|     my $strLockPath = shift; | ||||
|     my $strLockCommand = shift; | ||||
|     my $strLockStanza = shift; | ||||
|  | ||||
|     # Reset stderr log level so random errors do not get output | ||||
|     logLevelSet(undef, undef, OFF); | ||||
| @@ -146,19 +149,24 @@ sub process | ||||
|     # Loop until the exit command is received | ||||
|     eval | ||||
|     { | ||||
|         # Aquire a lock if a lock name is defined.  This is done here so any errors will be transmitted through the protocol layer | ||||
|         # and cause a graceful shutdown rather than a remote abort. | ||||
|         if (defined($strLockName)) | ||||
|         # Aquire a lock if required (this will be determined by lockAcquire()).  This is done here so any errors will be transmitted | ||||
|         # through the protocol layer and cause a graceful shutdown rather than a remote abort. | ||||
|         if (defined($strLockPath) && defined($strLockStanza)) | ||||
|         { | ||||
|             eval | ||||
|             { | ||||
|                 lockAcquire($strLockName, undef, true); | ||||
|                 if (lockAcquire($strLockPath, $strLockCommand, $strLockStanza, 30, true)) | ||||
|                 { | ||||
|                     # Check if processes have been stopped | ||||
|                     lockStopTest(); | ||||
|                 } | ||||
|  | ||||
|                 return true; | ||||
|             } | ||||
|             or do | ||||
|             { | ||||
|                 $oPermanentError = $EVAL_ERROR; | ||||
|             } | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         while (true) | ||||
|   | ||||
| @@ -43,6 +43,7 @@ These includes are from the src directory.  There is no Perl-specific code in th | ||||
| ***********************************************************************************************************************************/ | ||||
| #include "cipher/random.h" | ||||
| #include "common/error.h" | ||||
| #include "common/lock.h" | ||||
| #include "config/config.h" | ||||
| #include "config/define.h" | ||||
| #include "config/load.h" | ||||
| @@ -99,6 +100,7 @@ INCLUDE: const-xs.inc | ||||
| INCLUDE: xs/cipher/block.xs | ||||
| INCLUDE: xs/cipher/random.xs | ||||
| INCLUDE: xs/common/encode.xs | ||||
| INCLUDE: xs/common/lock.xs | ||||
| INCLUDE: xs/config/config.xs | ||||
| INCLUDE: xs/config/configTest.xs | ||||
| INCLUDE: xs/config/define.xs | ||||
|   | ||||
| @@ -82,6 +82,8 @@ my @stryCFile = | ||||
|     'common/encode/base64.c', | ||||
|     'common/error.c', | ||||
|     'common/ini.c', | ||||
|     'common/io/handle.c', | ||||
|     'common/lock.c', | ||||
|     'common/log.c', | ||||
|     'common/memContext.c', | ||||
|     'common/regExp.c', | ||||
|   | ||||
| @@ -108,6 +108,14 @@ my $rhExport = | ||||
|         )], | ||||
|     }, | ||||
|  | ||||
|     'lock' => | ||||
|     { | ||||
|         &BLD_EXPORTTYPE_SUB => [qw( | ||||
|             lockAcquire | ||||
|             lockRelease | ||||
|         )], | ||||
|     }, | ||||
|  | ||||
|     'random' => | ||||
|     { | ||||
|         &BLD_EXPORTTYPE_SUB => [qw( | ||||
|   | ||||
| @@ -235,6 +235,12 @@ sub libcAutoExportTag | ||||
|             'encodeToStr', | ||||
|         ], | ||||
|  | ||||
|         lock => | ||||
|         [ | ||||
|             'lockAcquire', | ||||
|             'lockRelease', | ||||
|         ], | ||||
|  | ||||
|         random => | ||||
|         [ | ||||
|             'randomBytes', | ||||
|   | ||||
							
								
								
									
										44
									
								
								libc/xs/common/lock.xs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								libc/xs/common/lock.xs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| # ---------------------------------------------------------------------------------------------------------------------------------- | ||||
| # Lock Exports | ||||
| # ---------------------------------------------------------------------------------------------------------------------------------- | ||||
|  | ||||
| MODULE = pgBackRest::LibC PACKAGE = pgBackRest::LibC | ||||
|  | ||||
| #################################################################################################################################### | ||||
| bool | ||||
| lockAcquire(lockPath, command, stanza, lockTimeout, failOnNoLock) | ||||
|     const char *lockPath | ||||
|     const char *command | ||||
|     const char *stanza | ||||
|     double lockTimeout | ||||
|     bool failOnNoLock | ||||
| CODE: | ||||
|     RETVAL = false; | ||||
|  | ||||
|     MEM_CONTEXT_XS_TEMP_BEGIN() | ||||
|     { | ||||
|         // Set the command so we can get the correct lock type to use | ||||
|         cfgCommandSet(cfgCommandId(command)); | ||||
|  | ||||
|         // Attempt to acquire the lock | ||||
|         if (cfgLockType() != lockTypeNone) | ||||
|             RETVAL = lockAcquire(strNew(lockPath), strNew(stanza), cfgLockType(), lockTimeout, failOnNoLock); | ||||
|     } | ||||
|     MEM_CONTEXT_XS_TEMP_END(); | ||||
| OUTPUT: | ||||
|     RETVAL | ||||
|  | ||||
| #################################################################################################################################### | ||||
| bool | ||||
| lockRelease(failOnNoLock) | ||||
|     bool failOnNoLock | ||||
| CODE: | ||||
|     RETVAL = false; | ||||
|  | ||||
|     MEM_CONTEXT_XS_TEMP_BEGIN() | ||||
|     { | ||||
|         RETVAL = lockRelease(failOnNoLock); | ||||
|     } | ||||
|     MEM_CONTEXT_XS_TEMP_END(); | ||||
| OUTPUT: | ||||
|     RETVAL | ||||
| @@ -61,6 +61,7 @@ SRCS = \ | ||||
| 	common/exit.c \ | ||||
| 	common/io/handle.c \ | ||||
| 	common/ini.c \ | ||||
| 	common/lock.c \ | ||||
| 	common/log.c \ | ||||
| 	common/memContext.c \ | ||||
| 	common/regExp.c \ | ||||
|   | ||||
							
								
								
									
										222
									
								
								src/common/lock.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										222
									
								
								src/common/lock.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,222 @@ | ||||
| /*********************************************************************************************************************************** | ||||
| Lock Handler | ||||
| ***********************************************************************************************************************************/ | ||||
| #include <errno.h> | ||||
| #include <fcntl.h> | ||||
| #include <string.h> | ||||
| #include <sys/file.h> | ||||
| #include <unistd.h> | ||||
|  | ||||
| #include "common/assert.h" | ||||
| #include "common/io/handle.h" | ||||
| #include "common/lock.h" | ||||
| #include "common/memContext.h" | ||||
| #include "common/wait.h" | ||||
| #include "storage/helper.h" | ||||
| #include "version.h" | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Lock type names | ||||
| ***********************************************************************************************************************************/ | ||||
| static const char *lockTypeName[] = | ||||
| { | ||||
|     "archive",                                                      // lockTypeArchive | ||||
|     "backup",                                                       // lockTypeBackup | ||||
| }; | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Mem context and local variables | ||||
| ***********************************************************************************************************************************/ | ||||
| static MemContext *lockMemContext = NULL; | ||||
| static String *lockFile[lockTypeAll]; | ||||
| static int lockHandle[lockTypeAll]; | ||||
| static LockType lockTypeHeld = lockTypeNone; | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Acquire a lock using a file on the local filesystem | ||||
| ***********************************************************************************************************************************/ | ||||
| static int | ||||
| lockAcquireFile(const String *lockFile, double lockTimeout, bool failOnNoLock) | ||||
| { | ||||
|     int result = -1; | ||||
|  | ||||
|     // Timeout can't be negative | ||||
|     ASSERT_DEBUG(lockTimeout >= 0); | ||||
|  | ||||
|     MEM_CONTEXT_TEMP_BEGIN() | ||||
|     { | ||||
|         Wait *wait = lockTimeout != 0 ? waitNew(lockTimeout) : NULL; | ||||
|         bool retry = false; | ||||
|         int errNo = 0; | ||||
|  | ||||
|         do | ||||
|         { | ||||
|             // Attempt to open the file | ||||
|             if ((result = open(strPtr(lockFile), O_WRONLY | O_CREAT, STORAGE_FILE_MODE_DEFAULT)) == -1) | ||||
|             { | ||||
|                 // Save the error for reporting outside the loop | ||||
|                 errNo = errno; | ||||
|  | ||||
|                 // If the path does not exist then create it | ||||
|                 if (errNo == ENOENT) | ||||
|                 { | ||||
|                     storagePathCreateNP(storageLocalWrite(), strPath(lockFile)); | ||||
|                     retry = true; | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 // Attempt to lock the file | ||||
|                 if (flock(result, LOCK_EX | LOCK_NB) == -1) | ||||
|                 { | ||||
|                     // Save the error for reporting outside the loop | ||||
|                     errNo = errno; | ||||
|  | ||||
|                     // Close the file and reset the handle | ||||
|                     close(result); | ||||
|                     result = -1; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         while (result == -1 && ((wait != NULL && waitMore(wait)) || retry)); | ||||
|  | ||||
|         waitFree(wait); | ||||
|  | ||||
|         // If the lock was not successful | ||||
|         if (result == -1) | ||||
|         { | ||||
|             // Error when requested | ||||
|             if (failOnNoLock) | ||||
|             { | ||||
|                 String *errorHint = NULL; | ||||
|  | ||||
|                 if (errNo == EWOULDBLOCK) | ||||
|                     errorHint = strNew("\nHINT: is another " PGBACKREST_NAME " process running?"); | ||||
|                 else if (errNo == EACCES) | ||||
|                 { | ||||
|                     errorHint = strNewFmt( | ||||
|                         "\nHINT: does the user running " PGBACKREST_NAME " have permissions on the '%s' file?", | ||||
|                         strPtr(lockFile)); | ||||
|                 } | ||||
|  | ||||
|                 THROW( | ||||
|                     LockAcquireError, "unable to acquire lock on file '%s': %s%s", | ||||
|                     strPtr(lockFile), strerror(errNo), errorHint == NULL ? "" : strPtr(errorHint)); | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             // Write pid of the current process | ||||
|             ioHandleWriteOneStr(result, strNewFmt("%d\n", getpid())); | ||||
|         } | ||||
|     } | ||||
|     MEM_CONTEXT_TEMP_END(); | ||||
|  | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Release the current lock | ||||
| ***********************************************************************************************************************************/ | ||||
| static void | ||||
| lockReleaseFile(int lockHandle, const String *lockFile) | ||||
| { | ||||
|     // Can't release lock if there isn't one | ||||
|     ASSERT_DEBUG(lockHandle != -1); | ||||
|  | ||||
|     // Remove file first and then close it to release the lock.  If we close it first then another process might grab the lock | ||||
|     // right before the delete which means the file locked by the other process will get deleted. | ||||
|     storageRemoveNP(storageLocalWrite(), lockFile); | ||||
|     close(lockHandle); | ||||
| } | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Acquire a lock type | ||||
|  | ||||
| This will involve locking one or more files on disk depending on the lock type.  Most operations only take a single lock (archive or | ||||
| backup), but the stanza commands all need to lock both. | ||||
| ***********************************************************************************************************************************/ | ||||
| bool | ||||
| lockAcquire(const String *lockPath, const String *stanza, LockType lockType, double lockTimeout, bool failOnNoLock) | ||||
| { | ||||
|     bool result = false; | ||||
|  | ||||
|     // Don't allow failures when locking more than one file.  This makes cleanup difficult and there are no known use cases. | ||||
|     ASSERT_DEBUG(failOnNoLock || lockType != lockTypeAll); | ||||
|  | ||||
|     // Don't allow another lock if one is already held | ||||
|     if (lockTypeHeld != lockTypeNone) | ||||
|         THROW(AssertError, "lock is already held by this process"); | ||||
|  | ||||
|     // Allocate a mem context to hold lock filenames if one does not already exist | ||||
|     if (lockMemContext == NULL) | ||||
|     { | ||||
|         MEM_CONTEXT_BEGIN(memContextTop()) | ||||
|         { | ||||
|             lockMemContext = memContextNew("Lock"); | ||||
|         } | ||||
|         MEM_CONTEXT_END(); | ||||
|     } | ||||
|  | ||||
|     // Lock files | ||||
|     MEM_CONTEXT_BEGIN(lockMemContext) | ||||
|     { | ||||
|         LockType lockMin = lockType == lockTypeAll ? lockTypeArchive : lockType; | ||||
|         LockType lockMax = lockType == lockTypeAll ? (lockTypeAll - 1) : lockType; | ||||
|         bool error = false; | ||||
|  | ||||
|         for (LockType lockIdx = lockMin; lockIdx <= lockMax; lockIdx++) | ||||
|         { | ||||
|             lockFile[lockIdx] = strNewFmt("%s/%s-%s.lock", strPtr(lockPath), strPtr(stanza), lockTypeName[lockIdx]); | ||||
|  | ||||
|             lockHandle[lockIdx] = lockAcquireFile(lockFile[lockIdx], lockTimeout, failOnNoLock); | ||||
|  | ||||
|             if (lockHandle[lockIdx] == -1) | ||||
|             { | ||||
|                 error = true; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (!error) | ||||
|         { | ||||
|             lockTypeHeld = lockType; | ||||
|             result = true; | ||||
|         } | ||||
|     } | ||||
|     MEM_CONTEXT_END(); | ||||
|  | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Release a lock type | ||||
| ***********************************************************************************************************************************/ | ||||
| bool | ||||
| lockRelease(bool failOnNoLock) | ||||
| { | ||||
|     bool result = false; | ||||
|  | ||||
|     if (lockTypeHeld == lockTypeNone) | ||||
|     { | ||||
|         if (failOnNoLock) | ||||
|             THROW(AssertError, "no lock is held by this process"); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         // Release locks | ||||
|         LockType lockMin = lockTypeHeld == lockTypeAll ? lockTypeArchive : lockTypeHeld; | ||||
|         LockType lockMax = lockTypeHeld == lockTypeAll ? (lockTypeAll - 1) : lockTypeHeld; | ||||
|  | ||||
|         for (LockType lockIdx = lockMin; lockIdx <= lockMax; lockIdx++) | ||||
|         { | ||||
|             lockReleaseFile(lockHandle[lockIdx], lockFile[lockIdx]); | ||||
|             strFree(lockFile[lockIdx]); | ||||
|         } | ||||
|  | ||||
|         lockTypeHeld = lockTypeNone; | ||||
|         result = true; | ||||
|     } | ||||
|  | ||||
|     return result; | ||||
| } | ||||
							
								
								
									
										26
									
								
								src/common/lock.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/common/lock.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| /*********************************************************************************************************************************** | ||||
| Lock Handler | ||||
| ***********************************************************************************************************************************/ | ||||
| #ifndef COMMON_LOCK_H | ||||
| #define COMMON_LOCK_H | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Lock types | ||||
| ***********************************************************************************************************************************/ | ||||
| typedef enum | ||||
| { | ||||
|     lockTypeArchive, | ||||
|     lockTypeBackup, | ||||
|     lockTypeAll, | ||||
|     lockTypeNone, | ||||
| } LockType; | ||||
|  | ||||
| #include "common/type/string.h" | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Functions | ||||
| ***********************************************************************************************************************************/ | ||||
| bool lockAcquire(const String *lockPath, const String *stanza, LockType lockType, double lockTimeout, bool failOnNoLock); | ||||
| bool lockRelease(bool failOnNoLock); | ||||
|  | ||||
| #endif | ||||
| @@ -16,6 +16,8 @@ static ConfigCommandData configCommandData[CFG_COMMAND_TOTAL] = CONFIG_COMMAND_L | ||||
|         CONFIG_COMMAND_LOG_FILE(false) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_DEFAULT(logLevelInfo) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_STDERR_MAX(logLevelTrace) | ||||
|         CONFIG_COMMAND_LOCK_REQUIRED(false) | ||||
|         CONFIG_COMMAND_LOCK_TYPE(lockTypeNone) | ||||
|     ) | ||||
|  | ||||
|     CONFIG_COMMAND | ||||
| @@ -25,6 +27,8 @@ static ConfigCommandData configCommandData[CFG_COMMAND_TOTAL] = CONFIG_COMMAND_L | ||||
|         CONFIG_COMMAND_LOG_FILE(false) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_DEFAULT(logLevelInfo) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_STDERR_MAX(logLevelTrace) | ||||
|         CONFIG_COMMAND_LOCK_REQUIRED(false) | ||||
|         CONFIG_COMMAND_LOCK_TYPE(lockTypeArchive) | ||||
|     ) | ||||
|  | ||||
|     CONFIG_COMMAND | ||||
| @@ -34,6 +38,8 @@ static ConfigCommandData configCommandData[CFG_COMMAND_TOTAL] = CONFIG_COMMAND_L | ||||
|         CONFIG_COMMAND_LOG_FILE(true) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_DEFAULT(logLevelInfo) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_STDERR_MAX(logLevelTrace) | ||||
|         CONFIG_COMMAND_LOCK_REQUIRED(true) | ||||
|         CONFIG_COMMAND_LOCK_TYPE(lockTypeBackup) | ||||
|     ) | ||||
|  | ||||
|     CONFIG_COMMAND | ||||
| @@ -43,6 +49,8 @@ static ConfigCommandData configCommandData[CFG_COMMAND_TOTAL] = CONFIG_COMMAND_L | ||||
|         CONFIG_COMMAND_LOG_FILE(false) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_DEFAULT(logLevelInfo) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_STDERR_MAX(logLevelTrace) | ||||
|         CONFIG_COMMAND_LOCK_REQUIRED(false) | ||||
|         CONFIG_COMMAND_LOCK_TYPE(lockTypeNone) | ||||
|     ) | ||||
|  | ||||
|     CONFIG_COMMAND | ||||
| @@ -52,6 +60,8 @@ static ConfigCommandData configCommandData[CFG_COMMAND_TOTAL] = CONFIG_COMMAND_L | ||||
|         CONFIG_COMMAND_LOG_FILE(true) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_DEFAULT(logLevelInfo) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_STDERR_MAX(logLevelTrace) | ||||
|         CONFIG_COMMAND_LOCK_REQUIRED(true) | ||||
|         CONFIG_COMMAND_LOCK_TYPE(lockTypeBackup) | ||||
|     ) | ||||
|  | ||||
|     CONFIG_COMMAND | ||||
| @@ -61,6 +71,8 @@ static ConfigCommandData configCommandData[CFG_COMMAND_TOTAL] = CONFIG_COMMAND_L | ||||
|         CONFIG_COMMAND_LOG_FILE(false) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_DEFAULT(logLevelDebug) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_STDERR_MAX(logLevelTrace) | ||||
|         CONFIG_COMMAND_LOCK_REQUIRED(false) | ||||
|         CONFIG_COMMAND_LOCK_TYPE(lockTypeNone) | ||||
|     ) | ||||
|  | ||||
|     CONFIG_COMMAND | ||||
| @@ -70,6 +82,8 @@ static ConfigCommandData configCommandData[CFG_COMMAND_TOTAL] = CONFIG_COMMAND_L | ||||
|         CONFIG_COMMAND_LOG_FILE(false) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_DEFAULT(logLevelDebug) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_STDERR_MAX(logLevelTrace) | ||||
|         CONFIG_COMMAND_LOCK_REQUIRED(false) | ||||
|         CONFIG_COMMAND_LOCK_TYPE(lockTypeNone) | ||||
|     ) | ||||
|  | ||||
|     CONFIG_COMMAND | ||||
| @@ -79,6 +93,8 @@ static ConfigCommandData configCommandData[CFG_COMMAND_TOTAL] = CONFIG_COMMAND_L | ||||
|         CONFIG_COMMAND_LOG_FILE(false) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_DEFAULT(logLevelInfo) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_STDERR_MAX(logLevelError) | ||||
|         CONFIG_COMMAND_LOCK_REQUIRED(false) | ||||
|         CONFIG_COMMAND_LOCK_TYPE(lockTypeNone) | ||||
|     ) | ||||
|  | ||||
|     CONFIG_COMMAND | ||||
| @@ -88,6 +104,8 @@ static ConfigCommandData configCommandData[CFG_COMMAND_TOTAL] = CONFIG_COMMAND_L | ||||
|         CONFIG_COMMAND_LOG_FILE(false) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_DEFAULT(logLevelInfo) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_STDERR_MAX(logLevelError) | ||||
|         CONFIG_COMMAND_LOCK_REQUIRED(false) | ||||
|         CONFIG_COMMAND_LOCK_TYPE(lockTypeNone) | ||||
|     ) | ||||
|  | ||||
|     CONFIG_COMMAND | ||||
| @@ -97,6 +115,8 @@ static ConfigCommandData configCommandData[CFG_COMMAND_TOTAL] = CONFIG_COMMAND_L | ||||
|         CONFIG_COMMAND_LOG_FILE(true) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_DEFAULT(logLevelInfo) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_STDERR_MAX(logLevelTrace) | ||||
|         CONFIG_COMMAND_LOCK_REQUIRED(false) | ||||
|         CONFIG_COMMAND_LOCK_TYPE(lockTypeNone) | ||||
|     ) | ||||
|  | ||||
|     CONFIG_COMMAND | ||||
| @@ -106,6 +126,8 @@ static ConfigCommandData configCommandData[CFG_COMMAND_TOTAL] = CONFIG_COMMAND_L | ||||
|         CONFIG_COMMAND_LOG_FILE(true) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_DEFAULT(logLevelInfo) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_STDERR_MAX(logLevelTrace) | ||||
|         CONFIG_COMMAND_LOCK_REQUIRED(true) | ||||
|         CONFIG_COMMAND_LOCK_TYPE(lockTypeAll) | ||||
|     ) | ||||
|  | ||||
|     CONFIG_COMMAND | ||||
| @@ -115,6 +137,8 @@ static ConfigCommandData configCommandData[CFG_COMMAND_TOTAL] = CONFIG_COMMAND_L | ||||
|         CONFIG_COMMAND_LOG_FILE(true) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_DEFAULT(logLevelInfo) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_STDERR_MAX(logLevelTrace) | ||||
|         CONFIG_COMMAND_LOCK_REQUIRED(true) | ||||
|         CONFIG_COMMAND_LOCK_TYPE(lockTypeAll) | ||||
|     ) | ||||
|  | ||||
|     CONFIG_COMMAND | ||||
| @@ -124,6 +148,8 @@ static ConfigCommandData configCommandData[CFG_COMMAND_TOTAL] = CONFIG_COMMAND_L | ||||
|         CONFIG_COMMAND_LOG_FILE(true) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_DEFAULT(logLevelInfo) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_STDERR_MAX(logLevelTrace) | ||||
|         CONFIG_COMMAND_LOCK_REQUIRED(true) | ||||
|         CONFIG_COMMAND_LOCK_TYPE(lockTypeAll) | ||||
|     ) | ||||
|  | ||||
|     CONFIG_COMMAND | ||||
| @@ -133,6 +159,8 @@ static ConfigCommandData configCommandData[CFG_COMMAND_TOTAL] = CONFIG_COMMAND_L | ||||
|         CONFIG_COMMAND_LOG_FILE(true) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_DEFAULT(logLevelInfo) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_STDERR_MAX(logLevelTrace) | ||||
|         CONFIG_COMMAND_LOCK_REQUIRED(false) | ||||
|         CONFIG_COMMAND_LOCK_TYPE(lockTypeNone) | ||||
|     ) | ||||
|  | ||||
|     CONFIG_COMMAND | ||||
| @@ -142,6 +170,8 @@ static ConfigCommandData configCommandData[CFG_COMMAND_TOTAL] = CONFIG_COMMAND_L | ||||
|         CONFIG_COMMAND_LOG_FILE(true) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_DEFAULT(logLevelInfo) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_STDERR_MAX(logLevelTrace) | ||||
|         CONFIG_COMMAND_LOCK_REQUIRED(false) | ||||
|         CONFIG_COMMAND_LOCK_TYPE(lockTypeNone) | ||||
|     ) | ||||
|  | ||||
|     CONFIG_COMMAND | ||||
| @@ -151,6 +181,8 @@ static ConfigCommandData configCommandData[CFG_COMMAND_TOTAL] = CONFIG_COMMAND_L | ||||
|         CONFIG_COMMAND_LOG_FILE(false) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_DEFAULT(logLevelDebug) | ||||
|         CONFIG_COMMAND_LOG_LEVEL_STDERR_MAX(logLevelTrace) | ||||
|         CONFIG_COMMAND_LOCK_REQUIRED(false) | ||||
|         CONFIG_COMMAND_LOCK_TYPE(lockTypeNone) | ||||
|     ) | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -14,6 +14,10 @@ Map command names to ids and vice versa. | ||||
| typedef struct ConfigCommandData | ||||
| { | ||||
|     const char *name; | ||||
|  | ||||
|     bool lockRequired:1; | ||||
|     unsigned int lockType:2; | ||||
|  | ||||
|     bool logFile:1; | ||||
|     unsigned int logLevelDefault:4; | ||||
|     unsigned int logLevelStdErrMax:4; | ||||
| @@ -25,6 +29,10 @@ typedef struct ConfigCommandData | ||||
| #define CONFIG_COMMAND(...)                                                                                                        \ | ||||
|     {__VA_ARGS__}, | ||||
|  | ||||
| #define CONFIG_COMMAND_LOCK_REQUIRED(lockRequiredParam)                                                                            \ | ||||
|     .lockRequired = lockRequiredParam, | ||||
| #define CONFIG_COMMAND_LOCK_TYPE(lockTypeParam)                                                                                    \ | ||||
|     .lockType = lockTypeParam, | ||||
| #define CONFIG_COMMAND_LOG_FILE(logFileParam)                                                                                      \ | ||||
|     .logFile = logFileParam, | ||||
| #define CONFIG_COMMAND_LOG_LEVEL_DEFAULT(logLevelDefaultParam)                                                                     \ | ||||
| @@ -277,6 +285,26 @@ cfgExeSet(const String *exeParam) | ||||
|     MEM_CONTEXT_END(); | ||||
| } | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Does this command require an immediate lock? | ||||
| ***********************************************************************************************************************************/ | ||||
| bool | ||||
| cfgLockRequired() | ||||
| { | ||||
|     ASSERT_DEBUG_COMMAND_SET(); | ||||
|     return configCommandData[cfgCommand()].lockRequired; | ||||
| } | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Get the lock type required for this command | ||||
| ***********************************************************************************************************************************/ | ||||
| LockType | ||||
| cfgLockType() | ||||
| { | ||||
|     ASSERT_DEBUG_COMMAND_SET(); | ||||
|     return (LockType)configCommandData[cfgCommand()].lockType; | ||||
| } | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Does this command log to a file? | ||||
| ***********************************************************************************************************************************/ | ||||
|   | ||||
| @@ -7,6 +7,7 @@ config/parse.c sets the command and options and determines which options are val | ||||
| #ifndef CONFIG_CONFIG_H | ||||
| #define CONFIG_CONFIG_H | ||||
|  | ||||
| #include "common/lock.h" | ||||
| #include "common/log.h" | ||||
| #include "common/type/stringList.h" | ||||
| #include "config/define.h" | ||||
| @@ -30,6 +31,9 @@ Access the current command and command parameters. | ||||
| ConfigCommand cfgCommand(); | ||||
| const char *cfgCommandName(ConfigCommand commandId); | ||||
|  | ||||
| bool cfgLockRequired(); | ||||
| LockType cfgLockType(); | ||||
|  | ||||
| bool cfgLogFile(); | ||||
| LogLevel cfgLogLevelDefault(); | ||||
| LogLevel cfgLogLevelStdErrMax(); | ||||
|   | ||||
| @@ -6,6 +6,7 @@ Configuration Load | ||||
|  | ||||
| #include "command/command.h" | ||||
| #include "common/memContext.h" | ||||
| #include "common/lock.h" | ||||
| #include "common/log.h" | ||||
| #include "config/config.h" | ||||
| #include "config/load.h" | ||||
| @@ -88,6 +89,9 @@ cfgLoadParam(unsigned int argListSize, const char *argList[], String *exe) | ||||
|                         cfgOptionDefaultSet(cfgOptPgHostCmd + optionIdx, varNewStr(cfgExe())); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (cfgLockRequired()) | ||||
|                 lockAcquire(cfgOptionStr(cfgOptLockPath), cfgOptionStr(cfgOptStanza), cfgLockType(), 0, true); | ||||
|         } | ||||
|  | ||||
|         // Neutralize the umask to make the repository file/path modes more consistent | ||||
|   | ||||
| @@ -105,6 +105,14 @@ module: | ||||
|         coverage: | ||||
|           common/debug: noCode | ||||
|  | ||||
|       # ---------------------------------------------------------------------------------------------------------------------------- | ||||
|       - name: lock | ||||
|         total: 2 | ||||
|         c: true | ||||
|  | ||||
|         coverage: | ||||
|           common/lock: full | ||||
|  | ||||
|       # ---------------------------------------------------------------------------------------------------------------------------- | ||||
|       - name: io-handle | ||||
|         total: 1 | ||||
|   | ||||
| @@ -89,13 +89,10 @@ P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = < | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 16384, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathExists(): strPathExp =  | ||||
| P00  DEBUG:     Storage::Local->pathExists=>: bExists = true | ||||
| P00  DEBUG:     Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup | ||||
| P00  DEBUG:     Common::Lock::lockStopTest(): bStanzaStopRequired = <false> | ||||
| P00  DEBUG:     Common::Lock::lockStopTest=>: bStopExists = false | ||||
| P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 16384, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock | ||||
| P00  DEBUG:     Common::Lock::lockAcquire=>: bResult = true | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log | ||||
| P00  DEBUG:     Backup::Info->new(): bIgnoreMissing = <false>, bLoad = <true>, bRequired = <true>, bValidate = <true>, oStorage = <[object]>, strBackupClusterPath = [TEST_PATH]/db-master/repo/backup/db, strCipherPassSub = [undef] | ||||
| P00  DEBUG:     Storage::Local->encrypted(): bIgnoreMissing = true, strFileName = [TEST_PATH]/db-master/repo/backup/db/backup.info | ||||
| @@ -314,12 +311,10 @@ P00  DEBUG:     Storage::Local->list=>: stryFileList = ([BACKUP-FULL-1]) | ||||
| P00  DEBUG:     Backup::Info->current(): strBackup = [BACKUP-FULL-1] | ||||
| P00  DEBUG:     Backup::Info->current=>: bTest = true | ||||
| P00   INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = <true> | ||||
| P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], strSignal = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: expire command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| + supplemental file: [TEST_PATH]/db-master/pgbackrest.conf | ||||
| @@ -469,7 +464,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: stop command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| full backup - abort backup - local (db-master host) | ||||
| @@ -482,13 +476,10 @@ P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = < | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathExists(): strPathExp =  | ||||
| P00  DEBUG:     Storage::Local->pathExists=>: bExists = true | ||||
| P00  DEBUG:     Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup | ||||
| P00  DEBUG:     Common::Lock::lockStopTest(): bStanzaStopRequired = <false> | ||||
| P00  DEBUG:     Common::Lock::lockStopTest=>: bStopExists = false | ||||
| P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock | ||||
| P00  DEBUG:     Common::Lock::lockAcquire=>: bResult = true | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log | ||||
| P00  DEBUG:     Backup::Info->new(): bIgnoreMissing = <false>, bLoad = <true>, bRequired = <true>, bValidate = <true>, oStorage = <[object]>, strBackupClusterPath = [TEST_PATH]/db-master/repo/backup/db, strCipherPassSub = [undef] | ||||
| P00  DEBUG:     Storage::Local->encrypted(): bIgnoreMissing = true, strFileName = [TEST_PATH]/db-master/repo/backup/db/backup.info | ||||
| @@ -551,7 +542,6 @@ P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = false, iRemoteI | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00  ERROR: [063]: terminated on signal [SIGTERM] | ||||
| P00   INFO: backup command end: terminated on signal [SIGTERM] | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 63 | ||||
|  | ||||
| full backup - global stop (db-master host) | ||||
| @@ -564,14 +554,12 @@ P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = < | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathExists(): strPathExp =  | ||||
| P00  DEBUG:     Storage::Local->pathExists=>: bExists = true | ||||
| P00  DEBUG:     Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup | ||||
| P00  DEBUG:     Common::Lock::lockStopTest(): bStanzaStopRequired = <false> | ||||
| P00  ERROR: [062]: stop file exists for all stanzas | ||||
| P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = [undef], oException = [object], strSignal = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = false, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: backup command end: aborted with exception [062] | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 62 | ||||
|  | ||||
| stop db stanza (db-master host) | ||||
| @@ -585,7 +573,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: stop command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| stop db stanza (db-master host) | ||||
| @@ -600,7 +587,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: stop command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| full backup - stanza stop (db-master host) | ||||
| @@ -613,14 +599,12 @@ P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = < | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathExists(): strPathExp =  | ||||
| P00  DEBUG:     Storage::Local->pathExists=>: bExists = true | ||||
| P00  DEBUG:     Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup | ||||
| P00  DEBUG:     Common::Lock::lockStopTest(): bStanzaStopRequired = <false> | ||||
| P00  ERROR: [062]: stop file exists for stanza db | ||||
| P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = [undef], oException = [object], strSignal = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = false, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: backup command end: aborted with exception [062] | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 62 | ||||
|  | ||||
| start db stanza (db-master host) | ||||
| @@ -631,7 +615,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: start command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| start all stanzas (db-master host) | ||||
| @@ -642,7 +625,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: start command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| start all stanzas (db-master host) | ||||
| @@ -654,7 +636,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: start command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| full backup - resume (db-master host) | ||||
| @@ -667,13 +648,10 @@ P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = < | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathExists(): strPathExp =  | ||||
| P00  DEBUG:     Storage::Local->pathExists=>: bExists = true | ||||
| P00  DEBUG:     Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup | ||||
| P00  DEBUG:     Common::Lock::lockStopTest(): bStanzaStopRequired = <false> | ||||
| P00  DEBUG:     Common::Lock::lockStopTest=>: bStopExists = false | ||||
| P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock | ||||
| P00  DEBUG:     Common::Lock::lockAcquire=>: bResult = true | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log | ||||
| P00  DEBUG:     Backup::Info->new(): bIgnoreMissing = <false>, bLoad = <true>, bRequired = <true>, bValidate = <true>, oStorage = <[object]>, strBackupClusterPath = [TEST_PATH]/db-master/repo/backup/db, strCipherPassSub = [undef] | ||||
| P00  DEBUG:     Storage::Local->encrypted(): bIgnoreMissing = true, strFileName = [TEST_PATH]/db-master/repo/backup/db/backup.info | ||||
| @@ -891,12 +869,10 @@ P00  DEBUG:     Storage::Local->list=>: stryFileList = ([BACKUP-FULL-2]) | ||||
| P00  DEBUG:     Backup::Info->current(): strBackup = [BACKUP-FULL-2] | ||||
| P00  DEBUG:     Backup::Info->current=>: bTest = true | ||||
| P00   INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = <true> | ||||
| P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], strSignal = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: expire command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| + supplemental file: [TEST_PATH]/db-master/pgbackrest.conf | ||||
| @@ -1044,13 +1020,10 @@ P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = < | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathExists(): strPathExp =  | ||||
| P00  DEBUG:     Storage::Local->pathExists=>: bExists = true | ||||
| P00  DEBUG:     Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = restore | ||||
| P00  DEBUG:     Common::Lock::lockStopTest(): bStanzaStopRequired = <false> | ||||
| P00  DEBUG:     Common::Lock::lockStopTest=>: bStopExists = false | ||||
| P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock | ||||
| P00  DEBUG:     Common::Lock::lockAcquire=>: bResult = true | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log | ||||
| P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/db/base, strTempExtension = pgbackrest.tmp | ||||
| @@ -1308,7 +1281,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: restore command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| + supplemental file: [TEST_PATH]/db-master/db/base/recovery.conf | ||||
| @@ -1682,13 +1654,10 @@ P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = < | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathExists(): strPathExp =  | ||||
| P00  DEBUG:     Storage::Local->pathExists=>: bExists = true | ||||
| P00  DEBUG:     Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup | ||||
| P00  DEBUG:     Common::Lock::lockStopTest(): bStanzaStopRequired = <false> | ||||
| P00  DEBUG:     Common::Lock::lockStopTest=>: bStopExists = false | ||||
| P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock | ||||
| P00  DEBUG:     Common::Lock::lockAcquire=>: bResult = true | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log | ||||
| P00  DEBUG:     Backup::Info->new(): bIgnoreMissing = <false>, bLoad = <true>, bRequired = <true>, bValidate = <true>, oStorage = <[object]>, strBackupClusterPath = [TEST_PATH]/db-master/repo/backup/db, strCipherPassSub = [undef] | ||||
| P00  DEBUG:     Storage::Local->encrypted(): bIgnoreMissing = true, strFileName = [TEST_PATH]/db-master/repo/backup/db/backup.info | ||||
| @@ -1897,12 +1866,10 @@ P00  DEBUG:     Backup::Info->current=>: bTest = true | ||||
| P00  DEBUG:     Backup::Info->current(): strBackup = [BACKUP-FULL-2] | ||||
| P00  DEBUG:     Backup::Info->current=>: bTest = true | ||||
| P00   INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = <true> | ||||
| P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], strSignal = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: expire command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| + supplemental file: [TEST_PATH]/db-master/pgbackrest.conf | ||||
| @@ -2049,13 +2016,10 @@ P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = < | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/db-master/repo, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathExists(): strPathExp =  | ||||
| P00  DEBUG:     Storage::Local->pathExists=>: bExists = true | ||||
| P00  DEBUG:     Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup | ||||
| P00  DEBUG:     Common::Lock::lockStopTest(): bStanzaStopRequired = <false> | ||||
| P00  DEBUG:     Common::Lock::lockStopTest=>: bStopExists = false | ||||
| P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock | ||||
| P00  DEBUG:     Common::Lock::lockAcquire=>: bResult = true | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log | ||||
| P00  DEBUG:     Backup::Info->new(): bIgnoreMissing = <false>, bLoad = <true>, bRequired = <true>, bValidate = <true>, oStorage = <[object]>, strBackupClusterPath = [TEST_PATH]/db-master/repo/backup/db, strCipherPassSub = [undef] | ||||
| P00  DEBUG:     Storage::Local->encrypted(): bIgnoreMissing = true, strFileName = [TEST_PATH]/db-master/repo/backup/db/backup.info | ||||
| @@ -2308,12 +2272,10 @@ P00  DEBUG:     Backup::Info->current=>: bTest = true | ||||
| P00  DEBUG:     Backup::Info->current(): strBackup = [BACKUP-FULL-2] | ||||
| P00  DEBUG:     Backup::Info->current=>: bTest = true | ||||
| P00   INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = <true> | ||||
| P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], strSignal = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: expire command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| + supplemental file: [TEST_PATH]/db-master/pgbackrest.conf | ||||
|   | ||||
| @@ -77,13 +77,10 @@ P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = < | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 16384, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathExists(): strPathExp =  | ||||
| P00  DEBUG:     Storage::Local->pathExists=>: bExists = true | ||||
| P00  DEBUG:     Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup | ||||
| P00  DEBUG:     Common::Lock::lockStopTest(): bStanzaStopRequired = <false> | ||||
| P00  DEBUG:     Common::Lock::lockStopTest=>: bStopExists = false | ||||
| P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 16384, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/backup/lock | ||||
| P00  DEBUG:     Common::Lock::lockAcquire=>: bResult = true | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log | ||||
| P00  DEBUG:     Backup::Info->new(): bIgnoreMissing = <false>, bLoad = <true>, bRequired = <true>, bValidate = <true>, oStorage = <[object]>, strBackupClusterPath = [TEST_PATH]/backup/repo/backup/db, strCipherPassSub = [undef] | ||||
| P00  DEBUG:     Storage::Local->encrypted(): bIgnoreMissing = true, strFileName = [TEST_PATH]/backup/repo/backup/db/backup.info | ||||
| @@ -306,12 +303,10 @@ P00  DEBUG:     Storage::Local->list=>: stryFileList = ([BACKUP-FULL-1]) | ||||
| P00  DEBUG:     Backup::Info->current(): strBackup = [BACKUP-FULL-1] | ||||
| P00  DEBUG:     Backup::Info->current=>: bTest = true | ||||
| P00   INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = <true> | ||||
| P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], strSignal = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: expire command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| + supplemental file: [TEST_PATH]/db-master/pgbackrest.conf | ||||
| @@ -478,7 +473,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: stop command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| full backup - abort backup - local (backup host) | ||||
| @@ -491,13 +485,10 @@ P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = < | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathExists(): strPathExp =  | ||||
| P00  DEBUG:     Storage::Local->pathExists=>: bExists = true | ||||
| P00  DEBUG:     Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup | ||||
| P00  DEBUG:     Common::Lock::lockStopTest(): bStanzaStopRequired = <false> | ||||
| P00  DEBUG:     Common::Lock::lockStopTest=>: bStopExists = false | ||||
| P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/backup/lock | ||||
| P00  DEBUG:     Common::Lock::lockAcquire=>: bResult = true | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log | ||||
| P00  DEBUG:     Backup::Info->new(): bIgnoreMissing = <false>, bLoad = <true>, bRequired = <true>, bValidate = <true>, oStorage = <[object]>, strBackupClusterPath = [TEST_PATH]/backup/repo/backup/db, strCipherPassSub = [undef] | ||||
| P00  DEBUG:     Storage::Local->encrypted(): bIgnoreMissing = true, strFileName = [TEST_PATH]/backup/repo/backup/db/backup.info | ||||
| @@ -585,7 +576,6 @@ P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = false, iRemoteI | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy: found cached protocol: iRemoteIdx = 1, strRemoteType = db | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: backup command end: terminated on signal from child process | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 63 | ||||
|  | ||||
| full backup - global stop (backup host) | ||||
| @@ -598,13 +588,10 @@ P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = < | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathExists(): strPathExp =  | ||||
| P00  DEBUG:     Storage::Local->pathExists=>: bExists = true | ||||
| P00  DEBUG:     Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup | ||||
| P00  DEBUG:     Common::Lock::lockStopTest(): bStanzaStopRequired = <false> | ||||
| P00  DEBUG:     Common::Lock::lockStopTest=>: bStopExists = false | ||||
| P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/backup/lock | ||||
| P00  DEBUG:     Common::Lock::lockAcquire=>: bResult = true | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log | ||||
| P00  DEBUG:     Backup::Info->new(): bIgnoreMissing = <false>, bLoad = <true>, bRequired = <true>, bValidate = <true>, oStorage = <[object]>, strBackupClusterPath = [TEST_PATH]/backup/repo/backup/db, strCipherPassSub = [undef] | ||||
| P00  DEBUG:     Storage::Local->encrypted(): bIgnoreMissing = true, strFileName = [TEST_PATH]/backup/repo/backup/db/backup.info | ||||
| @@ -642,7 +629,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = [undef], oException = [obj | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = false, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: backup command end: aborted with exception [062] | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 62 | ||||
|  | ||||
| stop db stanza (db-master host) | ||||
| @@ -656,7 +642,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: stop command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| stop db stanza (db-master host) | ||||
| @@ -671,7 +656,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: stop command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| full backup - stanza stop (backup host) | ||||
| @@ -684,13 +668,10 @@ P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = < | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathExists(): strPathExp =  | ||||
| P00  DEBUG:     Storage::Local->pathExists=>: bExists = true | ||||
| P00  DEBUG:     Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup | ||||
| P00  DEBUG:     Common::Lock::lockStopTest(): bStanzaStopRequired = <false> | ||||
| P00  DEBUG:     Common::Lock::lockStopTest=>: bStopExists = false | ||||
| P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/backup/lock | ||||
| P00  DEBUG:     Common::Lock::lockAcquire=>: bResult = true | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log | ||||
| P00  DEBUG:     Backup::Info->new(): bIgnoreMissing = <false>, bLoad = <true>, bRequired = <true>, bValidate = <true>, oStorage = <[object]>, strBackupClusterPath = [TEST_PATH]/backup/repo/backup/db, strCipherPassSub = [undef] | ||||
| P00  DEBUG:     Storage::Local->encrypted(): bIgnoreMissing = true, strFileName = [TEST_PATH]/backup/repo/backup/db/backup.info | ||||
| @@ -728,7 +709,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = [undef], oException = [obj | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = false, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: backup command end: aborted with exception [062] | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 62 | ||||
|  | ||||
| start db stanza (db-master host) | ||||
| @@ -739,7 +719,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: start command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| start all stanzas (db-master host) | ||||
| @@ -750,7 +729,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: start command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| start all stanzas (db-master host) | ||||
| @@ -762,7 +740,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: start command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| stop all stanzas (backup host) | ||||
| @@ -777,7 +754,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: stop command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| full backup - abort backup - remote (backup host) | ||||
| @@ -790,13 +766,10 @@ P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = < | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathExists(): strPathExp =  | ||||
| P00  DEBUG:     Storage::Local->pathExists=>: bExists = true | ||||
| P00  DEBUG:     Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup | ||||
| P00  DEBUG:     Common::Lock::lockStopTest(): bStanzaStopRequired = <false> | ||||
| P00  DEBUG:     Common::Lock::lockStopTest=>: bStopExists = false | ||||
| P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/backup/lock | ||||
| P00  DEBUG:     Common::Lock::lockAcquire=>: bResult = true | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log | ||||
| P00  DEBUG:     Backup::Info->new(): bIgnoreMissing = <false>, bLoad = <true>, bRequired = <true>, bValidate = <true>, oStorage = <[object]>, strBackupClusterPath = [TEST_PATH]/backup/repo/backup/db, strCipherPassSub = [undef] | ||||
| P00  DEBUG:     Storage::Local->encrypted(): bIgnoreMissing = true, strFileName = [TEST_PATH]/backup/repo/backup/db/backup.info | ||||
| @@ -883,7 +856,6 @@ P00  DEBUG:     Protocol::Command::Master->close=>: iExitStatus = 0 | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00  ERROR: [063]: terminated on signal [SIGTERM] | ||||
| P00   INFO: backup command end: terminated on signal [SIGTERM] | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 63 | ||||
|  | ||||
| full backup - global stop (backup host) | ||||
| @@ -896,14 +868,12 @@ P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = < | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathExists(): strPathExp =  | ||||
| P00  DEBUG:     Storage::Local->pathExists=>: bExists = true | ||||
| P00  DEBUG:     Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup | ||||
| P00  DEBUG:     Common::Lock::lockStopTest(): bStanzaStopRequired = <false> | ||||
| P00  ERROR: [062]: stop file exists for all stanzas | ||||
| P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = [undef], oException = [object], strSignal = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = false, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: backup command end: aborted with exception [062] | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 62 | ||||
|  | ||||
| start all stanzas (backup host) | ||||
| @@ -914,7 +884,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: start command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| full backup - resume (backup host) | ||||
| @@ -927,13 +896,10 @@ P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = < | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathExists(): strPathExp =  | ||||
| P00  DEBUG:     Storage::Local->pathExists=>: bExists = true | ||||
| P00  DEBUG:     Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup | ||||
| P00  DEBUG:     Common::Lock::lockStopTest(): bStanzaStopRequired = <false> | ||||
| P00  DEBUG:     Common::Lock::lockStopTest=>: bStopExists = false | ||||
| P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/backup/lock | ||||
| P00  DEBUG:     Common::Lock::lockAcquire=>: bResult = true | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log | ||||
| P00  DEBUG:     Backup::Info->new(): bIgnoreMissing = <false>, bLoad = <true>, bRequired = <true>, bValidate = <true>, oStorage = <[object]>, strBackupClusterPath = [TEST_PATH]/backup/repo/backup/db, strCipherPassSub = [undef] | ||||
| P00  DEBUG:     Storage::Local->encrypted(): bIgnoreMissing = true, strFileName = [TEST_PATH]/backup/repo/backup/db/backup.info | ||||
| @@ -1148,12 +1114,10 @@ P00  DEBUG:     Storage::Local->list=>: stryFileList = ([BACKUP-FULL-2]) | ||||
| P00  DEBUG:     Backup::Info->current(): strBackup = [BACKUP-FULL-2] | ||||
| P00  DEBUG:     Backup::Info->current=>: bTest = true | ||||
| P00   INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = <true> | ||||
| P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], strSignal = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: expire command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| + supplemental file: [TEST_PATH]/db-master/pgbackrest.conf | ||||
| @@ -1316,13 +1280,10 @@ restore delta, backup '[BACKUP-FULL-2]' - add and delete files (db-master host) | ||||
| > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --delta --set=[BACKUP-FULL-2]  --link-all --cmd-ssh=/usr/bin/ssh  --stanza=db restore | ||||
| ------------------------------------------------------------------------------------------------------------------------------------ | ||||
| P00   INFO: restore command begin [BACKREST-VERSION]: --cmd-ssh=/usr/bin/ssh --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/db-master/pgbackrest.conf --delta --link-all --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-2] --set=[BACKUP-FULL-2] --stanza=db | ||||
| P00  DEBUG:     Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = restore | ||||
| P00  DEBUG:     Common::Lock::lockStopTest(): bStanzaStopRequired = <false> | ||||
| P00  DEBUG:     Common::Lock::lockStopTest=>: bStopExists = false | ||||
| P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock | ||||
| P00  DEBUG:     Common::Lock::lockAcquire=>: bResult = true | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log | ||||
| P00  DEBUG:     Protocol::Helper::protocolGet(): bCache = <true>, iProcessIdx = [undef], iRemoteIdx = <1>, strBackRestBin = [undef], strCommand = <restore>, strRemoteType = backup | ||||
| P00  DEBUG:     Protocol::Helper::protocolGet: create (cached) remote protocol | ||||
| @@ -1533,7 +1494,6 @@ P00  DEBUG:     Protocol::Helper::protocolDestroy: found cached protocol: iRemot | ||||
| P00  DEBUG:     Protocol::Command::Master->close=>: iExitStatus = 0 | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: restore command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| + supplemental file: [TEST_PATH]/db-master/db/base/recovery.conf | ||||
| @@ -1744,13 +1704,10 @@ P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = < | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathExists(): strPathExp =  | ||||
| P00  DEBUG:     Storage::Local->pathExists=>: bExists = true | ||||
| P00  DEBUG:     Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup | ||||
| P00  DEBUG:     Common::Lock::lockStopTest(): bStanzaStopRequired = <false> | ||||
| P00  DEBUG:     Common::Lock::lockStopTest=>: bStopExists = false | ||||
| P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/backup/lock | ||||
| P00  DEBUG:     Common::Lock::lockAcquire=>: bResult = true | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log | ||||
| P00  DEBUG:     Backup::Info->new(): bIgnoreMissing = <false>, bLoad = <true>, bRequired = <true>, bValidate = <true>, oStorage = <[object]>, strBackupClusterPath = [TEST_PATH]/backup/repo/backup/db, strCipherPassSub = [undef] | ||||
| P00  DEBUG:     Storage::Local->encrypted(): bIgnoreMissing = true, strFileName = [TEST_PATH]/backup/repo/backup/db/backup.info | ||||
| @@ -1956,12 +1913,10 @@ P00  DEBUG:     Backup::Info->current=>: bTest = true | ||||
| P00  DEBUG:     Backup::Info->current(): strBackup = [BACKUP-FULL-2] | ||||
| P00  DEBUG:     Backup::Info->current=>: bTest = true | ||||
| P00   INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = <true> | ||||
| P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], strSignal = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: expire command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| + supplemental file: [TEST_PATH]/db-master/pgbackrest.conf | ||||
| @@ -2127,13 +2082,10 @@ P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = < | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [hash], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = [TEST_PATH]/backup/repo, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathExists(): strPathExp =  | ||||
| P00  DEBUG:     Storage::Local->pathExists=>: bExists = true | ||||
| P00  DEBUG:     Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup | ||||
| P00  DEBUG:     Common::Lock::lockStopTest(): bStanzaStopRequired = <false> | ||||
| P00  DEBUG:     Common::Lock::lockStopTest=>: bStopExists = false | ||||
| P00  DEBUG:     Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true> | ||||
| P00  DEBUG:     Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/backup/lock | ||||
| P00  DEBUG:     Common::Lock::lockAcquire=>: bResult = true | ||||
| P00  DEBUG:     Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log | ||||
| P00  DEBUG:     Backup::Info->new(): bIgnoreMissing = <false>, bLoad = <true>, bRequired = <true>, bValidate = <true>, oStorage = <[object]>, strBackupClusterPath = [TEST_PATH]/backup/repo/backup/db, strCipherPassSub = [undef] | ||||
| P00  DEBUG:     Storage::Local->encrypted(): bIgnoreMissing = true, strFileName = [TEST_PATH]/backup/repo/backup/db/backup.info | ||||
| @@ -2383,12 +2335,10 @@ P00  DEBUG:     Backup::Info->current=>: bTest = true | ||||
| P00  DEBUG:     Backup::Info->current(): strBackup = [BACKUP-FULL-2] | ||||
| P00  DEBUG:     Backup::Info->current=>: bTest = true | ||||
| P00   INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = <true> | ||||
| P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], strSignal = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: expire command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| + supplemental file: [TEST_PATH]/db-master/pgbackrest.conf | ||||
|   | ||||
| @@ -110,7 +110,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: archive-push command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-get --log-level-console=debug 000000010000000100000001 [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG | ||||
| @@ -156,7 +155,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: archive-get command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push --compress --archive-async --process-max=2 [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002 | ||||
|   | ||||
| @@ -94,7 +94,6 @@ P00  DEBUG:     Protocol::Helper::protocolDestroy: found cached protocol: iRemot | ||||
| P00  DEBUG:     Protocol::Command::Master->close=>: iExitStatus = 0 | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: archive-push command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-get --log-level-console=debug 000000010000000100000001 [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG | ||||
| @@ -133,7 +132,6 @@ P00  DEBUG:     Protocol::Helper::protocolDestroy: found cached protocol: iRemot | ||||
| P00  DEBUG:     Protocol::Command::Master->close=>: iExitStatus = 0 | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: archive-get command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push --compress --archive-async --process-max=2 [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002 | ||||
|   | ||||
| @@ -219,7 +219,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: archive-push command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| stanza-create db - fail on archive info file missing from non-empty dir (db-master host) | ||||
| @@ -468,7 +467,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: archive-push command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --archive-queue-max=33554432 --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001 | ||||
| @@ -560,7 +558,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: archive-get command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --archive-queue-max=33554432 --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001 | ||||
| @@ -969,7 +966,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: stop command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| stanza-delete db - successfully delete the stanza (db-master host) | ||||
|   | ||||
| @@ -235,7 +235,6 @@ P00  DEBUG:     Protocol::Helper::protocolDestroy: found cached protocol: iRemot | ||||
| P00  DEBUG:     Protocol::Command::Master->close=>: iExitStatus = 0 | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: archive-push command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| stanza-create db - gunzip fail on forced stanza-create (backup host) | ||||
| @@ -328,7 +327,6 @@ P00  DEBUG:     Protocol::Helper::protocolDestroy: found cached protocol: iRemot | ||||
| P00  DEBUG:     Protocol::Command::Master->close=>: iExitStatus = 0 | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: archive-push command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --archive-queue-max=33554432 --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001 | ||||
| @@ -419,7 +417,6 @@ P00  DEBUG:     Protocol::Helper::protocolDestroy: found cached protocol: iRemot | ||||
| P00  DEBUG:     Protocol::Command::Master->close=>: iExitStatus = 0 | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: archive-get command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --archive-queue-max=33554432 --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001 | ||||
| @@ -801,7 +798,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: stop command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| stanza-delete db - successfully delete the stanza (backup host) | ||||
|   | ||||
| @@ -219,7 +219,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: archive-push command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| stanza-create db - fail on archive info file missing from non-empty dir (db-master host) | ||||
| @@ -443,7 +442,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: archive-push command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --archive-queue-max=33554432 --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001 | ||||
| @@ -535,7 +533,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: archive-get command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| > [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --log-level-console=warn --archive-queue-max=33554432 --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001 | ||||
| @@ -956,7 +953,6 @@ P00  DEBUG:     Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], s | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef] | ||||
| P00  DEBUG:     Protocol::Helper::protocolDestroy=>: iExitStatus = 0 | ||||
| P00   INFO: stop command end: completed successfully | ||||
| P00  DEBUG:     Common::Lock::lockRelease(): bFailOnNoLock = false | ||||
| P00  DEBUG:     Common::Exit::exitSafe=>: iExitCode = 0 | ||||
|  | ||||
| stanza-delete db - successfully delete the stanza (db-master host) | ||||
|   | ||||
| @@ -17,7 +17,7 @@ use Getopt::Long qw(GetOptions); | ||||
| use pgBackRest::Common::Exception; | ||||
| use pgBackRest::Common::Log; | ||||
| use pgBackRest::Config::Config; | ||||
| use pgBackRest::LibC qw(:test); | ||||
| use pgBackRest::LibC qw(:test :lock); | ||||
| use pgBackRest::Version; | ||||
|  | ||||
| use pgBackRestTest::Common::RunTest; | ||||
| @@ -186,6 +186,9 @@ sub configTestLoad | ||||
|     $self->testResult( | ||||
|         sub {configLoad(false, backrestBin(), cfgCommandName($iCommandId), \$strConfigJson)}, | ||||
|         true, 'config load: ' . join(" ", @stryArg)); | ||||
|  | ||||
|     # Release any lock that was taken during configLoad. | ||||
|     lockRelease(false); | ||||
| } | ||||
|  | ||||
| 1; | ||||
|   | ||||
							
								
								
									
										155
									
								
								test/src/module/common/lockTest.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								test/src/module/common/lockTest.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,155 @@ | ||||
| /*********************************************************************************************************************************** | ||||
| Test Lock Handler | ||||
| ***********************************************************************************************************************************/ | ||||
| #include "common/time.h" | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Test Run | ||||
| ***********************************************************************************************************************************/ | ||||
| void | ||||
| testRun() | ||||
| { | ||||
|     // Create default storage object for testing | ||||
|     Storage *storageTest = storageNewP(strNew(testPath()), .write = true); | ||||
|  | ||||
|     // ***************************************************************************************************************************** | ||||
|     if (testBegin("lockAcquireFile() and lockReleaseFile()")) | ||||
|     { | ||||
|         String *archiveLock = strNewFmt("%s/main-archive.lock", testPath()); | ||||
|         int lockHandle = -1; | ||||
|  | ||||
|         TEST_RESULT_INT(system(strPtr(strNewFmt("touch %s", strPtr(archiveLock)))), 0, "touch lock file"); | ||||
|         TEST_ASSIGN(lockHandle, lockAcquireFile(archiveLock, 0, true), "get lock"); | ||||
|         TEST_RESULT_BOOL(lockHandle != -1, true, "lock succeeds"); | ||||
|         TEST_RESULT_BOOL(storageExistsNP(storageTest, archiveLock), true, "lock file was created"); | ||||
|         TEST_ERROR(lockAcquireFile(archiveLock, 0, true), LockAcquireError, | ||||
|             strPtr( | ||||
|                 strNewFmt( | ||||
|                     "unable to acquire lock on file '%s': Resource temporarily unavailable\n" | ||||
|                     "HINT: is another pgBackRest process running?", strPtr(archiveLock)))); | ||||
|  | ||||
|         TEST_ERROR( | ||||
|             lockAcquireFile(archiveLock, 0, true), LockAcquireError, | ||||
|             strPtr(strNewFmt( | ||||
|                 "unable to acquire lock on file '%s': Resource temporarily unavailable\n" | ||||
|                 "HINT: is another pgBackRest process running?", strPtr(archiveLock)))); | ||||
|         TEST_RESULT_BOOL(lockAcquireFile(archiveLock, 0, false) == -1, true, "lock is already held"); | ||||
|  | ||||
|         TEST_RESULT_VOID(lockReleaseFile(lockHandle, archiveLock), "release lock"); | ||||
|  | ||||
|         TEST_RESULT_VOID(lockReleaseFile(lockHandle, archiveLock), "release lock"); | ||||
|         TEST_RESULT_BOOL(storageExistsNP(storageTest, archiveLock), false, "lock file was removed"); | ||||
|         TEST_RESULT_VOID(lockReleaseFile(lockHandle, archiveLock), "release lock again without error"); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         String *subPathLock = strNewFmt("%s/sub1/sub2/db-backup.lock", testPath()); | ||||
|  | ||||
|         TEST_ASSIGN(lockHandle, lockAcquireFile(subPathLock, 0, true), "get lock in subpath"); | ||||
|         TEST_RESULT_BOOL(storageExistsNP(storageTest, subPathLock), true, "lock file was created"); | ||||
|         TEST_RESULT_BOOL(lockHandle != -1, true, "lock succeeds"); | ||||
|         TEST_RESULT_VOID(lockReleaseFile(lockHandle, subPathLock), "release lock"); | ||||
|         TEST_RESULT_BOOL(storageExistsNP(storageTest, subPathLock), false, "lock file was removed"); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         String *dirLock = strNewFmt("%s/dir.lock", testPath()); | ||||
|  | ||||
|         TEST_RESULT_INT(system(strPtr(strNewFmt("sudo mkdir -p 750 %s", strPtr(dirLock)))), 0, "create dirtest.lock dir"); | ||||
|  | ||||
|         TEST_ERROR( | ||||
|             lockAcquireFile(dirLock, 0, true), LockAcquireError, | ||||
|             strPtr(strNewFmt("unable to acquire lock on file '%s': Is a directory", strPtr(dirLock)))); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         String *noPermLock = strNewFmt("%s/noperm/noperm", testPath()); | ||||
|         TEST_RESULT_INT(system(strPtr(strNewFmt("sudo mkdir -p 700 %s", strPtr(strPath(noPermLock))))), 0, "create noperm dir"); | ||||
|  | ||||
|         TEST_ERROR( | ||||
|             lockAcquireFile(noPermLock, .1, true), LockAcquireError, | ||||
|             strPtr( | ||||
|                 strNewFmt( | ||||
|                     "unable to acquire lock on file '%s': Permission denied\n" | ||||
|                         "HINT: does the user running pgBackRest have permissions on the '%s' file?", | ||||
|                     strPtr(noPermLock), strPtr(noPermLock)))); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         String *backupLock = strNewFmt("%s/main-backup.lock", testPath()); | ||||
|  | ||||
|         if (fork() == 0) | ||||
|         { | ||||
|             TEST_RESULT_BOOL( | ||||
|                 lockAcquireFile(backupLock, 0, true), true, "lock on fork"); | ||||
|             sleepMSec(500); | ||||
|             exit(0); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             sleepMSec(250); | ||||
|             TEST_ERROR( | ||||
|                 lockAcquireFile(backupLock, 0, true), | ||||
|                 LockAcquireError, | ||||
|                 strPtr( | ||||
|                     strNewFmt( | ||||
|                         "unable to acquire lock on file '%s': Resource temporarily unavailable\n" | ||||
|                         "HINT: is another pgBackRest process running?", strPtr(backupLock)))); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // ***************************************************************************************************************************** | ||||
|     if (testBegin("lockAcquire() and lockRelease()")) | ||||
|     { | ||||
|         String *stanza = strNew("test"); | ||||
|         String *lockPath = strNew(testPath()); | ||||
|         String *archiveLockFile = strNewFmt("%s/%s-archive.lock", testPath(), strPtr(stanza)); | ||||
|         String *backupLockFile = strNewFmt("%s/%s-backup.lock", testPath(), strPtr(stanza)); | ||||
|         int lockHandle = -1; | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         TEST_ERROR(lockRelease(true), AssertError, "no lock is held by this process"); | ||||
|         TEST_RESULT_BOOL(lockRelease(false), false, "release when there is no lock"); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         TEST_ASSIGN(lockHandle, lockAcquireFile(archiveLockFile, 0, true), "archive lock by file"); | ||||
|         TEST_RESULT_BOOL(lockAcquire(lockPath, stanza, lockTypeArchive, 0, false), false, "archive already locked"); | ||||
|         TEST_ERROR( | ||||
|             lockAcquire(lockPath, stanza, lockTypeArchive, 0, true), LockAcquireError, | ||||
|             strPtr(strNewFmt( | ||||
|                 "unable to acquire lock on file '%s': Resource temporarily unavailable\n" | ||||
|                 "HINT: is another pgBackRest process running?", strPtr(archiveLockFile)))); | ||||
|         TEST_ERROR( | ||||
|             lockAcquire(lockPath, stanza, lockTypeAll, 0, true), LockAcquireError, | ||||
|             strPtr(strNewFmt( | ||||
|                 "unable to acquire lock on file '%s': Resource temporarily unavailable\n" | ||||
|                 "HINT: is another pgBackRest process running?", strPtr(archiveLockFile)))); | ||||
|         TEST_RESULT_VOID(lockReleaseFile(lockHandle, archiveLockFile), "release lock"); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         TEST_RESULT_BOOL(lockAcquire(lockPath, stanza, lockTypeArchive, 0, true), true, "archive lock"); | ||||
|         TEST_RESULT_BOOL(storageExistsNP(storageTest, archiveLockFile), true, "archive lock file was created"); | ||||
|         TEST_ERROR(lockAcquire(lockPath, stanza, lockTypeArchive, 0, false), AssertError, "lock is already held by this process"); | ||||
|         TEST_RESULT_VOID(lockRelease(true), "release archive lock"); | ||||
|  | ||||
|         // // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         TEST_ASSIGN(lockHandle, lockAcquireFile(backupLockFile, 0, true), "backup lock by file"); | ||||
|         TEST_ERROR( | ||||
|             lockAcquire(lockPath, stanza, lockTypeBackup, 0, true), LockAcquireError, | ||||
|             strPtr(strNewFmt( | ||||
|                 "unable to acquire lock on file '%s': Resource temporarily unavailable\n" | ||||
|                 "HINT: is another pgBackRest process running?", strPtr(backupLockFile)))); | ||||
|         TEST_ERROR( | ||||
|             lockAcquire(lockPath, stanza, lockTypeAll, 0, true), LockAcquireError, | ||||
|             strPtr(strNewFmt( | ||||
|                 "unable to acquire lock on file '%s': Resource temporarily unavailable\n" | ||||
|                 "HINT: is another pgBackRest process running?", strPtr(backupLockFile)))); | ||||
|         TEST_RESULT_VOID(lockReleaseFile(lockHandle, archiveLockFile), "release lock"); | ||||
|         TEST_RESULT_VOID(lockReleaseFile(lockHandle, backupLockFile), "release lock"); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         TEST_RESULT_BOOL(lockAcquire(lockPath, stanza, lockTypeAll, 0, true), true, "all lock"); | ||||
|         TEST_RESULT_BOOL(storageExistsNP(storageTest, archiveLockFile), true, "archive lock file was created"); | ||||
|         TEST_RESULT_BOOL(storageExistsNP(storageTest, backupLockFile), true, "backup lock file was created"); | ||||
|         TEST_ERROR( | ||||
|             lockAcquire(lockPath, stanza, lockTypeAll, 0, false), AssertError, | ||||
|             "debug assertion 'failOnNoLock || lockType != lockTypeAll' failed"); | ||||
|         TEST_RESULT_VOID(lockRelease(true), "release all lock"); | ||||
|     } | ||||
| } | ||||
| @@ -83,10 +83,20 @@ testRun() | ||||
|         TEST_RESULT_VOID(cfgCommandSet(cfgCmdBackup), "command set to backup"); | ||||
|         TEST_RESULT_INT(cfgLogLevelDefault(), logLevelInfo, "default log level is info"); | ||||
|         TEST_RESULT_BOOL(cfgLogFile(), true, "log file is on"); | ||||
|         TEST_RESULT_BOOL(cfgLockRequired(), true, "lock is required"); | ||||
|         TEST_RESULT_INT(cfgLockType(), lockTypeBackup, "lock is type backup"); | ||||
|  | ||||
|         TEST_RESULT_VOID(cfgCommandSet(cfgCmdInfo), "command set to info"); | ||||
|         TEST_RESULT_INT(cfgLogLevelDefault(), logLevelDebug, "default log level is debug"); | ||||
|         TEST_RESULT_INT(cfgLogLevelStdErrMax(), logLevelTrace, "max stderr log level is trace"); | ||||
|         TEST_RESULT_BOOL(cfgLogFile(), false, "log file is off"); | ||||
|         TEST_RESULT_BOOL(cfgLockRequired(), false, "lock is not required"); | ||||
|         TEST_RESULT_INT(cfgLockType(), lockTypeNone, "lock is type none"); | ||||
|  | ||||
|         TEST_RESULT_VOID(cfgCommandSet(cfgCmdStanzaCreate), "command set to stanza-create"); | ||||
|         TEST_RESULT_BOOL(cfgLockRequired(), true, "lock is required"); | ||||
|         TEST_RESULT_INT(cfgLockType(), lockTypeAll, "lock is type all"); | ||||
|  | ||||
|         TEST_RESULT_VOID(cfgCommandSet(cfgCmdLocal), "command set to local"); | ||||
|         TEST_RESULT_INT(cfgLogLevelStdErrMax(), logLevelError, "max stderr log level is error"); | ||||
|         TEST_RESULT_BOOL(cfgLogFile(), false, "log file is off"); | ||||
|   | ||||
| @@ -78,6 +78,7 @@ testRun() | ||||
|  | ||||
|         TEST_RESULT_VOID(cfgLoad(strLstSize(argList), strLstPtr(argList)), "load backup config"); | ||||
|         TEST_RESULT_PTR(cfgOptionDefault(cfgOptPgHostCmd), NULL, "    command backup, option pg1-host-cmd default"); | ||||
|         TEST_RESULT_BOOL(lockRelease(true), true, "release backup lock"); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         argList = strLstNew(); | ||||
| @@ -97,6 +98,7 @@ testRun() | ||||
|         TEST_RESULT_STR( | ||||
|             strPtr(varStr(cfgOptionDefault(cfgOptPgHostCmd + 2))), strPtr(cfgExe()), | ||||
|             "    command backup, option pg3-host-cmd default"); | ||||
|         TEST_RESULT_BOOL(lockRelease(true), true, "release backup lock"); | ||||
|  | ||||
|         // Set a distinct umask value and test that the umask is reset by configLoad since default for neutral-umask=y | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -179,6 +181,7 @@ testRun() | ||||
|             "            HINT: to retain full backups indefinitely (without warning), set option" | ||||
|                 " 'repo1-retention-full' to the maximum."); | ||||
|         TEST_RESULT_BOOL(cfgOptionTest(cfgOptRepoRetentionArchive), false, "    repo1-retention-archive not set"); | ||||
|         TEST_RESULT_BOOL(lockRelease(true), true, "release expire lock"); | ||||
|  | ||||
|         strLstAdd(argList, strNew("--repo1-retention-full=1")); | ||||
|  | ||||
| @@ -189,6 +192,7 @@ testRun() | ||||
|             "P00   INFO: expire command begin " PGBACKREST_VERSION ": --log-level-console=info --log-level-stderr=off" | ||||
|                 " --no-log-timestamp --repo1-retention-full=1 --stanza=db"); | ||||
|         TEST_RESULT_INT(cfgOptionInt(cfgOptRepoRetentionArchive), 1, "    repo1-retention-archive set"); | ||||
|         TEST_RESULT_BOOL(lockRelease(true), true, "release expire lock"); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAdd(argList, strNew("pgbackrest")); | ||||
| @@ -211,6 +215,7 @@ testRun() | ||||
|             "P00   WARN: WAL segments will not be expired: option 'repo1-retention-archive-type=incr' but option" | ||||
|                 " 'repo1-retention-archive' is not set"); | ||||
|         TEST_RESULT_BOOL(cfgOptionTest(cfgOptRepoRetentionArchive), false, "    repo1-retention-archive not set"); | ||||
|         TEST_RESULT_BOOL(lockRelease(true), true, "release expire lock"); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAdd(argList, strNew("pgbackrest")); | ||||
| @@ -233,6 +238,7 @@ testRun() | ||||
|             "P00   WARN: WAL segments will not be expired: option 'repo1-retention-archive-type=diff' but neither option" | ||||
|                 " 'repo1-retention-archive' nor option 'repo1-retention-diff' is set"); | ||||
|         TEST_RESULT_BOOL(cfgOptionTest(cfgOptRepoRetentionArchive), false, "    repo1-retention-archive not set"); | ||||
|         TEST_RESULT_BOOL(lockRelease(true), true, "release expire lock"); | ||||
|  | ||||
|         strLstAdd(argList, strNew("--repo1-retention-diff=2")); | ||||
|  | ||||
| @@ -246,6 +252,7 @@ testRun() | ||||
|             "            HINT: to retain full backups indefinitely (without warning), set option" | ||||
|                 " 'repo1-retention-full' to the maximum."); | ||||
|         TEST_RESULT_INT(cfgOptionInt(cfgOptRepoRetentionArchive), 2, "    repo1-retention-archive set to retention-diff"); | ||||
|         TEST_RESULT_BOOL(lockRelease(true), true, "release expire lock"); | ||||
|  | ||||
|         argList = strLstNew(); | ||||
|         strLstAdd(argList, strNew("pgbackrest")); | ||||
| @@ -268,6 +275,7 @@ testRun() | ||||
|             "P00   WARN: option 'repo1-retention-diff' is not set for 'repo1-retention-archive-type=diff'\n" | ||||
|             "            HINT: to retain differential backups indefinitely (without warning), set option 'repo1-retention-diff'" | ||||
|                 " to the maximum."); | ||||
|         TEST_RESULT_BOOL(lockRelease(true), true, "release expire lock"); | ||||
|  | ||||
|         testLogErrResult( | ||||
|             "WARN: unable to open log file '/var/log/pgbackrest/db-backup.log': No such file or directory\n" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user