Fixed passing transaction to more places
This commit is contained in:
@@ -364,9 +364,9 @@ namespace Duplicati.Library.Main.Database
|
||||
return RemoteVolumeEntry.Empty;
|
||||
}
|
||||
|
||||
public IEnumerable<KeyValuePair<string, RemoteVolumeState>> DuplicateRemoteVolumes()
|
||||
public IEnumerable<KeyValuePair<string, RemoteVolumeState>> DuplicateRemoteVolumes(IDbTransaction? transaction)
|
||||
{
|
||||
foreach (var rd in m_selectduplicateRemoteVolumesCommand.ExecuteReaderEnumerable())
|
||||
foreach (var rd in m_selectduplicateRemoteVolumesCommand.SetTransaction(transaction).ExecuteReaderEnumerable())
|
||||
{
|
||||
yield return new KeyValuePair<string, RemoteVolumeState>(
|
||||
rd.ConvertValueToString(0) ?? throw new Exception("Name was null"),
|
||||
|
||||
@@ -344,12 +344,12 @@ namespace Duplicati.Library.Main.Operation
|
||||
{
|
||||
if (options.NoBackendverification)
|
||||
{
|
||||
await FilelistProcessor.VerifyLocalList(backendManager, database, result.TaskControl.ProgressToken).ConfigureAwait(false);
|
||||
await FilelistProcessor.VerifyLocalList(backendManager, database, null, result.TaskControl.ProgressToken).ConfigureAwait(false);
|
||||
await UpdateStorageStatsFromDatabase(result, database, options, backendManager, result.TaskControl.ProgressToken).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
await FilelistProcessor.VerifyRemoteList(backendManager, options, database, result.BackendWriter, [lastTempFilelist.Name], [], logErrors: false, verifyMode: FilelistProcessor.VerifyMode.VerifyAndClean).ConfigureAwait(false);
|
||||
await FilelistProcessor.VerifyRemoteList(backendManager, options, database, null, result.BackendWriter, [lastTempFilelist.Name], [], logErrors: false, verifyMode: FilelistProcessor.VerifyMode.VerifyAndClean).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (RemoteListVerificationException ex)
|
||||
@@ -369,7 +369,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
database = new LocalBackupDatabase(options.Dbpath, options);
|
||||
|
||||
Log.WriteInformationMessage(LOGTAG, "BackendCleanupFinished", "Backend cleanup finished, retrying verification");
|
||||
await FilelistProcessor.VerifyRemoteList(backendManager, options, database, result.BackendWriter, [lastTempFilelist.Name], [], logErrors: true, verifyMode: FilelistProcessor.VerifyMode.VerifyStrict).ConfigureAwait(false);
|
||||
await FilelistProcessor.VerifyRemoteList(backendManager, options, database, null, result.BackendWriter, [lastTempFilelist.Name], [], logErrors: true, verifyMode: FilelistProcessor.VerifyMode.VerifyStrict).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
throw;
|
||||
@@ -515,7 +515,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
{
|
||||
m_result.OperationProgressUpdater.UpdatePhase(OperationPhase.Backup_PostBackupVerify);
|
||||
using (new Logging.Timer(LOGTAG, "AfterBackupVerify", "AfterBackupVerify"))
|
||||
await FilelistProcessor.VerifyRemoteList(backendManager, m_options, m_database, m_result.BackendWriter, [currentFilelistVolume], [previousTemporaryFilelist], logErrors: true, verifyMode: FilelistProcessor.VerifyMode.VerifyStrict).ConfigureAwait(false);
|
||||
await FilelistProcessor.VerifyRemoteList(backendManager, m_options, m_database, rtr.Transaction, m_result.BackendWriter, [currentFilelistVolume], [previousTemporaryFilelist], logErrors: true, verifyMode: FilelistProcessor.VerifyMode.VerifyStrict).ConfigureAwait(false);
|
||||
await backendManager.WaitForEmptyAsync(m_database, rtr.Transaction, m_taskReader.ProgressToken);
|
||||
|
||||
// Calculate the number of samples to test, using the largest number of file of a given type
|
||||
|
||||
@@ -66,9 +66,9 @@ namespace Duplicati.Library.Main.Operation
|
||||
/// Throws an error if there are issues with the remote storage
|
||||
/// </summary>
|
||||
/// <param name="database">The database to compare with</param>
|
||||
public static async Task VerifyLocalList(IBackendManager backendManager, LocalDatabase database, CancellationToken cancellationToken)
|
||||
public static async Task VerifyLocalList(IBackendManager backendManager, LocalDatabase database, IDbTransaction transaction, CancellationToken cancellationToken)
|
||||
{
|
||||
var locallist = database.GetRemoteVolumes();
|
||||
var locallist = database.GetRemoteVolumes(transaction);
|
||||
foreach (var i in locallist)
|
||||
{
|
||||
switch (i.State)
|
||||
@@ -120,7 +120,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
{
|
||||
LocalBackupDatabase backupDatabase = new LocalBackupDatabase(database, options);
|
||||
IEnumerable<string> protectedFiles = backupDatabase.GetTemporaryFilelistVolumeNames(latestVolumesOnly, transaction);
|
||||
await VerifyRemoteList(backend, options, database, backendWriter, protectedFiles, [], logErrors: true, verifyMode: verifyMode).ConfigureAwait(false);
|
||||
await VerifyRemoteList(backend, options, database, transaction, backendWriter, protectedFiles, [], logErrors: true, verifyMode: verifyMode).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,9 +137,9 @@ namespace Duplicati.Library.Main.Operation
|
||||
/// <param name="verifyMode">The mode to use for verification</param>
|
||||
/// <param name="logErrors">Disable the logging of errors to prevent spamming the log; exceptions will be thrown regardless</param>
|
||||
/// <returns>An awaitable task</returns>
|
||||
public static async Task VerifyRemoteList(IBackendManager backend, Options options, LocalDatabase database, IBackendWriter log, IEnumerable<string> protectedFiles, IEnumerable<string> strictExcemptFiles, bool logErrors, VerifyMode verifyMode)
|
||||
public static async Task VerifyRemoteList(IBackendManager backend, Options options, LocalDatabase database, IDbTransaction transaction, IBackendWriter log, IEnumerable<string> protectedFiles, IEnumerable<string> strictExcemptFiles, bool logErrors, VerifyMode verifyMode)
|
||||
{
|
||||
var tp = await RemoteListAnalysis(backend, options, database, log, protectedFiles, strictExcemptFiles, verifyMode).ConfigureAwait(false);
|
||||
var tp = await RemoteListAnalysis(backend, options, database, transaction, log, protectedFiles, strictExcemptFiles, verifyMode).ConfigureAwait(false);
|
||||
long extraCount = 0;
|
||||
long missingCount = 0;
|
||||
|
||||
@@ -249,7 +249,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
/// <param name="strictExcemptFiles">Filenames that should be exempted from strict verification</param>
|
||||
/// <param name="verifyMode">The mode to use for verification</param>
|
||||
/// <returns>The result of the analysis</returns>
|
||||
public static async Task<RemoteAnalysisResult> RemoteListAnalysis(IBackendManager backendManager, Options options, LocalDatabase database, IBackendWriter log, IEnumerable<string> protectedFiles, IEnumerable<string> strictExcemptFiles, VerifyMode verifyMode)
|
||||
public static async Task<RemoteAnalysisResult> RemoteListAnalysis(IBackendManager backendManager, Options options, LocalDatabase database, IDbTransaction transaction, IBackendWriter log, IEnumerable<string> protectedFiles, IEnumerable<string> strictExcemptFiles, VerifyMode verifyMode)
|
||||
{
|
||||
// If the last operation completed, no cleanup should be required
|
||||
if (verifyMode == VerifyMode.VerifyAndClean && !database.TerminatedWithActiveUploads)
|
||||
@@ -303,15 +303,15 @@ namespace Duplicati.Library.Main.Operation
|
||||
var temporaryAndDeletedVolumes = new HashSet<string>();
|
||||
var missingUploadingVolumes = new HashSet<string>();
|
||||
|
||||
foreach (var e in database.DuplicateRemoteVolumes())
|
||||
foreach (var e in database.DuplicateRemoteVolumes(transaction))
|
||||
{
|
||||
if (e.Value == RemoteVolumeState.Uploading || e.Value == RemoteVolumeState.Temporary)
|
||||
database.UnlinkRemoteVolume(e.Key, e.Value);
|
||||
database.UnlinkRemoteVolume(e.Key, e.Value, transaction);
|
||||
else
|
||||
throw new RemoteListVerificationException(string.Format("The remote volume {0} appears in the database with state {1} and a deleted state, cannot continue", e.Key, e.Value.ToString()), "AmbiguousStateRemoteFiles");
|
||||
}
|
||||
|
||||
var locallist = database.GetRemoteVolumes();
|
||||
var locallist = database.GetRemoteVolumes(transaction);
|
||||
foreach (var i in locallist)
|
||||
{
|
||||
var remoteFound = lookup.TryGetValue(i.Name, out var r);
|
||||
@@ -376,14 +376,14 @@ namespace Duplicati.Library.Main.Operation
|
||||
if (remoteFound && correctSize && r.File.Size >= 0)
|
||||
{
|
||||
Logging.Log.WriteInformationMessage(LOGTAG, "PromotingCompleteFile", "Promoting uploaded complete file from {0} to {2}: {1}", i.State, i.Name, RemoteVolumeState.Uploaded);
|
||||
database.UpdateRemoteVolume(i.Name, RemoteVolumeState.Uploaded, i.Size, i.Hash);
|
||||
database.UpdateRemoteVolume(i.Name, RemoteVolumeState.Uploaded, i.Size, i.Hash, transaction);
|
||||
}
|
||||
else if (!remoteFound)
|
||||
{
|
||||
if (protectedFiles.Any(pf => pf == i.Name))
|
||||
{
|
||||
Logging.Log.WriteInformationMessage(LOGTAG, "KeepIncompleteFile", "Keeping protected incomplete remote file listed as {0}: {1}", i.State, i.Name);
|
||||
database.UpdateRemoteVolume(i.Name, RemoteVolumeState.Temporary, i.Size, i.Hash, false, new TimeSpan(0), null, null);
|
||||
database.UpdateRemoteVolume(i.Name, RemoteVolumeState.Temporary, i.Size, i.Hash, false, new TimeSpan(0), null, transaction);
|
||||
}
|
||||
else if (verifyMode == VerifyMode.VerifyStrict && !strictExcemptFiles.Any(pf => pf == i.Name))
|
||||
{
|
||||
@@ -394,7 +394,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
{
|
||||
Logging.Log.WriteInformationMessage(LOGTAG, "SchedulingMissingFileForDelete", "Scheduling missing file for deletion, currently listed as {0}: {1}", i.State, i.Name);
|
||||
missingUploadingVolumes.Add(i.Name);
|
||||
database.UpdateRemoteVolume(i.Name, RemoteVolumeState.Deleting, i.Size, i.Hash, false, TimeSpan.FromHours(2), null, null);
|
||||
database.UpdateRemoteVolume(i.Name, RemoteVolumeState.Deleting, i.Size, i.Hash, false, TimeSpan.FromHours(2), null, transaction);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -431,7 +431,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
if (!remoteFound)
|
||||
missing.Add(i);
|
||||
else if (correctSize)
|
||||
database.UpdateRemoteVolume(i.Name, RemoteVolumeState.Verified, i.Size, i.Hash);
|
||||
database.UpdateRemoteVolume(i.Name, RemoteVolumeState.Verified, i.Size, i.Hash, transaction);
|
||||
else
|
||||
missingHash.Add(new Tuple<long, RemoteVolumeEntry>(r.File.Size, i));
|
||||
|
||||
@@ -458,7 +458,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
throw new RemoteListVerificationException($"The remote volumes {string.Join(", ", missingUploadingVolumes)} are supposed to be deleted, but strict mode is on. Try running the \"repair\" command", "DeleteDuringStrictMode");
|
||||
else if (verifyMode == VerifyMode.VerifyAndClean || verifyMode == VerifyMode.VerifyStrict)
|
||||
{
|
||||
database.RemoveRemoteVolumes(missingUploadingVolumes.Concat(temporaryAndDeletedVolumes), null);
|
||||
database.RemoveRemoteVolumes(missingUploadingVolumes.Concat(temporaryAndDeletedVolumes), transaction);
|
||||
// Clear the flag after we have cleaned up
|
||||
if (!options.Dryrun)
|
||||
database.TerminatedWithActiveUploads = false;
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
|
||||
Logging.Log.WriteInformationMessage(LOGTAG, "NoBrokenFilesetsInDatabase", "No broken filesets found in database, checking for missing remote files");
|
||||
|
||||
var remotestate = await FilelistProcessor.RemoteListAnalysis(backendManager, options, db, result.BackendWriter, null, null, FilelistProcessor.VerifyMode.VerifyOnly).ConfigureAwait(false);
|
||||
var remotestate = await FilelistProcessor.RemoteListAnalysis(backendManager, options, db, transaction, result.BackendWriter, null, null, FilelistProcessor.VerifyMode.VerifyOnly).ConfigureAwait(false);
|
||||
if (!remotestate.ParsedVolumes.Any())
|
||||
throw new UserInformationException("No remote volumes were found, refusing purge", "CannotPurgeWithNoRemoteVolumes");
|
||||
|
||||
|
||||
@@ -90,9 +90,9 @@ namespace Duplicati.Library.Main.Operation
|
||||
db.VerifyConsistency(m_options.Blocksize, m_options.BlockhashSize, false, null);
|
||||
|
||||
if (m_options.NoBackendverification)
|
||||
await FilelistProcessor.VerifyLocalList(backendManager, db, m_result.TaskControl.ProgressToken).ConfigureAwait(false);
|
||||
await FilelistProcessor.VerifyLocalList(backendManager, db, null, m_result.TaskControl.ProgressToken).ConfigureAwait(false);
|
||||
else
|
||||
await FilelistProcessor.VerifyRemoteList(backendManager, m_options, db, m_result.BackendWriter, null, null, logErrors: true, verifyMode: FilelistProcessor.VerifyMode.VerifyStrict).ConfigureAwait(false);
|
||||
await FilelistProcessor.VerifyRemoteList(backendManager, m_options, db, null, m_result.BackendWriter, null, null, logErrors: true, verifyMode: FilelistProcessor.VerifyMode.VerifyStrict).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var filesets = db.FilesetTimes.OrderByDescending(x => x.Value).ToArray();
|
||||
|
||||
@@ -141,7 +141,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
|
||||
// If the last backup failed, guard the incomplete fileset, so we can create a synthetic filelist
|
||||
var lastTempFilelist = db.GetLastIncompleteFilesetVolume(null);
|
||||
var tp = await FilelistProcessor.RemoteListAnalysis(backendManager, m_options, db, m_result.BackendWriter, [lastTempFilelist.Name], null, FilelistProcessor.VerifyMode.VerifyAndCleanForced).ConfigureAwait(false);
|
||||
var tp = await FilelistProcessor.RemoteListAnalysis(backendManager, m_options, db, null, m_result.BackendWriter, [lastTempFilelist.Name], null, FilelistProcessor.VerifyMode.VerifyAndCleanForced).ConfigureAwait(false);
|
||||
|
||||
var buffer = new byte[m_options.Blocksize];
|
||||
var hashsize = HashFactory.HashSizeBytes(m_options.BlockHashAlgorithm);
|
||||
|
||||
@@ -25,7 +25,6 @@ using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using Duplicati.Library.Interface;
|
||||
using Duplicati.Library.Utility;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Duplicati.Library.Main.Operation
|
||||
|
||||
Reference in New Issue
Block a user