Fixed: Logging error when accessing mount point

Fixes #2305
pull/2493/head
Leonardo Galli 7 years ago
parent 97ab4cbcbd
commit 27001b48f6

@ -1,8 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text;
using Mono.Unix; using Mono.Unix;
using Mono.Unix.Native; using Mono.Unix.Native;
using NLog; using NLog;
@ -18,50 +17,21 @@ namespace NzbDrone.Mono.Disk
private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(DiskProvider)); private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(DiskProvider));
private readonly IProcMountProvider _procMountProvider; private readonly IProcMountProvider _procMountProvider;
private readonly ISymbLinkResolver _symLinkResolver; private readonly ISymbolicLinkResolver _symLinkResolver;
private readonly Logger _logger;
// Mono supports sending -1 for a uint to indicate that the owner or group should not be set // Mono supports sending -1 for a uint to indicate that the owner or group should not be set
// `unchecked((uint)-1)` and `uint.MaxValue` are the same thing. // `unchecked((uint)-1)` and `uint.MaxValue` are the same thing.
private const uint UNCHANGED_ID = uint.MaxValue; private const uint UNCHANGED_ID = uint.MaxValue;
public DiskProvider(IProcMountProvider procMountProvider, ISymbLinkResolver symLinkResolver, Logger logger) public DiskProvider(IProcMountProvider procMountProvider, ISymbolicLinkResolver symLinkResolver)
{ {
_procMountProvider = procMountProvider; _procMountProvider = procMountProvider;
_symLinkResolver = symLinkResolver; _symLinkResolver = symLinkResolver;
_logger = logger;
} }
public override IMount GetMount(string path) public override IMount GetMount(string path)
{ {
if (path == null) return null; path = _symLinkResolver.GetCompleteRealPath(path);
try
{
string[] dirs;
int lastIndex;
GetPathComponents(path, out dirs, out lastIndex);
var realPath = new StringBuilder();
if (dirs.Length > 0)
{
var dir = UnixPath.IsPathRooted(path) ? "/" : "";
dir += dirs[0];
realPath.Append(GetRealPath(dir));
}
for (var i = 1; i < lastIndex; ++i)
{
realPath.Append("/").Append(dirs[i]);
var realSubPath = GetRealPath(realPath.ToString());
realPath.Remove(0, realPath.Length);
realPath.Append(realSubPath);
}
path = realPath.ToString();
}
catch (Exception ex)
{
_logger.Debug(ex, string.Format("Failed to check for symlinks in the path {0}", path));
}
return base.GetMount(path); return base.GetMount(path);
} }
@ -70,24 +40,15 @@ namespace NzbDrone.Mono.Disk
{ {
Ensure.That(path, () => path).IsValidPath(); Ensure.That(path, () => path).IsValidPath();
try var mount = GetMount(path);
{
var mount = GetMount(path);
if (mount == null)
{
Logger.Debug("Unable to get free space for '{0}', unable to find suitable drive", path);
return null;
}
return mount.AvailableFreeSpace; if (mount == null)
}
catch (InvalidOperationException ex)
{ {
Logger.Error(ex, "Couldn't get free space for " + path); Logger.Debug("Unable to get free space for '{0}', unable to find suitable drive", path);
return null;
} }
return null; return mount.AvailableFreeSpace;
} }
public override void InheritFolderPermissions(string filename) public override void InheritFolderPermissions(string filename)
@ -120,8 +81,8 @@ namespace NzbDrone.Mono.Disk
.Concat(GetDriveInfoMounts() .Concat(GetDriveInfoMounts()
.Select(d => new DriveInfoMount(d, FindDriveType.Find(d.DriveFormat))) .Select(d => new DriveInfoMount(d, FindDriveType.Find(d.DriveFormat)))
.Where(d => d.DriveType == DriveType.Fixed || .Where(d => d.DriveType == DriveType.Fixed ||
d.DriveType == DriveType.Network || d.DriveType == DriveType.Network || d.DriveType ==
d.DriveType == DriveType.Removable)) DriveType.Removable))
.DistinctBy(v => v.RootDirectory) .DistinctBy(v => v.RootDirectory)
.ToList(); .ToList();
} }
@ -130,20 +91,9 @@ namespace NzbDrone.Mono.Disk
{ {
Ensure.That(path, () => path).IsValidPath(); Ensure.That(path, () => path).IsValidPath();
try var mount = GetMount(path);
{
var mount = GetMount(path);
if (mount == null) return null;
return mount.TotalSize;
}
catch (InvalidOperationException e)
{
Logger.Error(e, "Couldn't get total space for " + path);
}
return null; return mount?.TotalSize;
} }
public override bool TryCreateHardLink(string source, string destination) public override bool TryCreateHardLink(string source, string destination)
@ -242,65 +192,5 @@ namespace NzbDrone.Mono.Disk
} }
private static void GetPathComponents(string path, out string[] components, out int lastIndex)
{
var dirs = path.Split(UnixPath.DirectorySeparatorChar);
var target = 0;
for (var i = 0; i < dirs.Length; ++i)
{
if (dirs[i] == "." || dirs[i] == string.Empty)
{
continue;
}
if (dirs[i] == "..")
{
if (target != 0)
{
target--;
}
else
{
target++;
}
}
else
{
dirs[target++] = dirs[i];
}
}
components = dirs;
lastIndex = target;
}
public string GetRealPath(string path)
{
do
{
var link = UnixPath.TryReadLink(path);
if (link == null)
{
var errno = Stdlib.GetLastError();
if (errno != Errno.EINVAL)
{
_logger.Trace("Checking path {0} for symlink returned error {1}, assuming it's not a symlink.", path, errno);
}
return path;
}
if (UnixPath.IsPathRooted(link))
{
path = link;
}
else
{
path = UnixPath.GetDirectoryName(path) + UnixPath.DirectorySeparatorChar + link;
path = UnixPath.GetCanonicalPath(path);
}
} while (true);
}
} }
} }

Loading…
Cancel
Save