1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-14 10:13:05 +02:00
Commit Graph

578 Commits

Author SHA1 Message Date
David Steele
8aa1e552b0 Add backup type conversion functions.
Convert back and forth between the string and enum representations of backup types.
2019-08-18 20:09:44 -04:00
David Steele
d0dee2e260 Add bool rendering to jsonFromVar(). 2019-08-17 17:47:13 -04:00
David Steele
8fc1d3883b Fix expire not immediately writing into separate file after backup.
Logging stayed in the backup log until the Perl code started.  Fix this so it logs to the correct file and will still work after the Perl code is removed.
2019-08-17 17:43:56 -04:00
Cynthia Shang
382ed92825 The start/stop commands are implemented entirely in C.
The Perl versions remain because they are still being used by the Perl stanza commands.  Once the stanza commands are migrated they can be removed.

Contributed by Cynthia Shang.
2019-08-09 15:17:18 -04:00
David Steele
e9517dcec0 Add hash constants for zero-length data.
No need to calculate a hash when the data length is known to be zero.  Use one of these constants instead.
2019-08-08 18:47:02 -04:00
David Steele
969e5817c5 Add cvtZToMode().
The companion function to cvtModeToZ().
2019-08-08 11:59:39 -04:00
David Steele
1f93e147fa Add kvGetDefault() to KeyValue object.
Return the default only if the key is not found, not when the value is NULL.
2019-08-08 11:41:49 -04:00
David Steele
289b47902b Allow NULLs in strEq().
Bring this function more in line with the way varEq() works.  NULL == NULL but NULL != NOT NULL.
2019-08-08 10:50:25 -04:00
Cynthia Shang
feec674b6f Add constant for lock file extension.
Contributed by Cynthia Shang.
2019-08-08 06:48:25 -04:00
David Steele
3d3003e9ca The check command is implemented partly in C.
Implement switch WAL and archive check in C but leave the rest in Perl for now.

The main idea was to have some real integration tests for the new database code so the rest of the migration can wait.

Reviewed by Cynthia Shang.
2019-08-01 20:35:01 -04:00
David Steele
e4901d50d5 Add Db object to encapsulate PostgreSQL queries and commands.
Migrate functionality from the Perl Db module to C. For now this is just enough to implement the WAL switch check.

Add the dbGet() helper function to get Db objects easily.

Create macros in harnessPq to make writing pq scripts easier by grouping commonly used functions together.

Reviewed by Cynthia Shang.
2019-08-01 15:38:27 -04:00
David Steele
f9e1f3a798 Retry S3 RequestTimeTooSkewed errors instead of immediately terminating.
The cause of this error seems to be that a failed request takes so long that a subsequent retry at the http level uses outdated headers.

We're not sure if pgBackRest it to blame here (in one case a kernel downgrade fixed it, in another case an incorrect network driver was the problem) so add retries to hopefully deal with the issue if it is not too persistent.  If SSL_write() has long delays before reporting an error then this will obviously affect backup performance.

Reported by sean0101n, Tim Garton, Jesper St John, Aleš Zelený.
2019-08-01 14:28:30 -04:00
David Steele
2eb3c9f95f Improve error handling for SSL_write().
Error codes were not being caught for SSL_write() so it was hard to see exactly what was happening in error cases.  Report errors to aid in debugging.

Also add a retry for SSL_ERROR_WANT_READ.  Even though we have not been able to reproduce this case it is required by SSL_write() so go ahead and implement it.
2019-08-01 09:58:24 -04:00
David Steele
89c67287bc Improve multi-host handling in protocol helper.
Multiple PostgreSQL hosts were supported via the host-id option but there are cases where it is useful to be able to directly specify the host id required, e.g. to iterate through pg* hosts when looking for candidate primaries and standbys during backup.
2019-07-31 20:44:49 -04:00
David Steele
893ae24284 Add timeout to walSegmentFind().
Keep trying to locate the WAL segment until timeout.  This is useful for the check and backup commands which must wait for segments to arrive in the archive.
2019-07-31 19:58:57 -04:00
David Steele
88c1929ec5 Don't pass local config* options to the remote.
The remotes have their own config options (repo-host-config, etc.) so don't pass the local config* options.

This was a regression from the behavior of the Perl code and while there have been no field reports it caused breakage on test systems with multiple configurations.
2019-07-26 08:37:58 -04:00
David Steele
554d98746a Add repo-s3-port option for setting a non-standard S3 service port.
If this option is set then ports appended to repo-s3-endpoint or repo-s3-host will be ignored.

Setting this option explicitly may be the only way to use a bare ipv6 address with S3 (since multiple colons confuse the parser) but we plan to improve this in the future.
2019-07-25 17:36:51 -04:00
David Steele
415542b4a3 Add PostgreSQL query client.
This direct interface to libpq allows simple queries to be run against PostgreSQL and supports timeouts.

Testing is performed using a shim that can use scripted responses to test all aspects of the client code.  The shim will be very useful for testing backup scenarios on complex topologies.

Reviewed by Cynthia Shang.
2019-07-25 14:50:02 -04:00
David Steele
59f135340d The local command for backup is implemented entirely in C.
The local process is now entirely migrated to C.  Since all major I/O operations are performed in the local process, the vast majority of I/O is now performed in C.

Contributed by David Steele, Cynthia Shang.
2019-07-25 14:34:16 -04:00
David Steele
54ec8f151e Add int rendering to jsonFromVar(). 2019-07-24 19:45:35 -04:00
David Steele
615735e7ee Add new types to JSON render.
Add bool, array, and int64 as valid array subtypes.

Pretty print for the array subtype is not correct but is currently not in use (this can be seen at line 328 in typeJsonTest.c).
2019-07-24 06:52:49 -04:00
David Steele
38ba458616 Add IoSink filter.
Discard all data passed to the filter.  Useful for calculating size/checksum on a remote system when no data needs to be returned.

Update ioReadDrain() to automatically use the IoSink filter.
2019-07-18 08:42:42 -04:00
Cynthia Shang
d1dd6add48 Remove never-used infoBackupCheckPg() function.
Contributed by Cynthia Shang.
2019-07-17 16:55:21 -04:00
David Steele
3bdba4933d Fix incorrect handling of transfer-encoding response to HEAD request.
The HTTP server can use either content-length or transfer-encoding to indicate that there is content in the response.  HEAD requests do not include content but return all the same headers as GET.  In the HEAD case we were ignoring content-length but not transfer-encoding which led to unexpected eof errors on AWS S3.  Our test server, minio, uses content-length so this was not caught in integration testing.

Ignore all content for HEAD requests (no matter how it is reported) and add a unit test for transfer-encoding to prevent a regression.

Found by Pavel Suderevsky.
2019-07-17 16:49:42 -04:00
Cynthia Shang
6f981c53bb Remove obsolete ignoreMissing parameter.
Contributed by Cynthia Shang.
2019-07-17 15:44:55 -04:00
David Steele
7662d32e60 Fix comment typos and clarify HEAD response behavior. 2019-07-17 15:42:37 -04:00
David Steele
eee67db4d6 Allow pg storage to be remote.
None of the currently migrated commands needed remote pg storage but now backup, check, stanza-* will need it.
2019-07-17 14:09:50 -04:00
David Steele
30f55a3c2a Add compressed storage feature.
This feature denotes storage that can compress files so that they take up less space than what was written.  Currently this includes the Posix and CIFS drivers.  The stored size of the file will be rechecked after write to determine if the reported size is different.  This check would be wasted on object stores such as S3, and they might not report the file as existing immediately after write.

Also add tests to each storage driver to check features.
2019-07-15 17:36:24 -04:00
David Steele
3e1062825d Allow multiple filters to be pushed to the remote and return results.
Previously only a single filter could be pushed to the remote since order was not being maintained.  Now the filters are strictly ordered.

Results are returned from the remote and set in the local IoFilterGroup so they can be retrieved.

Expand remote filter support to include all filters.
2019-07-15 16:49:46 -04:00
David Steele
d5654375a5 Add ioReadDrain().
Read all data from an IoRead object and discard it.  This is handy for calculating size, hash, etc. when the output is not needed.

Update code where a loop was used before.
2019-07-15 08:44:41 -04:00
David Steele
ede7df9fb1 Allow NULL in JSON list. 2019-07-14 15:53:31 -04:00
David Steele
c836c483dc Add lstClear() to List object. 2019-07-14 15:42:55 -04:00
Cynthia Shang
6a89c1526e Revert a2dcdc07.
It is simpler to implement the required logic in stanza-delete rather than add complexity to this function.

Contributed by Cynthia Shang.
2019-07-10 12:04:25 -04:00
Cynthia Shang
a2dcdc0711 Update lockStopTest() to optionally return a result rather than error.
Some commands (e.g. stanza-delete) would prefer to throw a customized error.

Contributed by Cynthia Shang.
2019-07-09 16:41:58 -04:00
David Steele
b9b21315ea Updates for openssl 1.1.1.
Some HTTP error tests were failing after the upgrade to openssl 1.1.1, though the rest of the unit and integration tests worked fine.  This seemed to be related to the very small messages used in the error testing, but it pointed to an issue with the code not being fully compliant, made worse by auto-retry being enabled by default.

Disable auto-retry and implement better error handling to bring the code in line with openssl recommendations.

There's no evidence this is a problem in the field, but having all the tests pass seems like a good idea and the new code is certainly more robust.

Coverage will be complete in the next commit when openssl 1.1.1 is introduced.
2019-07-02 22:09:12 -04:00
Cynthia Shang
33e3d316d6 Reverse loop in infoPgSave() to be consistent with infoPgNewLoad().
Contributed by Cynthia Shang.
2019-06-26 19:52:04 -04:00
David Steele
4815752ccc Add Perl interface to C storage layer.
Maintaining the storage layer/drivers in two languages is burdensome.  Since the integration tests require the Perl storage layer/drivers we'll need them even after the core code is migrated to C.  Create an interface layer so the Perl code can be removed and new storage drivers/features introduced without adding Perl equivalents.

The goal is to move the integration tests to C so this interface will eventually be removed.  That being the case, the interface was designed for maximum compatibility to ease the transition.  The result looks a bit hacky but we'll improve it as needed until it can be retired.
2019-06-26 08:24:58 -04:00
David Steele
d7f12f268a Redact secure options in the help command.
Secure options could show up in the help as "current".  While the user must have permissions to see the source of the options (e.g. environment, config file) it's still not a good idea to display them in an unexpected context.

Instead show secure options as <redacted> in the help command.
2019-06-24 19:27:13 -04:00
Cynthia Shang
b498188f01 Error on db history mismatch when expiring.
Amend commit 434cd832 to error when the db history in archive.info and backup.info do not match.

The Perl code would attempt to reconcile the history by matching on system id and version but we are not planning to migrate that code to C.  It's possible that there are users with mismatches but if so they should have been getting errors from info for the last six months.  It's easy enough to manually fix these files if there are any mismatches in the field.

Contributed by Cynthia Shang.
2019-06-24 11:59:44 -04:00
David Steele
039e515a31 Allow protocol compression when read/writing remote files.
If the file is compressible (i.e. not encrypted or already compressed) it can be marked as such in storageNewRead()/storageNewWrite().  If the file is being read from/written to a remote it will be compressed in transit using gzip.

Simplify filter group handling by having the IoRead/IoWrite objects create the filter group automatically.  This removes the need for a lot of NULL checking and has a negligible effect on performance since a filter group needs to be created eventually unless the source file is missing.

Allow filters to be created using a VariantList so filter parameters can be passed to the remote.
2019-06-24 10:20:47 -04:00
David Steele
434cd83285 The expire command is implemented entirely in C.
This implementation duplicates the functionality of the Perl code but does so with different logic and includes full unit tests.

Along the way at least one bug was fixed, see issue #748.

Contributed by Cynthia Shang.
2019-06-18 15:19:20 -04:00
David Steele
593446718a Add S3 info type missed in 7f2f5354.
File is the only type possible in S3.
2019-06-18 06:45:47 -04:00
David Steele
ceafd8e19d Migrate page checksum filter to C.
This filter exactly mimics the behavior of the Perl filter so is a drop-in replacement.

The filter is not integrated yet since it requires the Perl-to-C storage layer interface coming in a future commit.
2019-06-17 07:52:03 -04:00
David Steele
892f35a728 Add new types to JSON render.
Still not a complete list, but we are getting there.
2019-06-17 07:42:12 -04:00
Cynthia Shang
c64c9c0590 Add backup management functions to InfoBackup.
Allow current backups to be listed and deleted.

Also expose some constants required by expire and stanza-* commands.

Contributed by Cynthia Shang.
2019-06-17 06:59:06 -04:00
Cynthia Shang
44bafc127d Rename info*New() functions to info*NewLoad().
These names more accurately reflect what the functions do and follow the convention started in Info and InfoPg.

Also remove the ignoreMissing parameter since it was never used.

Contributed by Cynthia Shang.
2019-06-17 06:47:15 -04:00
David Steele
f05fbc54a8 Fix filters not processing when there is no input.
Some filters (e.g. encryption and compression) produce output even if there is no input.  Since the filter group was marked as "done" initially, processing would not run when there was zero input and that resulted in zero output.

All filters start not done so start the filter group the same way.
2019-06-14 08:04:28 -04:00
David Steele
fdd375b63d Integrate S3 storage driver with HTTP client cache.
This allows copying from one S3 object to another.  We generally try to avoid doing this but there are a few cases where it is needed and the tests do it quite a bit.

One thing to look out for here is that reads require the http client to be explicitly released by calling httpClientDone().  This means than clients could grow if they are not released properly.  The http statistics will hopefully alert us if this is happening.
2019-06-11 16:26:32 -04:00
David Steele
ced42d6511 Add HTTP client cache.
This cache manages multiple http clients and returns one to the caller that is not busy.  It is the responsibility of the caller to indicate when they are done with a client. If returnContent is set then the client will automatically be marked done.

Also add special handing for HEAD requests to recognize that content-length is informational only and no content is expected.
2019-06-11 10:48:22 -04:00
David Steele
7f2f535460 Add info() and infoList() to S3 driver.
These should be the last functions required to complete the implementation of the S3 driver.
2019-06-10 16:09:38 -04:00
David Steele
456391f67c Create general-purpose S3 list function.
There are already two functions which need file lists and more on the way, so create a general-purpose function to reduce code duplication.
2019-06-10 12:23:04 -04:00
David Steele
e701e8fd84 Expose storage type.
Code calling the storage should be driver agnostic but knowing the storage type can be useful for debugging and error reporting.
2019-06-05 11:50:49 -04:00
David Steele
6ff3325c77 Enforce requiring repo-cipher-pass at config parse time.
This was not enforced at parse time because repo1-cipher-type could be passed on the command-line even in cases where encryption was not needed by the subprocess.

Filter repo-cipher-type so it is never passed on the command line.  If the subprocess does not have access to the passphrase then knowing the encryption type is useless anyway.
2019-06-05 11:43:17 -04:00
David Steele
aca11b2fa1 Add String to types supported by JSON list render.
All types should be supported eventually but for now this answers the need.
2019-06-04 17:40:27 -04:00
David Steele
0ab6f3bb87 Fix incorrect error type on missing path. 2019-06-04 13:38:05 -04:00
David Steele
4b91259de8 Make working with filter groups less restrictive.
Filter groups could not be manipulated once they had been assigned to an IO object.  Now they can be freely manipulated up to the time the IO object is opened.

Also, move the filter group into the IO object's context so they don't need to be tracked separately.
2019-06-04 12:56:04 -04:00
David Steele
44eb21ea93 Use HEAD to check if a file exists on S3.
The previous implementation searched for the file in a list which worked but was not optimal.  For arbitrary bucket structures it would also produce a false negative if a match was not found in the first 1000 entries.  This was not an issue for our repo structure since the max hits on exists calls is two but it seems worth fixing to avoid future complications.
2019-06-04 10:05:27 -04:00
David Steele
15b8e3b6af Make C S3 requests use the same host logic as Perl.
The C code was passing the host (if specified) with the request which could force the server into path-style URLs, which are not supported.

Instead, use the Perl logic of always passing bucket.endpoint in the request no matter what host is used for the HTTPS connection.

