Skip to content

Commit

Permalink
Fix Android device issues related to filesystem/IO (dotnet#58586)
Browse files Browse the repository at this point in the history
- Use F_SETLK64 for fcntl to fix an issue where 32bit arm Android apps would get the wrong flag
- Add numerical magic numbers for missing file systems to Interop.UnixFileSystemTypes so they are correctly recognized
- Make ping test a bit more forgiving if the process returns a few milliseconds _before_ the timeout

(cherry picked from commit 462ab6e)
  • Loading branch information
akoeplinger committed Sep 9, 2021
1 parent 2bb7a34 commit 6ecf2ba
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ private static DriveType GetDriveType(string fileSystemName)
// This list is based primarily on "man fs", "man mount", "mntent.h", "/proc/filesystems", coreutils "stat.c",
// and "wiki.debian.org/FileSystem". It can be extended over time as we find additional file systems that should
// be recognized as a particular drive type.
// Keep this in sync with the UnixFileSystemTypes enum in Interop.UnixFileSystemTypes.cs
switch (fileSystemName)
{
case "cddafs":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ internal enum UnixFileSystemTypes : long
befs = 0x42465331,
bdevfs = 0x62646576,
bfs = 0x1BADFACE,
bpf_fs = 0xCAFE4A11,
binfmt_misc = 0x42494E4D,
bootfs = 0xA56D3FF9,
btrfs = 0x9123683E,
Expand All @@ -53,6 +54,7 @@ internal enum UnixFileSystemTypes : long
ext2 = 0xEF53,
ext3 = 0xEF53,
ext4 = 0xEF53,
f2fs = 0xF2F52010,
fat = 0x4006,
fd = 0xF00D1E,
fhgfs = 0x19830326,
Expand Down Expand Up @@ -122,6 +124,7 @@ internal enum UnixFileSystemTypes : long
sysv2 = 0x012FF7B6,
sysv4 = 0x012FF7B5,
tmpfs = 0x01021994,
tracefs = 0x74726163,
ubifs = 0x24051905,
udf = 0x15013346,
ufs = 0x00011954,
Expand Down
13 changes: 12 additions & 1 deletion src/libraries/Native/Unix/System.Native/pal_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1427,6 +1427,7 @@ int64_t SystemNative_GetFileSystemType(intptr_t fd)
else if (strcmp(statfsArgs.f_basetype, "befs") == 0) result = 0x42465331;
else if (strcmp(statfsArgs.f_basetype, "bdevfs") == 0) result = 0x62646576;
else if (strcmp(statfsArgs.f_basetype, "bfs") == 0) result = 0x1BADFACE;
else if (strcmp(statfsArgs.f_basetype, "bpf_fs") == 0) result = 0xCAFE4A11;
else if (strcmp(statfsArgs.f_basetype, "binfmt_misc") == 0) result = 0x42494E4D;
else if (strcmp(statfsArgs.f_basetype, "bootfs") == 0) result = 0xA56D3FF9;
else if (strcmp(statfsArgs.f_basetype, "btrfs") == 0) result = 0x9123683E;
Expand All @@ -1452,6 +1453,7 @@ int64_t SystemNative_GetFileSystemType(intptr_t fd)
else if (strcmp(statfsArgs.f_basetype, "ext2") == 0) result = 0xEF53;
else if (strcmp(statfsArgs.f_basetype, "ext3") == 0) result = 0xEF53;
else if (strcmp(statfsArgs.f_basetype, "ext4") == 0) result = 0xEF53;
else if (strcmp(statfsArgs.f_basetype, "f2fs") == 0) result = 0xF2F52010;
else if (strcmp(statfsArgs.f_basetype, "fat") == 0) result = 0x4006;
else if (strcmp(statfsArgs.f_basetype, "fd") == 0) result = 0xF00D1E;
else if (strcmp(statfsArgs.f_basetype, "fhgfs") == 0) result = 0x19830326;
Expand Down Expand Up @@ -1519,6 +1521,7 @@ int64_t SystemNative_GetFileSystemType(intptr_t fd)
else if (strcmp(statfsArgs.f_basetype, "sysv2") == 0) result = 0x012FF7B6;
else if (strcmp(statfsArgs.f_basetype, "sysv4") == 0) result = 0x012FF7B5;
else if (strcmp(statfsArgs.f_basetype, "tmpfs") == 0) result = 0x01021994;
else if (strcmp(statfsArgs.f_basetype, "tracefs") == 0) result = 0x74726163;
else if (strcmp(statfsArgs.f_basetype, "ubifs") == 0) result = 0x24051905;
else if (strcmp(statfsArgs.f_basetype, "udf") == 0) result = 0x15013346;
else if (strcmp(statfsArgs.f_basetype, "ufs") == 0) result = 0x00011954;
Expand Down Expand Up @@ -1560,13 +1563,21 @@ int32_t SystemNative_LockFileRegion(intptr_t fd, int64_t offset, int64_t length,
struct flock lockArgs;
#endif

#if defined(TARGET_ANDROID) && defined(HAVE_FLOCK64)
// On Android, fcntl is always implemented by fcntl64 but before https://github.com/aosp-mirror/platform_bionic/commit/09e77f35ab8d291bf88302bb9673aaa518c6bcb0
// there was no remapping of F_SETLK to F_SETLK64 when _FILE_OFFSET_BITS=64 (which we set in eng/native/configurecompiler.cmake) so we need to always pass F_SETLK64
int command = F_SETLK64;
#else
int command = F_SETLK;
#endif

lockArgs.l_type = unixLockType;
lockArgs.l_whence = SEEK_SET;
lockArgs.l_start = (off_t)offset;
lockArgs.l_len = (off_t)length;

int32_t ret;
while ((ret = fcntl (ToFileDescriptor(fd), F_SETLK, &lockArgs)) < 0 && errno == EINTR);
while ((ret = fcntl (ToFileDescriptor(fd), command, &lockArgs)) < 0 && errno == EINTR);
return ret;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ public static void TimeoutIsRespected(int timeout)
p.Start();
p.WaitForExit();

//ensure that the process takes longer than or equal to 'timeout'
Assert.True(stopWatch.ElapsedMilliseconds >= timeout);
//ensure that the process takes longer than or within 10ms of 'timeout', with a 5s maximum
Assert.InRange(stopWatch.ElapsedMilliseconds, timeout - 10, 5000);
}

[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))]
Expand Down

0 comments on commit 6ecf2ba

Please sign in to comment.