Commit Graph
316 Commits
Author SHA1 Message Date
Carl Johnsen 1ad2344e99 ParallelScanner may be null 2026-02-27 15:36:03 +01:00
Carl Johnsen 0268da5ef6 Fixed race condition where the source provider would be disposed before the parallel scanner was done accessing it. 2026-02-27 13:51:05 +01:00
Kenneth Skovhede e7aa60fba0 Handle duplicate source paths
This PR adds guards to prevent creating filesets with multiple files that have the same path.

While it should technically be impossible to have multiple entries that have the same path, it could happend either due to glitches or because the source data (manual lists, remote sources, etc) returns duplicates.

This PR adds a simple check for each folder to ensure that on a folder-level, duplicate paths cannot be introduced.

There is also a post-backup check to evict any duplicates, and the recreate process will reject duplicate paths.

Finally, the repair command will remove duplicates if they somehow manage to get into the database anyway.

A database-level prevention is not currently feasible as it needs a cross-table check for uniqueness, which requires more work from the database to check for each added file. Since this is expected to be a very rare event, the added processing was not justified.
2026-02-05 11:06:41 +01:00
Kenneth SkovhedeandGitHub e61fadf40f Merge pull request #6732 from duplicati/feature/improve-support-for-remote-source
Extended support for remote sources
2026-01-30 08:27:24 +01:00
Kenneth Skovhede 7cebb96e95 Fixed an issue with mount points not always being recorded as folders 2026-01-29 21:19:15 +01:00
Kenneth Skovhede a986a13abf Fixed dry-run command
This PR adds fixes to honor the --dry-run option to avoid surprises when running an operation.

This fixes #6573
This closes #6581
2026-01-27 15:01:34 +01:00
Kenneth Skovhede 83779a9486 Minor fixes
- Added Cloudflare to list of known S3 provider domains.
- Removed AWS specific naming on the help texts.
- Fixed an edge case where calculating how many files to test with an empty list would crash
- Fixed a bug with getting a safe display url for very short urls
2026-01-06 09:48:23 +01:00
Kenneth Skovhede 6e6e993765 Fixed issues with database transaction not being comitted.
Renamed the options to be more descriptive.
Rewrote the dependency query to be more readable and also check for metadata dependency.

Fixed an edge case where there were no modified files, and no new backup is created.

Fixed some issues with local/utc datetime compares.

Fixed logic for deleting filesets to only look at the filesets themselves. This makes the version lock follow the dlist file, and can create "dangling" volumes that have no filesets, but these will be picked up by compaction.

Updated tests to work correctly.

Added lock-info update option for the backup recreate call, so the UI can also re-create lock information on database rebuilds.
2025-12-17 22:27:38 +01:00
Kenneth Skovhede 0f81b42146 Add support for remote locks
This PR adds support for locking files if the backend supports it.

To activate locking, set the option `--file-lock-duration=30D` and the backup will lock the files.

If the database is rebuilt with the intention of continuing the backups, use the option `--repair-refresh-lock-info` which will update lock information in the database after recreating the database.

The locking works by asking the backend to lock files after a backup has completed.

The implementation keeps track of which files are currently assigned a lock and prevents attempting to delete the files that are currently locked.

Note that the bucket should not have a default lock policy as Duplicati needs to finish the backup before the locking is applied.

In this initial version, Azure Blob Storage, B2, S3 and iDrive are supported with locking.

The CLI is updated to allow setting locks on a specific version. The backend tool is updated to allow setting locks on specific files.
2025-12-14 17:17:48 +01:00
Kenneth Skovhede e1b9015a85 Added support for exclusion of files based on xattrs
This PR adds detection of exclusion attributes on files and folders. If a file or folder has an exclusion extended attribute, the file or folder is excluded from the backup.

The option `--disable-backup-exclusion-xattr` can be used to revert to the previous behavior where the xattrs were not checked.

This has the biggest impact on MacOS where it will not perform like other backup software and avoid files that are marked as excluded from backup.

This fixes #6393
2025-11-21 10:59:28 +01:00
Kenneth Skovhede 3b695cf065 Added support for Photos on MacOS
This PR adds detection of the MacOS Photos folder, and intercepts reads and replaces them with PhotoKit calls.
With this, it is possible to make backups of all MacOS Photos, even if they are not stored locally.

The previous versions would just make a backup of the on-disk structure, which was not guaranteed to contain all photos, but instead has various indexing for finding photos, and may contain some original photos.

The option `--photos-handling` controls how Duplicati now deals with the Photos folder. The options are:
- `LibraryOnly`: Same as before, just treat it as a folder
- `PhotosOnly`: Ignore the folder contents and just back up the actual photos
- `PhotosAndLibrary` (default): Make a backup of the photos and the library on-disk. This may cause images to be stored twice, but de-duplication will usually limit the storage increase.

The option `--photos-library-path` can be used to point to the on-disk Photo library that should be handled, in case the auto-detection does not pick it up. If this does not point to a valid Photoslibrary, or the path is not being backed up, no special handling will be done.