It's an open question whether we should support path-style URLs but since we don't it's useless to tell the server otherwise.  Note that Amazon S3 has deprecated path-style URLs and they are no longer supported on newly created buckets.
2019-06-04 09:39:08 -04:00
David Steele
404284b90f Add internal flag for commands.
Allow commands to be skipped by default in the command help but still work if help is requested for the command directly.  There may be other uses for the flag in the future.

Update help for ls now that it is exposed.
2019-05-28 12:18:05 -04:00
David Steele
20e5b92f36 Add ls command.
Allows listing repo paths/files from the command-line, to be used primarily for testing and debugging.

This command is internal-only so the interface may change at any time without notice.
2019-05-28 10:03:48 -04:00
David Steele
3b3327eae6 Move tls/http statistics output to command/command.
This module already has the filtering required to keep these messages from being displayed by default for commands that output to stdout (e.g. info).
2019-05-28 09:50:59 -04:00
David Steele
a474ba54c5 Refactoring path support in the storage module.
Not all storage types support paths as a physical thing that must be created/destroyed.  Add a feature to determine which drivers use paths and simplify the driver API as much as possible given that knowledge and by implementing as much path logic as possible in the Storage object.

Remove the ignoreMissing parameter from pathSync() since it is not used and makes little sense.

Create a standard list of error messages for the drivers to use and apply them where the code was modified -- there is plenty of work still to be done here.
2019-05-26 12:41:15 -04:00
David Steele
38f28bd520 Log TLS and HTTP statistics on exit.
These stats measure how efficiently TLS and HTTP are reusing connections (i.e. pipelining).
2019-05-26 12:32:49 -04:00
David Steele
d12d94c53c Make info(), pathCreate() and pathSync() optional for storage drivers.
These functions are not required for repository storage so make them optional and error if they are not implemented for non-repository storage, .e.g. pg or spool.

The goal is to simplify the drivers (e.g. S3) that are intended only for repository storage.
2019-05-24 18:09:16 -04:00
David Steele
39645fc1a9 Add pathRemove() and remove() to S3 storage.
These functions will be needed for the expire command.
2019-05-24 14:33:47 -04:00
David Steele
96770c529b storageList() returns an empty list by default for missing paths.
The prior behavior was to return NULL so the caller would know the path was missing, but this is rarely useful, complicates the calling code, and increases the chance of segfaults.

The .nullOnMissing param has been added to enable the prior behavior.
2019-05-24 13:12:56 -04:00
David Steele
ff9c1bed5d Save cipher-pass key/value missed in f492f057.
This value is required when encryption is enabled.

In passing simplify the expression used to skip the checksum when calculating the checksum.
2019-05-22 11:24:18 -04:00
David Steele
3da60f4b5e Don't escape / when rendering JSON.
/ is escaped in the spec but the Perl renderer we use does not escape it which leads to checksum mismatches between the two sets of code.

This particular escape seems to be a more recent addition to the spec and is targeted toward embedding JSON in JavaScript.

\/ is still allowed when parsing JSON.
2019-05-22 11:10:43 -04:00
David Steele
e3fe3434b4 Rename repo-s3-verify-ssl option to repo-s3-verify-tls.
The new name is preferred because pgBackRest does not support any SSL protocol versions (they are all considered to be insecure).

The old name will continue to be accepted.
2019-05-21 10:14:41 -04:00
David Steele
1bc84c6474 The local command for restore is implemented entirely in C.
This is just the part of restore run by the local helper processes, not the entire command.

Even so, various optimizations in the code (like pipelining and optimizations for zero-length files) should make the restore command faster on object stores.
2019-05-20 17:07:37 -04:00
Cynthia Shang
a839830333 Add most unimplemented functions to the remote storage driver.
Add pathCreate(), pathRemove(), pathSync(), and remove() to the driver.

Contributed by Cynthia Shang.
2019-05-20 16:19:14 -04:00
Cynthia Shang
2b75f57232 Add linefeeds for clarity. 2019-05-16 09:56:48 -04:00
David Steele
5c1d4bcd0d Automate coverage summary report generation.
This report replaces the lcov report that was generated manually for each release.

The lcov report was overly verbose just to say that we have virtually 100% coverage.
2019-05-15 13:04:56 -04:00
David Steele
53f6232264 Improve coverage in config/parse module. 2019-05-14 10:35:39 -04:00
David Steele
1e5ab69cad Improve coverage in config/config module. 2019-05-13 19:10:24 -04:00
David Steele
2d2bec842a Improve coverage in perl/exec module. 2019-05-13 13:36:24 -04:00
David Steele
431532574b Add testUser() and testGroup().
Retrieve the name of the current user/group used for testing.
2019-05-13 07:51:11 -04:00
David Steele
31d0fe5f50 Improve log performance, simplify macros, rename logWill() to logAny().
Pre-calculate the value used by logAny() to improve performance and make it more likely to be inlined.

Move IF_LOG_ANY() into LOG_INTERNAL() to simplify the macros and improve performance of LOG() and LOG_PID().  If the message has no chance of being logged there's no reason to call logInternal().

Rename logWill() to logAny() because it seems more intuitive.
2019-05-11 18:20:57 -04:00
David Steele
87f36e814e Improve macros and coverage rules that were hiding missing coverage.
The branch coverage exclusion rules were overly broad and included functions that ended in a capital letter, which disabled all coverage for the statement.  Improve matching so that all characters in the name must be upper-case for a match.

Some macros with internal branches accepted parameters that might contain conditionals.  This made it impossible to tell which branches belonged to which, and in any case an overzealous exclusion rule was ignoring all branches in such cases.  Add the DEBUG_COVERAGE flag to build a modified version of the macros without any internal branches to be used for coverage testing.  In most cases, the branches were optimizations (like checking logWill()) that improve production performance but are not needed for testing.  In other cases, a parameter needed to be added to the underlying function to handle the branch during coverage testing.

Also tweak the coverage rules so that macros without conditionals are automatically excluded from branch coverage as long as they are not themselves a parameter.

Finally, update tests and code where missing coverage was exposed by these changes.  Some code was updated to remove existing coverage exclusions when it was a simple change.
2019-05-11 14:51:51 -04:00
David Steele
f0f105ddec Improve filter's notion of "done" to optimize filter processing.
Filters had different ideas about what "done" meant and this added complication to the group filter processing.  For example, gzip decompression would detect end of stream and mark the filter as done before it had been flushed.

Improve the IoFilter interface to give a consistent definition of done across all filters, i.e. no filter can be done until it has started flushing no matter what the underlying driver reports.  This removes quite a bit of tricky logic in the processing loop which tried to determine when a filter was "really" done.

Also improve management of the input buffers by pointing directly to the prior output buffer (or the caller's input) to eliminate loops that set/cleared these buffers.
2019-05-09 12:10:46 -04:00
David Steele
d5fac35fe3 Improve zero-length content handling in HttpClient object.
If content was zero-length then the IO object was not created.  This put the burden on the caller to test that the IO object existed before checking eof.

Instead, create an IO object even if it will immediately return eof.  This has little cost and makes the calling code simpler.

Also add an explicit test for zero-length files in S3 and a few assertions.
2019-05-09 09:53:24 -04:00
David Steele
15531151d7 Add --c option to request a C remote.
The rules for when a C remote is required are getting complicated and will get worse when restoreFile() is migrated.

Instead, set the --c option when a C remote is required.  This option will be removed when the remote is entirely implemented in C.
2019-05-09 08:55:48 -04:00
David Steele
c99c7c458b Add pathExists() to Storage object.
The S3 driver did not get an implementation since S3 has a weak notion of paths, and it is not currently required.
2019-05-09 08:28:58 -04:00
David Steele
f1eea23121 Add macros for object free functions.
Most of the *Free() functions are pretty generic so add macros to make creating them as easy as possible.

Create a distinction between *Free() functions that the caller uses to free memory and callbacks that free third-party resources.  There are a number of cases where a driver needs to free resources but does not need a normal *Free() because it is handled by the interface.

Add common/object.h for macros that make object maintenance easier.  This pattern can also be used for many more object functions.
2019-05-03 18:52:54 -04:00
David Steele
7ae96949f1 Various MemContext callback improvements.
Rename memContextCallback() to memContextCallbackSet() to be more consistent with other parts of the code.

Free all context memory when an exception is thrown from a callback.  Previously only the child contexts would be freed and this resulted in some allocations being lost.  In practice this is probably not a big deal since the process will likely terminate shortly, but there may well be cases where that is not true.
2019-05-03 18:09:58 -04:00
David Steele
4a20d44c6b Add common/macro.h for general-purpose macros.
Add GLUE() macro which is useful for creating identifiers.

Move MACRO_TO_STR() here and rename it STRINGIFY().  This appears to be the standard name for this type of macro and it is also an awesome name.
2019-05-03 17:49:57 -04:00
David Steele
32ca27a20b Simplify storage object names.
Remove "File" and "Driver" from object names so they are shorter and easier to keep consistent.

Also remove the "driver" directory so storage implementations are visible directly under "storage".
2019-05-03 15:46:15 -04:00
David Steele
8c712d89eb Improve type safety of interfaces and drivers.
The function pointer casting used when creating drivers made changing interfaces difficult and led to slightly divergent driver implementations.  Unit testing caught production-level errors but there were a lot of small issues and the process was harder than it should have been.

Use void pointers instead so that no casts are required.  Introduce the THIS_VOID and THIS() macros to make dealing with void pointers a little safer.

Since we don't want to expose void pointers in header files, driver functions have been removed from the headers and the various driver objects return their interface type.  This cuts down on accessor methods and the vast majority of those functions were not being used.  Move functions that are still required to .intern.h.

Remove the special "C" crypto functions that were used in libc and instead use the standard interface.
2019-05-02 17:52:24 -04:00
David Steele
498017bcf0 Various Buffer improvements.
Add bufDup() and bufNewUsedC().

Arrange bufNewC() params to match bufNewUsedC() since they have always seemed backward.

Fix bufHex() to only render the used portion of the buffer and fix some places where used was not being set correctly.

Use a union to make macro assignments for all legal values without casting.  This is much more likely to catch bad assignments.
2019-05-02 12:43:09 -04:00
David Steele
59234f249e Use THROW_ON_SYS_ERROR*() to improve code coverage.
There is only one instance in the core code where this helps. It is mostly helpful in the tests.

There is an argument to be made that only THROW_SYS_ERROR*() variants should be used in the core code to improve test coverage.  If so, that will be the subject of a future commit.
2019-04-29 18:36:57 -04:00
David Steele
683b096e18 Don't append strerror() to error message when errno is 0.
Some functions (e.g. getpwnam()/getgrnam()) will return an error but not set errno.  In this case there's no use in appending strerror(), which will be "Success".  This is confusing since an error has just been reported.

At least in the examples above, an error with no errno set just means "missing" and our current error message already conveys that.
2019-04-29 18:03:32 -04:00
David Steele
af33126cb6 Allow StorageFileWrite to set user, group, and modification time.
The S3 driver will throw an error if these options are set since they are not supported.
2019-04-29 17:17:14 -04:00
David Steele
d0c296bd5b Fix segfault when process-max > 8 for archive-push/archive-get.
The remote list was at most 9 (based on pg[1-8]-* max index) so anything over 8 wrote into unallocated memory.

The remote for the main process is (currently) stored in position zero so do the same for remotes started from locals, since there should only be one.  The main process will need to start more remotes in the future which is why there is extra space.

Reported by Jens Wilke.
2019-04-29 16:10:27 -04:00
David Steele
c935b1c9e8 Add missing httpUriEncode() in S3 request.
This was not a live bug since the files currently handled by C can't have special characters in them.
2019-04-29 15:20:54 -04:00
David Steele
62b48d8a5a Allow storageInfo() to follow links.
This allows info to be retrieved from linked files/paths in a single step.
2019-04-29 15:14:10 -04:00
David Steele
60edadf71d Expose handle (file descriptor) from IoWrite when applicable.
This is a followup to dee90d3e which exposed file handles for IoRead.

Also expose handle for StorageDriverPosixFileRead missed in dee90d3e.
2019-04-29 14:54:49 -04:00
David Steele
52b0b81976 Add storageInfoList() to get detailed info about all entries in a path.
The function provides all the file/path/link information required to build a backup manifest.

Also update storageInfo() to provide the same information for a single file.
2019-04-23 19:33:55 -04:00
David Steele
f492f0571b Add *Save() functions to most Info objects.
At the same time change the way that load constructors work (and are named) so that Ini objects do not persist after the constructors complete.

infoArchiveSave() is excluded from this commit since it is just a trivial call to infoPgSave() and won't be required soon.
2019-04-23 17:08:34 -04:00
David Steele
f41112a463 Add harnessInfoChecksum/Z() to ease creation of test info files. 2019-04-23 14:02:30 -04:00
David Steele
aebac47cd5 Extern infoHash() so it can be used by other modules.
This is currently needed only for testing, but there's no reason not to expose the function to everyone.
2019-04-23 13:58:19 -04:00
David Steele
cddb0c05b4 Add iniSave() and iniMove() to Ini object.
iniSave() sorts alphabetically to maintain compatibility with the expect tests, but we plan to change this behavior when the migration is complete.
2019-04-23 13:03:22 -04:00
David Steele
c650134a04 Add ioWriteStr() and ioWriteStrLine().
These function names make it clearer what is being written.

The old ioWriteLine() has been repurposed to write buffers.
2019-04-22 18:46:29 -04:00
David Steele
81f652137c Add separate functions to encode/decode each JSON type.
In most cases the JSON type is known so this is more efficient than converting to Variant first, both in terms of memory and time.

Also rename some of the existing functions for consistency.
2019-04-22 18:41:01 -04:00
David Steele
47491e3c47 varNewKv() accepts a KeyValue object rather than creating one.
This allows for more flexibility about when the Variant is created.
2019-04-22 16:04:04 -04:00
David Steele
fdf19e5ab6 Refactor Ini interface to expose String values instead of Variant.
Variants were being used to expose String and StringList types but this can be done more simply with an additional method.

Using only strings also allows for a more efficient implementation down the road.
2019-04-22 09:00:50 -04:00
David Steele
e7255be108 Only process next filter in IoFilterGroup when input buffer is full or flushing.
This greatly reduces calls to filter processing, which is a performance benefit, but also makes the trace logs smaller and easier to read.

However, this means that ioWriteFlush() will no longer work with filters since a full flush of IoFilterGroup would require an expensive reset.  Currently ioWriteFlush() is not used in this scenario so for now just add an assert to ensure it stays that way.
2019-04-20 11:25:04 -04:00
David Steele
e513c52c09 Add macros to create constant Buffer objects.
These are more efficient than creating buffers in place when needed.

After replacement discovered that bufNewStr() and BufNewZ() were not being used in the core code so removed them.  This required using the macros in tests which is not the usual pattern.
2019-04-20 08:16:17 -04:00
David Steele
c9168028c6 Improve performance of non-blocking reads by using maximum buffer size.
Since the introduction of blocking read drivers (e.g. IoHandleRead, TlsClient) the non-blocking drivers have used the same rules for determining maximum buffer size, i.e. read only as much as requested.  This is necessary so the blocking drivers don't get stuck waiting for data that might not be coming.

Instead mark blocking drivers so IoRead knows how much buffer to allow for the read.  The non-blocking drivers can now request the maximum number of bytes allowed by buffer-size.
2019-04-19 14:38:11 -04:00
David Steele
0c866f52c6 Update code to use new unsigned int Variant type and config methods. 2019-04-19 11:40:39 -04:00
David Steele
9f0829cbf2 Add cfgOptionUInt() and cfgOptionUInt64().
These are better than casting from cfgOptionInt() since bounds checking is performed.
2019-04-19 11:29:08 -04:00
David Steele
1adcbc5c91 Add unsigned int Variant type.
This is better than using (unsigned int)varUInt64() because bounds checking is performed.
2019-04-19 11:22:43 -04:00
David Steele
7390952d8e Harden IO filters against zero input and optimize zero output case.
Add production checks to ensure no filter gets a zero-size input buffer.

Also, optimize the case where a filter returns no output.  There's no sense in running downstream filters if they have no new input.
2019-04-18 21:24:10 -04:00
David Steele
2d73de1d36 Fix zero-length reads causing problems for IO filters that did not expect them.
The IoRead object was passing zero-length buffers into the filter processing code but not all the filters were happy about getting them.

In particular, the gzip compression filter failed if it was given no input directly after it had flushed all of its buffers.  This made the problem rather intermittent even though a zero-length buffer was being passed to the filter at the end of every file.  It also explains why tweaking compress-level or buffer-size allowed the file to go through.

Since this error was happening after all processing had completed, there does not appear to be any risk that successfully processed files were corrupted.

Reported by brunre01, jwpit, Tomasz Kontusz, guruguruguru.
2019-04-18 21:21:35 -04:00
David Steele
b960919cf7 Fix reliability of error reporting from local/remote processes.
Asserts were only only reported on stderr rather than being returned through the protocol layer.  This did not appear to be very reliable.

Instead, report the assert through the protocol layer like any other error.  Add a stack trace if an assert error or debug logging is enabled.
2019-04-18 10:36:21 -04:00
David Steele
0d4ba3a39f Fix Posix/CIFS error messages reporting the wrong filename on write/sync/close.
The reported file name was the destination file, not the temp file that is written to during atomic write operations.
2019-04-17 18:18:55 -04:00
David Steele
4c13955c05 Add macros to create constant Variant types.
These work almost exactly like the String constant macros. However, a struct per variant type was required which meant custom constructors and destructors for each type.

Propagate the variant constants out into the codebase wherever they are useful.
2019-04-17 08:04:22 -04:00
David Steele
2dac4b5986 Add STR() macro to create constant String objects from runtime strings.
The STRING_CONST() macro worked fine for constants but was not able to constify strings created at runtime.

Add the STR() macro to do this by using strlen() to get the size.

Also rename STRING_CONST() to STRDEF() for brevity and to match the other macro name.
2019-04-16 13:39:58 -04:00
David Steele
a029eba8d5 Use a macro instead of a nested struct to create common String variables.
This makes the code a bit less obfuscated while still ensuring that these variables will be common to both String structures.
2019-04-16 13:18:30 -04:00
Cynthia Shang
a7281878ac Migrate backupRegExp() to C.
Removed the "anchor" parameter because it was never used in any calls in the Perl code so it was just a dead parameter that always defaulted to true.

Contributed by Cynthia Shang.
2019-04-15 08:29:25 -04:00
David Steele
df12cbb162 Fix C code to recognize host:port format like Perl does.
This was not an intentional feature in Perl, but it works, so it makes sense to implement the same syntax in C.

This is a break from other places where a -port option is explicitly supplied, so it may make sense to support both styles going forward.  This commit does not address that, however.

Reported by Kyle Nevins.
2019-04-10 17:48:34 -04:00
David Steele
25cea0bd0a Add process id to C archive-get and archive-push logging.
This was missed in the original migration.  There was no functional issue, but logging the process ids is useful for debugging.
2019-04-09 11:08:27 -04:00
David Steele
8c202c77da Add process id to ProtocolParallelJob.
This exposes the process that performed to job to the caller for logging purposes.
2019-04-09 11:01:35 -04:00
David Steele
4ace7edbd9 Allow process id in C logging
The default process id in C logging has always been zero.  This should have been updated when multi-processing was introduced in C, but it was missed.
2019-04-09 10:54:36 -04:00
David Steele
6099729e92 Improve error message when an S3 bucket name contains dots.
The Perl lib we have been using for TLS allows dots in wildcards, but this is forbidden by RFC-2818.  The new TLS implementation in C forbids this pattern, just as PostgreSQL and curl do.

However, this does present a problem for users who have been using bucket names with dots in older versions of pgBackRest.  Since this limitation exists for security reasons there appears to be no option but to take a hard line and do our best to notify the user of the issue as clearly as possible.
2019-04-08 19:38:06 -04:00
David Steele
21c83eea59 Fix issue setting log-level-file=off for the archive-get command.
This problem was not specific to archive-get, but that was the only place it was expressing in the last release.  The new archive-push was also affected.

The issue was with daemon processes that had closed all their file descriptors.  When exec'ing and setting up pipes to communicate with a child process the dup2() function created file descriptors that overlapped with the first descriptor (stdout) that was being duped into.  This descriptor was subsequently closed and wackiness ensued.

If logging was enabled (the default) that increased all the file descriptors by one and everything worked.

Fix this by checking if the file descriptor to be closed is the same one being dup'd into.  This solution may not be generally applicable but it works fine in this case.

Reported by Brad Nicholson.
2019-04-08 17:21:20 -04:00
David Steele
8ac422dca9 Close log file before exec().
The log file should be closed before exec() so the child process does not retain a reference to it.
2019-04-07 21:09:29 -04:00
David Steele
9f3425f6dd Skip coverage for macros with numbers in their name.
This was an oversight in the old regular expression.
2019-04-07 18:47:04 -04:00
David Steele
9a7eab9428 Allow three-digits process IDs in logging.
This is required to support process-max > 99 or else there will be formatting/alignment issues in the logs.
2019-04-07 18:12:07 -04:00
Cynthia Shang
5504f286eb Add test and asserts missed in abba2bd1.
Contributed by Cynthia Shang.
2019-04-03 12:32:56 +01:00
David Steele
4c63279a19 Add forkSafe() to handle fork errors.
fork() rarely fails but we should definitely detect when it does so.
2019-04-02 13:50:02 +01:00
David Steele
1b48684713 The archive-push command is implemented entirely in C.
This new implementation should behave exactly like the old Perl code with the exception of updated log messages.

Remove as much of the Perl code as possible without breaking other commands.
2019-03-29 13:26:33 +00:00
David Steele
251dbede8f Add locking capability to the remote command.
When a repository server is configured, commands that modify the repository acquire a remote lock as well as a local lock for extra protection against multiple writers.

Instead of the custom logic used in Perl, make remote locking part of the command configuration.

This also means that the C remote needs the stanza since it is used to construct the lock name.  We may need to revisit this at a later date.
2019-03-27 21:14:06 +00:00
David Steele
7db8cedd68 Add protocolKeepAlive() to send noops to all remotes.
While the local processes are doing their jobs the remote connection from the main process may timeout.

Send occasional noops to ensure that doesn't happen.
2019-03-27 20:59:28 +00:00
David Steele
f8cbf5d78c Add TEST_64BIT() macro to detect 64-bit platforms.
This may not be the best way to detect 64-bit platforms but it seems to be working fine so far.

Create a macro to make it clearer what is being done and to make it easier to change the implementation.
2019-03-27 20:52:23 +00:00
David Steele
1fa103a4d2 Fix missing semicolon in code example. 2019-03-27 18:14:00 +02:00
David Steele
3181cd0ab8 Set WAL long header flag in test function missed in e938a892.
This was missed because the unit tests were reusing a buffer without resetting it to zero, so this flag ended up still set when the test function was called.

This was not a live issue since it only expressed in tests and this code is not used in master yet.
2019-03-26 18:46:44 +02:00
David Steele
5ee8388f48 Build test harness with the same warnings as code being tested.
The test harness was not being built with warnings which caused some wackiness with an improperly structured switch.  Just use the same warnings as the code being tested.

Also enable warnings on code that is not directly being tested since other code modules are frequently modified during testing.
2019-03-26 08:20:55 +02:00
David Steele
abba2bd132 Add strLstMergeAnti() for merge anti-joins.
We deal with some pretty big lists in archive-push so a nested-loop anti-join looked like it would not be efficient enough.

This merge anti-join should do the trick even though both lists must be sorted first.
2019-03-25 20:35:20 +04:00
David Steele
538e2c7474 Add storagePg()/storagePgWrite() to storage helper.
Add read/write storage helper functions for the PostgreSQL data directory.
2019-03-25 09:45:36 +04:00
David Steele
444b4f8640 Allow warnings to be written by archiveAsyncStatusOkWrite().
Migrate this feature to the C code since archive-push will need it.
2019-03-25 09:17:15 +04:00
David Steele
8820d69574 Use a single file to handle global errors in async archiving.
The prior behavior on a global error (i.e. not file specific) was to write an individual error file for each WAL file being processed.  On retry each of these error files would be removed, and if the error was persistent, they would then be recreated.  In a busy environment this could mean tens or hundreds of thousands of files.

Another issue was that the error files could not be written until a list of WAL files to process had been generated.  This was easy enough for archive-get but archive-push requires more processing and any errors that happened when generating the list would only be reported in the pgBackRest log rather than the PostgreSQL log.

Instead write a global.error file that applies to any WAL file that does not have an explicit ok or error file.  This reduces churn and allows more errors to be reported directly to PostgreSQL.
2019-03-25 08:12:38 +04:00
David Steele
1fff60ad2a Remove unused infoArchiveCheckPg() function.
The idea was to use this function for archive-push, but in the end archive-push required two very different versions of the function.
2019-03-24 14:34:45 +04:00
David Steele
7cf7373761 Refactor PostgreSQL interface to remove most code duplication.
Having a copy per version worked well until it was time to add new features or modify existing functions.  Then it was necessary to modify every version and try to keep them all in sync.

Consolidate all the PostgreSQL types into a single file using #if for type versions.  Many types do not change or change infrequently so this cuts down on duplication.  In addition, it is far easier to see what has changed when a new version is added.

Use macros to write the interface functions.  There is still duplication here since some changes require a new copy of the macro, but it is far less than before.
2019-03-21 21:11:36 +04:00
David Steele
e938a89250 Add WAL info to PostgreSQL interface.
This allows the WAL header to be read for any supported version on PostgreSQL.
2019-03-19 19:44:06 +04:00
David Steele
856a369b86 Add file write to the S3 storage driver.
Now that repositories are writable the storage drivers that don't yet support file writes need to be updated to do so.

Note that the part size for multi-part upload has not been defined as a proper constant.  This will become an option in the near future so it doesn't seem worth creating a constant that we might then forget to remove.
2019-03-17 22:00:54 +04:00
David Steele
7193738288 Add document creation to XML objects.
The xml objects only exposed read methods of the underlying libxml2.

This worked for S3 commands that only received data but to send data we need to be able to create XML documents from scratch.

Add the ability to create empty documents and add nodes and contents.
2019-03-17 21:38:07 +04:00
David Steele
8ebc6d6c34 Add file write to the remote storage driver.
Now that repositories are writable the storage drivers that don't yet support file writes need to be updated to do so.
2019-03-16 21:50:19 +04:00
David Steele
2d386cd266 Move WAL path prefix logic into walPath().
This logic is used by both archive-push and archive-get.
2019-03-16 16:14:10 +04:00
David Steele
12273a1034 Add storageRepoWrite() to storage helper.
Writable repos are allowed with the addition of the CIFS driver, so add a helper function.
2019-03-16 15:48:50 +04:00
David Steele
66c2f4cd2e Make notion of current PostgreSQL info ID in C align with Perl.
The C code was assuming that the current PostgreSQL version in archive.info/backup.info was the most recent item in the history, but this is not always the case with some stanza-upgrade scenarios.  If a cluster is restored from before the upgrade and stanza-upgrade is run again, it will revert db-id to the original history item.

Instead, load db-id from the db section explicitly as the Perl code does.

This did not affect archive-get since it does a reverse scan through the history versions and does not rely on the current version.
2019-03-16 15:27:38 +04:00