Skip to content

Commit

Permalink
[C#] Process and volume privilege for LocalStorageDevice (#381)
Browse files Browse the repository at this point in the history
* Added config to disable process/volume privileges for LocalStorageDevice (LocalStorageDevice.UsePrivileges)
* Do not request privilege if preallocateFile is set to true
  • Loading branch information
badrishc authored Dec 1, 2020
1 parent 5281504 commit 32b226d
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 12 deletions.
29 changes: 19 additions & 10 deletions cs/src/core/Device/LocalStorageDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ namespace FASTER.core
/// </summary>
public unsafe class LocalStorageDevice : StorageDeviceBase
{
/// <summary>
/// Whether we use process and volume privilege calls to set file size in Windows.
/// Speeds up disk writes, but may have scalability issues on cloud VMs if many devices
/// are concurrently created.
/// </summary>
public static bool UsePrivileges = true;

private readonly bool preallocateFile;
private readonly bool deleteOnClose;
private readonly bool disableFileBuffering;
Expand Down Expand Up @@ -80,7 +87,9 @@ protected internal LocalStorageDevice(string filename,
IEnumerable<KeyValuePair<int, SafeFileHandle>> initialLogFileHandles = null)
: base(filename, GetSectorSize(filename), capacity)
{
Native32.EnableProcessPrivileges();
if (UsePrivileges && preallocateFile)
Native32.EnableProcessPrivileges();

string path = new FileInfo(filename).Directory.FullName;
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
Expand Down Expand Up @@ -136,10 +145,10 @@ private void RecoverFiles()
/// <param name="readLength"></param>
/// <param name="callback"></param>
/// <param name="context"></param>
public override void ReadAsync(int segmentId, ulong sourceAddress,
IntPtr destinationAddress,
uint readLength,
DeviceIOCompletionCallback callback,
public override void ReadAsync(int segmentId, ulong sourceAddress,
IntPtr destinationAddress,
uint readLength,
DeviceIOCompletionCallback callback,
object context)
{
if (!results.TryDequeue(out SimpleAsyncResult result))
Expand Down Expand Up @@ -200,11 +209,11 @@ public override void ReadAsync(int segmentId, ulong sourceAddress,
/// <param name="numBytesToWrite"></param>
/// <param name="callback"></param>
/// <param name="context"></param>
public override unsafe void WriteAsync(IntPtr sourceAddress,
public override unsafe void WriteAsync(IntPtr sourceAddress,
int segmentId,
ulong destinationAddress,
uint numBytesToWrite,
DeviceIOCompletionCallback callback,
ulong destinationAddress,
uint numBytesToWrite,
DeviceIOCompletionCallback callback,
object context)
{
HandleCapacity(segmentId);
Expand Down Expand Up @@ -415,7 +424,7 @@ private static bool SetFileSize(string filename, SafeFileHandle logHandle, long
if (size <= 0)
return false;

if (Native32.EnableVolumePrivileges(filename, logHandle))
if (UsePrivileges && Native32.EnableVolumePrivileges(filename, logHandle))
{
return Native32.SetFileSize(logHandle, size);
}
Expand Down
18 changes: 16 additions & 2 deletions cs/src/core/Utilities/Native32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@ public static void AffinitizeThreadShardedNuma(uint threadIdx, ushort nrOfProces
[DllImport("kernel32.dll", SetLastError = true)]
private static extern SafeFileHandle CreateFile(string filename, uint access, uint share, IntPtr securityAttributes, uint creationDisposition, uint flagsAndAttributes, IntPtr templateFile);

private static bool? processPrivilegeEnabled = null;

/// <summary>
/// Enable privilege for process
/// </summary>
Expand All @@ -276,28 +278,38 @@ public static bool EnableProcessPrivileges()
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
return false;
#endif
if (processPrivilegeEnabled.HasValue) return processPrivilegeEnabled.Value;

TOKEN_PRIVILEGES token_privileges = default(TOKEN_PRIVILEGES);
token_privileges.PrivilegeCount = 1;
token_privileges.Privileges.Attributes = 0x2;

if (!LookupPrivilegeValue(null, "SeManageVolumePrivilege",
ref token_privileges.Privileges.Luid)) return false;
ref token_privileges.Privileges.Luid))
{
processPrivilegeEnabled = false;
return false;
}

if (!OpenProcessToken(GetCurrentProcess(), 0x20, out IntPtr token))
{
processPrivilegeEnabled = false;
return false;

}
if (!AdjustTokenPrivileges(token, 0, ref token_privileges, 0, 0, 0))
{
CloseHandle(token);
processPrivilegeEnabled = false;
return false;
}
if (Marshal.GetLastWin32Error() != 0)
{
CloseHandle(token);
processPrivilegeEnabled = false;
return false;
}
CloseHandle(token);
processPrivilegeEnabled = true;
return true;
}

Expand All @@ -312,6 +324,8 @@ internal static bool EnableVolumePrivileges(string filename, SafeFileHandle hand
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
return false;
#endif
if (processPrivilegeEnabled == false)
return false;

string volume_string = "\\\\.\\" + filename.Substring(0, 2);

Expand Down

0 comments on commit 32b226d

Please sign in to comment.