Subject: Re: bug#52193: mv broken on non-APFS filesystems on macOS on coreutils >= 9.0

From: Sudhip Nashi <[email-masked]>
Date: Wed, 8 Dec 2021 18:08:08 -0600

> Thanks, but as I don't have access to a macOS machine I don't know what "the issue" is. What are the symptoms visible to the user? Can you do the equivalent of an strace to show us what system calls are being executed?
> 
> As near as I can make out, on macOS mv should be doing the equivalent of the following:
> 
>   sfd = open ("source", O_RDONLY | O_NOFOLLOW);
>   if (fclonefileat (sfd, AT_FDCWD, "destination", 0) != 0)
>     {
>        dfd = open ("destination", O_WRONLY | O_CREAT | O_EXCL, mode);
>        next_start = lseek (sfd, 0, SEEK_DATA);
>        ...
> 
> and evidently something is going wrong at or after the "...". What is it?

Ah, my bad. The issue is that all `mv` operations within the mountpoint fail with an ENOTSUPP error. Here’s a dtruss for an example:

access("/AppleInternal/XBS/.isChrooted\0", 0x0, 0x0)		= -1 Err#2
bsdthread_register(0x1AEC802C8, 0x1AEC802BC, 0x4000)		= 1073742303 0
shm_open(0x1AEB48F55, 0x0, 0x45E4000)		= 3 0
fstat64(0x3, 0x16B81A100, 0x0)		= 0 0
mmap(0x0, 0x4000, 0x1, 0x40001, 0x3, 0x0)		= 0x104718000 0
close(0x3)		= 0 0
ioctl(0x2, 0x4004667A, 0x16B81A1AC)		= 0 0
mprotect(0x104724000, 0x4000, 0x0)		= 0 0
mprotect(0x104730000, 0x4000, 0x0)		= 0 0
mprotect(0x104734000, 0x4000, 0x0)		= 0 0
mprotect(0x104740000, 0x4000, 0x0)		= 0 0
mprotect(0x104744000, 0x4000, 0x0)		= 0 0
mprotect(0x104750000, 0x4000, 0x0)		= 0 0
mprotect(0x10471C000, 0x90, 0x1)		= 0 0
mprotect(0x10471C000, 0x90, 0x3)		= 0 0
mprotect(0x10471C000, 0x90, 0x1)		= 0 0
mprotect(0x104754000, 0x4000, 0x1)		= 0 0
mprotect(0x104758000, 0x90, 0x1)		= 0 0
mprotect(0x104758000, 0x90, 0x3)		= 0 0
mprotect(0x104758000, 0x90, 0x1)		= 0 0
mprotect(0x10471C000, 0x90, 0x3)		= 0 0
mprotect(0x10471C000, 0x90, 0x1)		= 0 0
mprotect(0x104754000, 0x4000, 0x3)		= 0 0
mprotect(0x104754000, 0x4000, 0x1)		= 0 0
objc_bp_assist_cfg_np(0x1AEB103C0, 0x8000000000201048, 0x0)		= -1 Err#5
issetugid(0x0, 0x0, 0x0)		= 0 0
getentropy(0x16B819FC8, 0x20, 0x0)		= 0 0
getentropy(0x16B81A018, 0x40, 0x0)		= 0 0
getpid(0x0, 0x0, 0x0)		= 1135 0
stat64("/AppleInternal\0", 0x16B81A710, 0x0)		= -1 Err#2
csops_audittoken(0x46F, 0x7, 0x16B81A240)		= 0 0
proc_info(0x2, 0x46F, 0xD)		= 64 0
csops_audittoken(0x46F, 0x7, 0x16B81A300)		= 0 0
sysctlbyname(kern.osvariant_status, 0x15, 0x16B81A778, 0x16B81A770, 0x0)		= 0 0
csops(0x46F, 0x0, 0x16B81A79C)		= 0 0
mprotect(0x104610000, 0x100000, 0x1)		= 0 0
open_nocancel("/usr/share/locale/en_US.UTF-8/LC_COLLATE\0", 0x0, 0x0)		= 3 0
fcntl_nocancel(0x3, 0x3, 0x0)		= 0 0
getrlimit(0x1008, 0x16B81B148, 0x0)		= 0 0
fstat64(0x3, 0x16B81B0C0, 0x0)		= 0 0
read_nocancel(0x3, "1.1A\n\0", 0x1000)		= 2086 0
close_nocancel(0x3)		= 0 0
open_nocancel("/usr/share/locale/en_US.UTF-8/LC_CTYPE\0", 0x0, 0x0)		= 3 0
fcntl_nocancel(0x3, 0x3, 0x0)		= 0 0
fstat64(0x3, 0x16B81B1F0, 0x0)		= 0 0
fstat64(0x3, 0x16B81AFE0, 0x0)		= 0 0
lseek(0x3, 0x0, 0x1)		= 0 0
lseek(0x3, 0x0, 0x0)		= 0 0
read_nocancel(0x3, "RuneMagAUTF-8\0", 0x1000)		= 4096 0
read_nocancel(0x3, "\0", 0x1000)		= 4096 0
read_nocancel(0x3, "\0", 0x1000)		= 4096 0
read_nocancel(0x3, "\0", 0x1000)		= 4096 0
read_nocancel(0x3, "\0", 0x1000)		= 4096 0
read_nocancel(0x3, "\0", 0x1000)		= 4096 0
read_nocancel(0x3, "\0", 0x1000)		= 4096 0
read_nocancel(0x3, "@\004\211\0", 0xF5D0)		= 62928 0
close_nocancel(0x3)		= 0 0
open_nocancel("/usr/share/locale/en_US.UTF-8/LC_MONETARY\0", 0x0, 0x0)		= 3 0
fstat64(0x3, 0x16B81B210, 0x0)		= 0 0
read_nocancel(0x3, "USD \n$\n.\n,\n3;3\n\n-\n2\n2\n1\n0\n1\n0\n1\n1\n(\0", 0x22)		= 34 0
close_nocancel(0x3)		= 0 0
open_nocancel("/usr/share/locale/en_US.UTF-8/LC_NUMERIC\0", 0x0, 0x0)		= 3 0
fstat64(0x3, 0x16B81B210, 0x0)		= 0 0
read_nocancel(0x3, ".\n,\n3;3\n@$\b\0", 0x8)		= 8 0
close_nocancel(0x3)		= 0 0
open_nocancel("/usr/share/locale/en_US.UTF-8/LC_TIME\0", 0x0, 0x0)		= 3 0
fstat64(0x3, 0x16B81B220, 0x0)		= 0 0
read_nocancel(0x3, "Jan\nFeb\nMar\nApr\nMay\nJun\nJul\nAug\nSep\nOct\nNov\nDec\nJanuary\nFebruary\nMarch\nApril\nMay\nJune\nJuly\nAugust\nSeptember\nOctober\nNovember\nDecember\nSun\nMon\nTue\nWed\nThu\nFri\nSat\nSunday\nMonday\nTuesday\nWednesday\nThursday\nFriday\nSaturday\n%H:%M:%S\n%m/%d/%Y\n%a %b %e %X %Y\nAM\nP", 0x179)		= 377 0
close_nocancel(0x3)		= 0 0
open_nocancel("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/LC_MESSAGES\0", 0x0, 0x0)		= 3 0
fstat64(0x3, 0x16B81B220, 0x0)		= 0 0
read_nocancel(0x3, "^[yYsS].*\n^[nN].*\n(\0", 0x12)		= 18 0
close_nocancel(0x3)		= 0 0
geteuid(0x0, 0x0, 0x0)		= 0 0
ioctl(0x0, 0x4004667A, 0x16B81B77C)		= 0 0
fstatat64(0xFFFFFFFFFFFFFFFE, 0x16B81BC34, 0x16B81B670)		= -1 Err#2
renameatx_np(0xFFFFFFFFFFFFFFFE, "test1\0", 0xFFFFFFFFFFFFFFFE, "test2\0", 0|0|RENAME_EXCL)		= -1 Err#45
stat64("test2\0", 0x16B81B878, 0x0)		= -1 Err#2
fstatat64(0xFFFFFFFFFFFFFFFE, 0x16B81BC2E, 0x16B81B480)		= 0 0
fstatat64(0xFFFFFFFFFFFFFFFE, 0x16B81BC34, 0x16B81B3F0)		= -1 Err#2
fcntl(0x1, 0x3, 0x6B81B320)		= 65538 0
write_nocancel(0x2, "gmv: \0", 0x5)		= 5 0
write_nocancel(0x2, "cannot move 'test1' to 'test2'\0", 0x1E)		= 30 0
write_nocancel(0x2, ": Operation not supported\0", 0x19)		= 25 0
write_nocancel(0x2, "\n\0", 0x1)		= 1 0
lseek(0x0, 0x0, 0x1)		= 34002 0
lseek(0x0, 0x0, 0x1)		= 34002 0
lseek(0x0, 0x84D2, 0x0)		= 34002 0
close_nocancel(0x0)		= 0 0
close_nocancel(0x1)		= 0 0
close_nocancel(0x2)		= 0 0