mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 22:33:05 +08:00
Merge pull request #28019 from peppy/realm-file-perm-check
Check realm file can be written to before attempting further initialisation
This commit is contained in:
commit
5e2e2a8d39
@ -35,6 +35,7 @@ using osu.Game.Rulesets.Mods;
|
|||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Scoring.Legacy;
|
using osu.Game.Scoring.Legacy;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
using osu.Game.Utils;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
using Realms;
|
using Realms;
|
||||||
using Realms.Exceptions;
|
using Realms.Exceptions;
|
||||||
@ -321,12 +322,32 @@ namespace osu.Game.Database
|
|||||||
{
|
{
|
||||||
Logger.Error(e, "Your local database is too new to work with this version of osu!. Please close osu! and install the latest release to recover your data.");
|
Logger.Error(e, "Your local database is too new to work with this version of osu!. Please close osu! and install the latest release to recover your data.");
|
||||||
|
|
||||||
// If a newer version database already exists, don't backup again. We can presume that the first backup is the one we care about.
|
// If a newer version database already exists, don't create another backup. We can presume that the first backup is the one we care about.
|
||||||
if (!storage.Exists(newerVersionFilename))
|
if (!storage.Exists(newerVersionFilename))
|
||||||
createBackup(newerVersionFilename);
|
createBackup(newerVersionFilename);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// This error can occur due to file handles still being open by a previous instance.
|
||||||
|
// If this is the case, rather than assuming the realm file is corrupt, block game startup.
|
||||||
|
if (e.Message.StartsWith("SetEndOfFile() failed", StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
// This will throw if the realm file is not available for write access after 5 seconds.
|
||||||
|
FileUtils.AttemptOperation(() =>
|
||||||
|
{
|
||||||
|
if (storage.Exists(Filename))
|
||||||
|
{
|
||||||
|
using (var _ = storage.GetStream(Filename, FileAccess.ReadWrite))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 20);
|
||||||
|
|
||||||
|
// If the above eventually succeeds, try and continue startup as per normal.
|
||||||
|
// This may throw again but let's allow it to, and block startup.
|
||||||
|
return getRealmInstance();
|
||||||
|
}
|
||||||
|
|
||||||
Logger.Error(e, "Realm startup failed with unrecoverable error; starting with a fresh database. A backup of your database has been made.");
|
Logger.Error(e, "Realm startup failed with unrecoverable error; starting with a fresh database. A backup of your database has been made.");
|
||||||
createBackup($"{Filename.Replace(realm_extension, string.Empty)}_{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}_corrupt{realm_extension}");
|
createBackup($"{Filename.Replace(realm_extension, string.Empty)}_{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}_corrupt{realm_extension}");
|
||||||
}
|
}
|
||||||
@ -1142,11 +1163,7 @@ namespace osu.Game.Database
|
|||||||
{
|
{
|
||||||
Logger.Log($"Creating full realm database backup at {backupFilename}", LoggingTarget.Database);
|
Logger.Log($"Creating full realm database backup at {backupFilename}", LoggingTarget.Database);
|
||||||
|
|
||||||
int attempts = 10;
|
FileUtils.AttemptOperation(() =>
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
using (var source = storage.GetStream(Filename, mode: FileMode.Open))
|
using (var source = storage.GetStream(Filename, mode: FileMode.Open))
|
||||||
{
|
{
|
||||||
@ -1157,18 +1174,7 @@ namespace osu.Game.Database
|
|||||||
using (var destination = storage.GetStream(backupFilename, FileAccess.Write, FileMode.CreateNew))
|
using (var destination = storage.GetStream(backupFilename, FileAccess.Write, FileMode.CreateNew))
|
||||||
source.CopyTo(destination);
|
source.CopyTo(destination);
|
||||||
}
|
}
|
||||||
|
}, 20);
|
||||||
return;
|
|
||||||
}
|
|
||||||
catch (IOException)
|
|
||||||
{
|
|
||||||
if (attempts-- <= 0)
|
|
||||||
throw;
|
|
||||||
|
|
||||||
// file may be locked during use.
|
|
||||||
Thread.Sleep(500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
Loading…
Reference in New Issue
Block a user