Note that the restore is not restoring into Photos itself, but instead restores into a sub-folder in the Photolibrary that is called `dup_backup`. To get the photos out after a restore, one needs to right-click the Photolibrary folder, and choose "Show package contents" and then the `dup_backup` folder is revealed.

This is done to keep all photos in the same folder, but avoid messing with the structure of the on-disk Photolibrary.

A future update could allow restoring back into Photos, and metadata is captured for each image to eventually allow this.

This fixes #6381
2025-11-17 17:12:10 +01:00
Kenneth Skovhede 46428936c4 Various updates after the upgrade 2025-11-14 15:45:19 +01:00
Kenneth Skovhede 6502017c57 Merge remote-tracking branch 'origin/master' into feature/vanara-vss-backup 2025-07-03 17:09:30 +02:00
Kenneth Skovhede 98deb8c576 Update support for VSS
This updates VSS to default use Vanara in favor of AlphaVSS which is no longer maintained.

The build for Vanara requires targeting `net8.0-windows7.0`, which will cause significant build overhead and complexity for cross platform builds.
To counter this, the setup is to have a single project, `Duplicati.Library.WindowsModules`, that is targeting `net8.0-windows7.0`.
The output from this project is then hoisted into the TrayIcon project for Windows builds so the files are available when debugging on Windows.
A top-level dummy executable project is added to ensure the project always builds.
The built modules are then loaded with reflection when requested.

With the use of Vanara there is now also support for using BackupRead to read files without making a VSS snapshot.
With BackupRead, it is possible to read locked files, but it still requires the SeBackupPrivilege as VSS does as well.

Unfortunately, the `vssapi.dll` file is not shipped for Arm64 on Windows, so even with Vanara this will not work, and only WMIC is supported on Arm64.
A workaround is to run Duplicati with x64 emulation if more advanced VSS features are needed (HyperV and MSSQL support).

This PR also updates options and filters out unsupported options for each operating system, so options that are not supported by the current OS are not reported and will give warnings if they are used, as opposed to just being ignored.

The release builder project has been updated to exclude the unused project, and purge unwanted outputs.
2025-07-01 16:32:19 +02:00
Carl Johnsen 31c5441bdb Forwarded cancellation tokens, added some missing .ConfigureAwait() and added some missing docstrings 2025-06-19 11:04:09 +02:00
Carl Johnsen 32efa4b845 Updated all of the handler calls to database methods to forward their cancellation token 2025-06-19 09:47:33 +02:00
Carl Johnsen 9ac583db94 Made all relevant using statements use await to use DisposeAsync 2025-06-18 11:53:11 +02:00
Carl Johnsen 859b65054d Simplified using statements that uses databases or accesses their methods 2025-06-18 11:52:05 +02:00
Carl Johnsen 3d11a05400 Added .ConfigureAwait(false) to all of the await statements 2025-06-12 08:34:29 +02:00
Carl Johnsen bd493638af Merge branch 'master' into performance/mssqlite-async 2025-06-02 10:39:33 +02:00
Kenneth Skovhede c8b9fb5c73 Websocket subscriptions
This PR adds the ability to subscribe to messages over a websocket.

To prevent polling data, the server can now push messages through the websocket, so the client can instantly update when new data is available.

The change is backwards compatible, still serving the status updates over the socket. If the client is providing the authentication token, it is auto-subscried to the legacy status message.

If the client is using the new authentication message, it needs to subscribe to get the status updates (and any other services it needs).

The event system has been extended to support new, and more accurate, events. This is the first step towards removing the general status update and the long-poll mechanism.

This also re-introduces the blocking marker, so the client can know if the operation is halted due to too many pending transfers.

Some endpoints have been moved to service implementations, to allow serving the exact same data from both endpoints and websocket.

This PR also updates the way the progress is handled, so that all transfers are returned to the client, and the transfer speeds for each transfer is calculated based on a small sample buffer, so the values are more accurate even if the program is paused during transfers.
2025-05-27 12:13:07 +02:00
Carl Johnsen 26e738e8d6 The databases may still need to use the transaction when disposing for running PRAGMA optimize 2025-05-26 09:02:52 +02:00
Carl Johnsen dc4ef34cbd Since transactions are now shared across the lifespan of a database object, the transaction shouldn't be disposed halfway through. 2025-05-22 15:29:48 +02:00
Carl Johnsen 4ffbc36abf IAsyncEnumerable was being chained incorrectly 2025-05-22 15:29:10 +02:00
Carl Johnsen cdba7ef6e9 Updated Utility to use the new async database methods 2025-05-22 08:25:25 +02:00
Carl Johnsen d02608f925 Updated the BackupHandler to use the new async database methods 2025-05-21 15:30:54 +02:00
Carl Johnsen 6dc40fc5a7 Removed whitespace 2025-05-21 15:29:55 +02:00
Kenneth Skovhede 0df9d67a6a Implemented handling for cases where the previous fileset ends up being empty and removed.
This fixes #5862
2025-05-14 23:36:48 +02:00
Kenneth Skovhede 5378e9128f Fixed race on dispose where transactions can be double comitted 2025-05-14 20:39:55 +02:00
Kenneth Skovhede 75f7582014 Fixed passing transaction to more places 2025-04-24 20:28:26 +02:00
Kenneth Skovhede 3ff868b0f9 Removed tracking of files sizes, and implemented it with a database lookup 2025-04-23 15:39:32 +02:00
Kenneth Skovhede 66862043b6 Fixed a case where the transactions were not used, despite being active 2025-04-23 13:44:46 +02:00
Kenneth Skovhede 7be9678080 Fixed handling promotion of pending upload to actual filelist 2025-04-23 11:48:35 +02:00
Kenneth Skovhede 80ce993526 Simple fix to prevent uploading dlist on failures 2025-04-16 19:05:51 +02:00
Kenneth Skovhede 4773914639 Rewrote testing to use an externally supplied transaction, to avoid temporary transactions from clearing the active transaction.
This is needed because SQLite does not support multiple active transactions.
2025-04-14 12:05:10 +02:00
Kenneth Skovhede ba4b6d4fc5 Added minor delay to deal with backups running back-to-back.
Probably mostly happening in tests.
2025-04-03 17:40:12 +02:00
Kenneth Skovhede 7f008341df Untangle the results and database
The code was using a two-way reference linking the database to the results and the results to the database.

However, this was not really used so it ended up just cluttering the code. With this commit, the results and databases are no longer keeping track of each other, and the only interaction is when the results are written to the database at the end of the operation.

To ensure result data is always written, this code has been moved into the controller, which will now flush the results for all operations. Prior to this, only some operations would write result data to the log.

The controller now also handles logic for cleaning old log data and invoking the vacuum command.

Fixed a bug due to using System.Text.Json where some attributes from NewtonSoft.Json were being applied and not picked up.
2025-03-20 09:51:49 +01:00
Kenneth Skovhede c1bdaa069e Async operation handlers
Rewrote all operation handlers to be async.
This moves the async/sync threshold out into the controller.

Fixed all the uses of cancellation token in the handlers to use the provided cancellation token.

Introduced a new ReusableTransaction that can be passed around, avoiding a ref parameter passing of the transaction instance.
2025-03-14 10:41:14 +01:00
Kenneth SkovhedeandGitHub eac394f0a3 Merge pull request #6011 from duplicati/feature/improved-failure-resilience
Improved failure resilience
2025-03-12 14:48:14 +01:00
Kenneth Skovhede ceff365ff8 Fixed compact count to use sample count, instead of file count. 2025-03-08 15:30:17 +01:00
Kenneth Skovhede 5f8ff74bd5 Streamlined handling of previous backup's fileset and dlist file if it failed to upload. 2025-03-08 15:25:55 +01:00
Kenneth Skovhede fce09596f3 Removed unused parameter and redundant namespace prefixes 2025-03-08 15:18:19 +01:00
Kenneth Skovhede ca236f03e3 Renamed flag to more precisely describe the purpose 2025-03-06 14:56:35 +01:00
Kenneth Skovhede 7beeb27ade Extended tests and fixed a case where a left-over upload could cause errors. 2025-03-06 14:53:46 +01:00
Kenneth Skovhede 4e60a7ad49 Merge remote-tracking branch 'origin/master' into feature/improved-failure-resilience 2025-03-06 12:09:42 +01:00
Kenneth Skovhede 1321488527 Improve failure detection
This commit adds extra logic to prevent cases where the backup reports success but leaves behind partial files.

A new flag is recorded to track if partial files are possible. If no partial files are possible, the verification will fail if any are found.
2025-03-06 12:02:11 +01:00
Kenneth Skovhede c61cc778a8 Log remote filesets
This commit adds the number of known remote filesets to the log output.
2025-02-28 11:18:23 +01:00
Kenneth Skovhede 26bbe6a577 Added setup step for source providers.
This enables a fail-early approach, where the remote source loads the initial results.
By storing the `IAsyncEnumerable` it is possible to not perform any additional remote calls, even with the initial probing call.

This makes it possible to detect the absence of sources, so the backup can be aborted if sources are missing.
2025-02-24 12:50:58 +01:00
Kenneth Skovhede 9dfe977d3f Changed logic so the source providers are now logically mounted into the source directory structure.
This fixes the restore issues as all sources will now appear as if they were originally part of the source file system.

The backend implementation has now been simplified so the backends only return names of entries with no path information.  Most backends already do this, but the S3 backends did not, so this was fixed as well.

This also clears up the interfaces, so the backend does not know about the `ISourceProviderEntry`. All mapping is done by the `BackendSourceProvider`, making it simpler to support other backends as sources.
2025-02-21 16:06:55 +01:00
Kenneth Skovhede 1716d09b51 Fixed source providers for S3, CIFS, and SSH.
Made the SMBShareConnection slightly more robust.

Introduced v2 List API to S3 backend, currently it retains v1 as the default.

Changed S3 backends to not recurse, potentially making smaller listings. This option can be disabled if it breaks things.

Added support for relative paths in the SSH backend.
2025-02-21 13:20:52 +01:00