Merge pull request #6944 from duplicati/feature/fix-locking-on-windows
Fix remote file locking on Windows
This commit is contained in:
@@ -54,6 +54,23 @@ namespace Duplicati.Library.Main.Database
|
||||
return dbnew;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="LocalLockDatabase"/> class.
|
||||
/// </summary>
|
||||
/// <param name="database">The database to create the new instance on.</param>
|
||||
/// <param name="token">A cancellation token to cancel the operation.</param>
|
||||
/// <returns>The <see cref="LocalLockDatabase"/> instance</returns>
|
||||
public static async Task<LocalLockDatabase> CreateAsync(LocalDatabase database, CancellationToken token)
|
||||
{
|
||||
var db = (LocalLockDatabase)await LocalDatabase.CreateLocalDatabaseAsync(
|
||||
database,
|
||||
new LocalLockDatabase(),
|
||||
token
|
||||
).ConfigureAwait(false);
|
||||
db.ShouldCloseConnection = false;
|
||||
return db;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the lock expiration time for a remote volume.
|
||||
/// </summary>
|
||||
|
||||
@@ -604,9 +604,10 @@ namespace Duplicati.Library.Main.Operation
|
||||
return;
|
||||
}
|
||||
|
||||
m_result.LockResults = new SetLockResults(m_result);
|
||||
using var lockDb = await LocalLockDatabase.CreateAsync(m_database, m_taskReader.StopToken);
|
||||
m_result.LockResults ??= new SetLockResults();
|
||||
await new SetLocksHandler(m_options, (SetLockResults)m_result.LockResults)
|
||||
.RunAsync(backendManager, versionTimestamps)
|
||||
.RunAsync(backendManager, lockDb, versionTimestamps)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -73,14 +73,14 @@ namespace Duplicati.Library.Main.Operation
|
||||
if (!backendManager.SupportsObjectLocking)
|
||||
throw new UserInformationException("Backend does not support object locking", "BackendDoesNotSupportLocking");
|
||||
|
||||
if (!File.Exists(m_options.Dbpath))
|
||||
var ownsDatabase = databaseOverride is null;
|
||||
if (ownsDatabase && !File.Exists(m_options.Dbpath))
|
||||
throw new UserInformationException(string.Format("Database file does not exist: {0}", m_options.Dbpath), "DatabaseFileDoesNotExist");
|
||||
|
||||
m_result.OperationProgressUpdater.UpdatePhase(OperationPhase.ReadLockInfo_Running);
|
||||
|
||||
var ownsDatabase = databaseOverride is null;
|
||||
await using var db = ownsDatabase
|
||||
? await LocalLockDatabase.CreateAsync(m_options.Dbpath, null, m_result.TaskControl.ProgressToken).ConfigureAwait(false)
|
||||
? await LocalLockDatabase.CreateAsync(m_options.Dbpath!, null, m_result.TaskControl.ProgressToken).ConfigureAwait(false)
|
||||
: null;
|
||||
var database = databaseOverride ?? db!;
|
||||
|
||||
@@ -118,6 +118,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
|
||||
m_result.VolumesRead = readCount;
|
||||
m_result.VolumesUpdated = updatedCount;
|
||||
m_result.EndTime = DateTime.UtcNow;
|
||||
|
||||
if (updatedCount > 0 || errorCount > 0)
|
||||
Log.WriteInformationMessage(LOGTAG, "ReadLockInfoComplete", "Read lock info complete: {0} updated, {1} errors", updatedCount, errorCount);
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
public Task RunAsync(IBackendManager backendManager, IEnumerable<DateTime>? versionTimestamps = null)
|
||||
=> RunAsync(backendManager, null, versionTimestamps);
|
||||
|
||||
internal async Task RunAsync(IBackendManager backendManager, Database.LocalLockDatabase? databaseOverride, IEnumerable<DateTime>? versionTimestamps = null)
|
||||
public async Task RunAsync(IBackendManager backendManager, Database.LocalLockDatabase? databaseOverride, IEnumerable<DateTime>? versionTimestamps = null)
|
||||
{
|
||||
if (m_options.RemoteFileLockDuration is null)
|
||||
throw new UserInformationException("No lock duration specified", "MissingLockDuration");
|
||||
@@ -61,16 +61,16 @@ namespace Duplicati.Library.Main.Operation
|
||||
if (!backendManager.SupportsObjectLocking)
|
||||
throw new UserInformationException("Backend does not support object locking", "BackendDoesNotSupportLocking");
|
||||
|
||||
if (!File.Exists(m_options.Dbpath))
|
||||
var ownsDatabase = databaseOverride is null;
|
||||
if (ownsDatabase && !File.Exists(m_options.Dbpath))
|
||||
throw new Exception(string.Format("Database file does not exist: {0}", m_options.Dbpath));
|
||||
|
||||
var effectiveVersionTimestamps = versionTimestamps ?? m_versionTimestamps;
|
||||
|
||||
m_result.OperationProgressUpdater.UpdatePhase(OperationPhase.Backup_Lock);
|
||||
|
||||
var ownsDatabase = databaseOverride is null;
|
||||
await using var db = ownsDatabase
|
||||
? await LocalLockDatabase.CreateAsync(m_options.Dbpath, null, m_result.TaskControl.ProgressToken).ConfigureAwait(false)
|
||||
? await LocalLockDatabase.CreateAsync(m_options.Dbpath!, null, m_result.TaskControl.ProgressToken).ConfigureAwait(false)
|
||||
: null;
|
||||
var database = databaseOverride ?? db!;
|
||||
|
||||
@@ -123,6 +123,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
|
||||
m_result.VolumesRead = readCount;
|
||||
m_result.VolumesUpdated = updatedCount;
|
||||
m_result.EndTime = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
private async Task<List<long>> ResolveFilesetIdsAsync(Database.LocalListDatabase db, IEnumerable<DateTime>? suppliedVersions)
|
||||
|
||||
Reference in New Issue
Block a user