Better error message when trying to backup a DB to itself#8944
Better error message when trying to backup a DB to itself#8944kdmtctl wants to merge 3 commits intoFirebirdSQL:masterfrom
Conversation
When gbak -b is called with a database alias as source and the resolved path as destination (e.g., gbak -b db_alias /path/to/db.gdb), the duplicate file check in the validation loop only compared raw strings, missing the overlap. This could silently overwrite the live database with backup data. Enhance the existing all-pairs file comparison loop to expand both paths via expandDatabaseName() (already used for one side) and emit the correct error: msg 11 (input and output have the same name) when source matches a destination, msg 9 (multiple sources or destinations) for duplicate destinations.
|
I would suggest to add inability to open existing file for write (unless |
This can be implemented by adding O_EXCL to the open() flags on Linux (burp.cpp:2224) and changing CREATE_ALWAYS to CREATE_NEW on Windows (burp.cpp:2221), then adding something like But this is a breaking change and some backup scripts should be updated to this behavior. |
|
Yes, and this is fine for |
gbak -b now refuses to overwrite an existing file at the destination path unless -OV(ERWRITE) is explicitly passed. This mirrors the existing RECREATE vs RECREATE OVERWRITE guardrail on the restore side. - Register IN_SW_BURP_OVERWRITE (58) with min prefix 2 (OV) - Add gbl_sw_backup_overwrite flag to BurpGlobals - Use O_EXCL (Unix) / CREATE_NEW (Windows) when opening backup files unless -OVERWRITE is specified - Emit msg 424 on EEXIST/ERROR_FILE_EXISTS instead of generic msg 65 - Apply same treatment to split-backup volumes in mvol.cpp
|
May be for the sake of consistency it would be better to reuse |
So it the complete forced overwrite command should be |
|
Tests. Didn't copy messages file though. But the error code is correct. |
|
This is a CLI-only patch. I just glanced at how the Services API will call it. I noticed the parameters bitmask we would have to add to support the new one. Should we tackle this too? |
Yes, I think it would a better match for restore command |
dyemanov
left a comment
There was a problem hiding this comment.
Implementation is not consistent with what we had previously for RECREATE. It uses OVERWRITE as a optional command modifier:
-RECREATE [OVERWRITE] ...
and OVERWRITE is not expected outside the RECREATE command.
But the new code uses OVERWRITE as a regular top-level switch:
-BACKUP [-OVERWRITE] ...
I'm not going to argue what approach is better, but I'd rather respect the existing syntax for RECREATE and do the same for BACKUP. Just find out how BURP_SW_OVERWRITE is handled for recreate and do the same for backup.
src/burp/burp.h
Outdated
| bool gbl_sw_mode_val; | ||
| bool gbl_sw_overwrite; | ||
| bool gbl_sw_direct_io; | ||
| bool gbl_sw_backup_overwrite; |
There was a problem hiding this comment.
I'd better reuse the existing gbl_sw_overwrite option. Backup and restore are mutually exclusive commands.
On restore I can do either. Just need a final decision from maintainers: |
Per review feedback, align backup's overwrite syntax with the existing RECREATE [OVERWRITE] pattern on the restore side: - Removed IN_SW_BURP_OVERWRITE switch and gbl_sw_backup_overwrite flag - OVERWRITE is now a positional argument to -B(ACKUP_DATABASE), parsed the same way as RECREATE's optional OVERWRITE modifier - Reuse existing BURP_SW_OVERWRITE string constant and gbl_sw_overwrite flag Syntax: gbak -b <db> <file> error if backup file already exists gbak -b OVERWRITE <db> <file> allow overwriting existing backup file
|
@dyemanov You're right. OVERWRITE should be a positional argument. The new commit matches the existing RECREATE pattern, using the same @aafemt Here is the full picture after the last commit: Restore:
Backup:
|
In Firebird 2.5,
gbakdoes not check whether the source and destination resolve to the same file during backup. Runninggbak -b db_alias /path/to/db.gdbwhere the alias resolves to the same path silently overwrites the live database with backup data. We lost a database this way.Trying to fix this on master, I found that Firebird 5 already catches this case in the all-pairs file comparison loop — but reports the wrong error message. Both source equals destination and duplicate destination checks matches report msg 9 ("multiple sources or destinations specified"), which is confusing while the actual problem is that the source database and backup destination resolve to the same path via alias.
This patch separates the error messages: msg 11 ("input and output have the same name") when the source matches a destination, msg 9 when duplicate destinations are specified.
What changed
In
src/burp/burp.cpp, the existing all-pairs comparison loop (which already expands both sides viaexpandDatabaseName()) now checks whether the match involves the first file (source). If so, it emits msg 11 instead of msg 9.Tested on par with Firebird 5.0.1.1469
Patched binary built with GCC 13.3.1 (gcc-toolset-13) in AlmaLinux 9 container, tested against a live Firebird 5.0.1 instance.