diff --git a/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs b/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs
index f0cca9efd0..d1376f18ad 100644
--- a/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs
+++ b/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs
@@ -1,5 +1,7 @@
using System;
+using System.Collections.Generic;
using System.IO;
+using System.Linq;
using MediaBrowser.Common.Configuration;
namespace Emby.Server.Implementations.AppBase
@@ -30,7 +32,6 @@ namespace Emby.Server.Implementations.AppBase
ConfigurationDirectoryPath = configurationDirectoryPath;
CachePath = cacheDirectoryPath;
WebPath = webDirectoryPath;
-
DataPath = Directory.CreateDirectory(Path.Combine(ProgramDataPath, "data")).FullName;
}
@@ -75,5 +76,47 @@ namespace Emby.Server.Implementations.AppBase
///
public string TrickplayPath => Path.Combine(DataPath, "trickplay");
+
+ ///
+ public virtual void MakeSanityCheckOrThrow()
+ {
+ CreateAndCheckMarker(ConfigurationDirectoryPath, "config");
+ CreateAndCheckMarker(LogDirectoryPath, "log");
+ CreateAndCheckMarker(PluginsPath, "plugin");
+ CreateAndCheckMarker(ProgramDataPath, "data");
+ CreateAndCheckMarker(CachePath, "cache");
+ CreateAndCheckMarker(DataPath, "data");
+ }
+
+ ///
+ public void CreateAndCheckMarker(string path, string markerName, bool recursive = false)
+ {
+ if (!Directory.Exists(path))
+ {
+ Directory.CreateDirectory(path);
+ }
+
+ CheckOrCreateMarker(path, $".jellyfin-{markerName}", recursive);
+ }
+
+ private IEnumerable GetMarkers(string path, bool recursive = false)
+ {
+ return Directory.EnumerateFiles(path, ".jellyfin-*", recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
+ }
+
+ private void CheckOrCreateMarker(string path, string markerName, bool recursive = false)
+ {
+ var otherMarkers = GetMarkers(path, recursive).FirstOrDefault(e => Path.GetFileName(e) != markerName);
+ if (otherMarkers != null)
+ {
+ throw new InvalidOperationException($"Exepected to find only {markerName} but found marker for {otherMarkers}.");
+ }
+
+ var markerPath = Path.Combine(path, markerName);
+ if (!File.Exists(markerPath))
+ {
+ File.Create(markerPath).Dispose();
+ }
+ }
}
}
diff --git a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs
index 9bc3a0204b..81ef0e5f9a 100644
--- a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs
+++ b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs
@@ -227,6 +227,7 @@ namespace Emby.Server.Implementations.AppBase
Logger.LogInformation("Setting cache path: {Path}", cachePath);
((BaseApplicationPaths)CommonApplicationPaths).CachePath = cachePath;
+ CommonApplicationPaths.CreateAndCheckMarker(((BaseApplicationPaths)CommonApplicationPaths).CachePath, "cache");
}
///
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index 40045782b6..a6eddbbc3b 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -768,8 +768,6 @@ namespace Emby.Server.Implementations.Library
{
var rootFolderPath = _configurationManager.ApplicationPaths.RootFolderPath;
- Directory.CreateDirectory(rootFolderPath);
-
var rootFolder = GetItemById(GetNewItemId(rootFolderPath, typeof(AggregateFolder))) as AggregateFolder ??
(ResolvePath(_fileSystem.GetDirectoryInfo(rootFolderPath)) as Folder ?? throw new InvalidOperationException("Something went very wong"))
.DeepCopy();
diff --git a/Emby.Server.Implementations/ServerApplicationPaths.cs b/Emby.Server.Implementations/ServerApplicationPaths.cs
index 725df98da5..f049e66475 100644
--- a/Emby.Server.Implementations/ServerApplicationPaths.cs
+++ b/Emby.Server.Implementations/ServerApplicationPaths.cs
@@ -96,5 +96,12 @@ namespace Emby.Server.Implementations
///
public string VirtualInternalMetadataPath => "%MetadataPath%";
+
+ ///
+ public override void MakeSanityCheckOrThrow()
+ {
+ base.MakeSanityCheckOrThrow();
+ CreateAndCheckMarker(RootFolderPath, "root");
+ }
}
}
diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs
index 8d0bf73f6a..511306755b 100644
--- a/Jellyfin.Server/Program.cs
+++ b/Jellyfin.Server/Program.cs
@@ -77,6 +77,7 @@ namespace Jellyfin.Server
{
_startTimestamp = Stopwatch.GetTimestamp();
ServerApplicationPaths appPaths = StartupHelpers.CreateApplicationPaths(options);
+ appPaths.MakeSanityCheckOrThrow();
// $JELLYFIN_LOG_DIR needs to be set for the logger configuration manager
Environment.SetEnvironmentVariable("JELLYFIN_LOG_DIR", appPaths.LogDirectoryPath);
diff --git a/MediaBrowser.Common/Configuration/EncodingConfigurationExtensions.cs b/MediaBrowser.Common/Configuration/EncodingConfigurationExtensions.cs
index 70a4fe4098..78e96ab47c 100644
--- a/MediaBrowser.Common/Configuration/EncodingConfigurationExtensions.cs
+++ b/MediaBrowser.Common/Configuration/EncodingConfigurationExtensions.cs
@@ -35,8 +35,7 @@ namespace MediaBrowser.Common.Configuration
transcodingTempPath = Path.Combine(configurationManager.CommonApplicationPaths.CachePath, "transcodes");
}
- // Make sure the directory exists
- Directory.CreateDirectory(transcodingTempPath);
+ configurationManager.CommonApplicationPaths.CreateAndCheckMarker(transcodingTempPath, "transcode", true);
return transcodingTempPath;
}
}
diff --git a/MediaBrowser.Common/Configuration/IApplicationPaths.cs b/MediaBrowser.Common/Configuration/IApplicationPaths.cs
index 7a8ab32361..fa0d8247b4 100644
--- a/MediaBrowser.Common/Configuration/IApplicationPaths.cs
+++ b/MediaBrowser.Common/Configuration/IApplicationPaths.cs
@@ -90,5 +90,18 @@ namespace MediaBrowser.Common.Configuration
///
/// The trickplay path.
string TrickplayPath { get; }
+
+ ///
+ /// Checks and creates all known base paths.
+ ///
+ void MakeSanityCheckOrThrow();
+
+ ///
+ /// Checks and creates the given path and adds it with a marker file if non existant.
+ ///
+ /// The path to check.
+ /// The common marker file name.
+ /// Check for other settings paths recursivly.
+ void CreateAndCheckMarker(string path, string markerName, bool recursive = false);
}
}
diff --git a/MediaBrowser.Controller/IServerApplicationPaths.cs b/MediaBrowser.Controller/IServerApplicationPaths.cs
index 608286cd8a..a6e83a02c7 100644
--- a/MediaBrowser.Controller/IServerApplicationPaths.cs
+++ b/MediaBrowser.Controller/IServerApplicationPaths.cs
@@ -2,6 +2,10 @@
#pragma warning disable CS1591
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
using MediaBrowser.Common.Configuration;
namespace MediaBrowser.Controller