Hello,
I am working on a daemon which collects information about disk space usage on macOS. APFS has quite complex structure and there is a challenge to get detailed info.
My application must provide disk usage by APFS containers.
- Are there any recommended way to get space usage by particular APFS volume?
- Are there any recommended way to get free space on particular APFS container?
- Are there any recommended way to enumerate APFS containers and volumes?
I am using Disk Arbitration to get APFS info. However, I get restricted info about space usage because I get get disk usage for mounted volumes only. Are there any public API (daemon-safe) which allows to easily get disk space usage on macOS?
Thank you in advance, Pavel
FYI, you also asked about APFS on this thread and I've moved you answer to that question on this thread.
Is it bug or ATTR_VOL_SPACEUSED is unsupported on macOS 11?
I don't know exactly why it was done, but I believe it was an intentional choice while the team was sorting out how APFS should "present" itself to the VFS system. ATTR_VOL_SPACEUSED is actually calculated in the VFS layer (you can see the code here if you're curious) and I suspect that at the time "vs.f_bused" wasn't giving a value that matched well with the "expectation" of the rest of the system. Disabling ATTR_VOL_SPACEUSED was the easiest way to prevent that from causing broader problems.
That leads to here:
Are there any other way to get space which is used on an APFS volume? (C++)
So, the "basic" answer is what's the described in "Checking Volume Storage Capacity". The more complicated answer starts with "What are you actually trying to do?". The big issue here isn't simply that APFS is more complicated (which it definitely is), it's that part of that transition was a broad shift in how the system manage storage.
Historically issues like slow I/O performance (particularly random I/O) and the file system locking architecture limited how aggressively the system relied on the file system. In concrete terms, if "enough" was happening at the same time, overall performance could collapse as random I/O spiked and/or locking bottlenecks in HFS+ hampered the file systems ability to process modifications. This generally wasn't an issue for normal user usage but it did mean that the system tried to limit how much "extra" I/O the system generated.
The transition to SSDs removed the first issue (I/O performance) and APFS largely resolved the second (file system locking), enabling a broad change in how the system manages local storage. The modern approach is built around the idea that unused storage is a "wasted" resource in much the same way that unused memory is. In very broad terms, the system tracks caching across the entire system and dynamically increases/decreases how much data is being cached based on storage demand from the "rest" of the system. It's goal is basically to maintain an empty buffer big enough (several GBs) to immediately handle demand spike and then allow the rest of storage to fill with "useful" cache data.
With all that background, let me move to here:
I am working on a daemon which collects information about disk space usage on macOS.
Why? What are you actually trying to understand from this information? The problem here is that a drive can be physically "full" under completely different circumstances:
-
The user has filled the device with "real" data and the volume really is "full".
-
The user has used some fraction of the device and the system has then filled the rest with "stuff" that it will happily delete as soon as that storage is needed.
Critically, those two cases (or the range in between) all look identical at the filesystem level ("the drive is full"). Differentiating between these cases is why the APIs in "Checking Volume Storage Capacity" exist.
My application must provide disk usage by APFS containers.
Are there any recommended way to get space usage by particular APFS volume?
Are there any recommended way to get free space on particular APFS container?
Are there any recommended way to enumerate APFS containers and volumes?
We don't have public API for any of this, however, the "diskutil" command line tool is intentionally architected to be usable as "semi-API". Note, for example, that most of it's command take a "-plist" argument, making the output easy to programmatically process. While there isn't any formal commitment to this, the engineering team understand the role it serve and it's argument and output format (particularly it's plist output) have been quite stable. Like any command line tool usage, you should be careful when processing it's output and fail gracefully if/when something changes, however, this is a tool that we expect apps be rely on.
I am using Disk Arbitration to get APFS info. However, I get restricted info about space usage because I get get disk usage for mounted volumes only. Are there any public API (daemon-safe) which allows to easily get disk space usage on macOS?
Whether or not the tool is daemon-safe doesn't actually matter* to your daemon, but I expect diskutil to work fine in a daemon context as long as you avoid commands which trigger UI. I can't easily provide a list of all those cases, but most of those cases should be clear from the man page and none of the informational commands should be an issue.
*A tool/command may not work in the daemon context but because it's running in a separate process, any issues it creates shouldn't effect your daemon.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware