Subject: bug#61386: [PATCH] cp,mv,install: Disable sparse copy on macOS

From: George Valkov <[email-masked]>
Date: Fri, 10 Feb 2023 14:13:20 +0200

> On 2023-02-10, at 11:18 AM, Pádraig Brady <[email-masked]> wrote:
> 
> On 10/02/2023 03:57, Paul Eggert wrote:
>> On 2/9/23 01:20, George Valkov wrote:
>>> -#ifdef SEEK_HOLE
>>> +#if defined(SEEK_HOLE) && !defined(__APPLE__)
>> Instead of always disabling the SEEK_HOLE optimization, how about doing
>> it only on APFS files? Something like the attached, perhaps (this is
>> against Savannah master).
>> If APFS is pretty much universal now on Apple platforms, this patch is
>> overkill and we should use your much-simpler patch.

Hi Paul,
I compiled your patch against git://git.savannah.gnu.org/coreutils.git
and it fixes the problem. But as I mention later, I think we should not use it.
Thank you!

> Thanks for doing that Paul.
> I think the simpler patch is best though
> since APFS is the default macOS file system since 2017,
> and upon upgrade earlier file systems are upgraded to that.

I agree. macOS supports HFS+ and APFS.
According to Wikipedia, HFS+ does not support sparse files.
On APFS we should not use SEEK_DATA since it is broken.
So the simple patch is better.

> Also SEEK_DATA doesn't seem to be a well supported feature
> on macOS anyway as there was also this issue:
> https://bugs.gnu.org/51857
> 
> I'll apply the simple patch later I think.

I have an interesting idea: If I copy a large file, say the 16 GB disk image
where I compiled OpenWRT. So I copy this on the same filesystem, and check
disk usage before an after: no change. Also the copy is instant. That’s because
APFS supports copy-on-write. Initially both files share the same sectors on disk,
any changes made after that are copied to new sectors.
This is the most efficient way to copy files on APFS, and should produce no corruption.
Let’s implement it. I would assume there is a system cal that does the entire copy,
And we don’t need to read and write any data.
Does the trace contain any interesting calls that might be related to that?

Regarding dtruss, on macOS there is integrity protection which prevents you
from debugging applications that came with macOS such as fined. I read
that in order to do this, integrity protection has to be disabled from recovery,
then copy the application to a non-system location, e.g. ~/ and finally
remove code signature. That’s why the traces I provided are limited, and it gets
tricky to do all of this, considering Finder runs all the time and the system
will restart it if it gets killed. But we need to run the copy. With that said, if you want,
I will give it a try.

dtruss [-acdefholLs] [-t syscall] { -p PID | -n name | command | -W name }
-p PID          # examine this PID
-n name         # examine this process name
-t syscall      # examine this syscall only
-W name         # wait for a process matching this name
-a              # print all details
-c              # print syscall counts
-d              # print relative times (us)
-e              # print elapsed times (us)
-f              # follow children
-l              # force printing pid/lwpid
-o              # print on cpu times
-s              # print stack backtraces
-L              # don't print pid/lwpid
-b bufsize      # dynamic variable buf size

Georgi Valkov
httpstorm.com
nano RTOS