The online documentation for fs_snapshot_create
, which is on a website which apparently I'm not allowed to link to on this forum, mentions that some entitlement is necessary, but doesn't specify which one. Searching online I found someone mentioning com.apple.developer.vfs.snapshot
, but when adding this to my entitlement file and building my Xcode project, I get the error
Provisioning profile "Mac Team Provisioning Profile: com.example.myApp" doesn't include the com.apple.developer.vfs.snapshot entitlement.
Searching some more online, I found someone mentioning that one has to request this entitlement from DTS. Is this true? I couldn't find any official documentation.
I actually want to make a snapshot of a user-selected directory so that my app can sync it to another volume while avoiding that the user makes changes during the sync process that would make the copy inconsistent. Would fs_snapshot_create
be faster than traversing the chosen directory and creating clones of each nested file with filecopy
and the flag COPYFILE_CLONE
? Although I have the impression that only fs_snapshot_create
could make a truly consistent snapshot.
I’m gonna let Kevin answer your main question
I can never resist a good file system question.
Searching some more online, I found someone mentioning that one has to request this entitlement from DTS. Is this true?
Yes, that is correct. However, the criteria for granting this entitlement are very narrow, so it is only granted to "backup" applications. I'm not sure that this would qualify:
I actually want to make a snapshot of a user-selected directory so that my app can sync it to another volume while avoiding that the user makes changes during the sync process that would make the copy inconsistent.
Having said that, I'm also not sure you need volume snapshotting for that. Breaking down your options:
Would fs_snapshot_create be faster than traversing the chosen directory and creating clones of each nested file with filecopy and the flag COPYFILE_CLONE?
So, there are three options here, loosely ordered by performance:
-
Create a snapshot with fs_snapshot_create.
-
Clone the entire directory using clonefile() (see "man clonefile")
-
Iteratively clone the files and recreate the directory (which is what copyfile would do).
Moving into the comparison side of things:
Although I have the impression that only fs_snapshot_create could make a truly consistent snapshot.
Semantically, #1 & #2 above are identical. Both of them create an atomic clone of a given hierarchy and, in fact, you can basically think of "fs_snapshot_create" as a special case of directory cloning that just happens to target the entire volume. You're correct that #3 does not create a TRULY consistent "snapshot", however, how important that actually is depends a lot on the overall context.
Comparing #2 & #3, the issue here is a tradeoff between performance and safety. I actually did a detailed pair of forum posts on that here, but the summary is that:
-
Directory cloning is significantly faster (~10x).
-
Iterative cloning is still quite fast in absolute terms.
-
The danger with directory cloning is that you can (potentially) block access to large parts of the file system, causing major performance problems, potentially even panic'ing the kernel.
That last point is the BIG issue here. If you're going to use directory cloning, then you need to either:
-
Already "klnow" that the source hierarchy is of "reasonable" size. Note that "reasonable" here isn't necessarily "small". Results will vary widely depending on the specifics of the underlying hardware but, for reference, it takes ~0.6s for clonefile() to clone a directory of ~10,000 files on my macBook Pro.
-
Ensure/"know" that the source directory won't have system wide consequence and/or disrupt the user.
...and, ideally, both. The big point here is that you probably shouldn't just let the user select and arbitrary source and then clone whatever directory they point at. However, the performance benefit is large enough that it's worth considering when the circumstances are appropriate.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware