Apple has released its weekly update to XProtect, bringing it to version 5318. As usual, it doesn’t release information about what security issues this update might add or change.
This version makes several changes to the Yara definition for MACOS.COMPLIANTPIRATE.DEFU, but doesn’t add any new detection rules.
You can check whether this update has been installed by opening System Information via About This Mac, and selecting the Installations item under Software.
A full listing of security data file versions is given by SilentKnight and SystHist for El Capitan to Tahoe available from their product page. If your Mac hasn’t yet installed this update, you can force it using SilentKnight or at the command line.
If you want to install this as a named update in SilentKnight, its label is XProtectPlistConfigData_10_15-5318
Sequoia and Tahoe systems only
This update hasn’t yet been released for Sequoia and Tahoe via iCloud, but hopefully will be shortly. If you want to check it manually, use the Terminal command sudo xprotect check
then enter your admin password. If that returns version 5318 but your Mac still reports an older version is installed, you should be able to force the update using sudo xprotect update
However, if the regular update has been installed in the old location, XProtect is likely to update its new location from that. There’s nothing you can do to force that, but it may well explain why your Mac seem to have updated itself.
If you ever encounter an error when checking an APFS volume using First Aid in Disk Utility or fsck_apfs, you won’t be informed of the path and name of the item responsible, but given its inode number, in an entry like warning: inode (id 402194151): Resource Fork xattr is missing for compressed file
The inode number given can only be resolved to a path and file/folder name if you also have a second number giving the volume for that item. As that will be for the volume being checked at the time, you should be able to identify that immediately. The only time that you might struggle to do that is with items in a snapshot; those should, I think, be the same as the volume they are taken from. However, as snapshots are read-only, there’s probably little point in pursuing errors in them.
To resolve these in my free utility Mints, open its inode Resolver using the Window / Data… / Inode menu command. Drag and drop another file from the same volume onto that window.
The Resolver will then display that file’s volfs path, such as /.vol/16777242/1241014
All you need do now is paste the inode number given in the warning or error message in Disk Utility or fsck_apfs, into the Inode Number box at the top of the Resolver window, and click the Resolve button. Mints then looks up information for that inode number on the same volume, using GetFileInfo, and displays it below.
One drag and drop, a paste, and a click to discover what APFS is complaining about.
Command line
You’ll sometimes see Terminal’s find command with the option -inum recommended as a way to convert from an inode number to a regular path. Although you can do that, it’s easier to use the command GetFileInfo instead. For that you’ll need the full volfs path, including the volume number.
To find the volume number, use my free utility Precize, and open another file on the same volume. The second line in its window gives the full volfs path for that file. Copy the start of that, leaving the second number, the inode, such as /.vol/16777238/
Alternatively, you can use the stat command as given below.
In Terminal, type GetFileInfo
with a space at the end, and paste the text you copied from Precize. Then copy and paste the inode number given in the First Aid warning, to assemble the whole command, such as GetFileInfo /.vol/16777238/402194151
Press Return, and after a few seconds, you should see something like file: "/Users/hoakley/Library/Mobile Documents/com~apple~CloudDocs/backup1/0MintsSpotlightTest4syzFiles/SpotTestA.rtf"
type: "\0\0\0\0"
creator: "\0\0\0\0"
attributes: avbstclinmedz
created: 05/17/2023 08:45:00
modified: 05/17/2023 08:45:00
giving the full path and filename that you want.
GetFileInfo is one of the oldest commands in macOS, and has been deprecated as long as anyone can remember. I suspect that Apple is still trying to work out what can substitute for it.
Get a volfs path for a file
Use Precize to run this the other way around: open the file and read the path in that second line. To copy the whole of it, press Command-2.
The simplest ways of obtaining inode numbers and so building volfs paths in Terminal are using the -i option to the ls command, and for individual items using stat: ls -i lists each item in the current directory, giving its inode number first, e.g. 22084095 00swift
13679656 Microsoft User Data
22075835 Wolfram Mathematica
and so on; stat myfile.text returns 16777220 36849933 -rw-r--r-- 1 hoakley staff […] myfile.text
where the first number is the volume number, and the second is the inode number of that item, or /.vol/16777220/36849933.
You’ve just run First Aid in Disk Utility, or fsck_apfs, and that reports warnings or errors. What should you do next?
Failure to unmount
By far the most frequent error encountered in Disk Utility’s checks results from its inability to unmount a volume before it can start testing. While this is reported as an error, and it prevents the checks from running, it can sometimes be solved by manually unmounting the volume in question. It normally doesn’t indicate anything sinister, and is simply frustrating.
Repeat in Recovery mode
If the warnings or errors were reported on your current boot Data volume and you ran that check in normal user mode, consider starting your Mac up in Recovery mode to repeat the check there.
Although macOS does an impressive job of performing checks on a live volume, it’s more reliable and more likely to be able to perform any repairs needed in Recovery mode, when the Data volume isn’t mounted and live. When there, if you prefer, you can still use fsck_apfs in Terminal.
The other case where checks may be best made in Recovery are those on an active Time Machine backup volume. That’s because those can be difficult to unmount before running the checks, although that is possible as long as a backup isn’t being made at the time, or Spotlight indexing taking place. The sure way to avoid those is to do so in Recovery mode.
Warnings or errors?
Any remarks about problems or irregularities encountered during checks should make explicit whether they are warnings or errors, and it’s essential to make a clear distinction between them.
Warnings are observations that could have significance, or might be perfectly normal in the circumstances. Only an APFS engineer is likely to be able to tell the difference. Among the commonest are those reporting missing xattrs for compressed files: warning: inode (id 113812826): Resource Fork xattr is missing for compressed file
Experience is that those aren’t related to any consequent errors, and you should be able to leave those alone.
Errors are abnormalities that do have more significance, and might have the potential to cause further problems. Where possible, First Aid or fsck_apfs should attempt to repair those, most probably by performing “deferred repairs”. Those are normally minor errors that it already has plans to attend to when that volume is next mounted, the time that APFS normally performs its routine maintenance.
Snapshots
These are read-only copies of the file system metadata at a previous instant in time, and are associated with retained storage blocks. They aren’t part of the active volume, and their metadata are separate. As they’re read-only, any warnings or errors are most unlikely to be fixed, so you have a choice of leaving that snapshot to be deleted routinely by age, or deleting it early yourself.
Snapshots are made by backup utilities including Time Machine, which are required by Apple to have a mechanism that will delete them automatically after a set period. In the case of Time Machine, that’s when the snapshot is over 24 hours old. Snapshots aren’t backups, but augment regular backups, and stand in for them when backup storage isn’t available. In general, there seems little point in deleting a snapshot early just because there’s a reported warning or error for it, as that won’t affect the health of the active volume.
Identifying faulty items
Warnings and errors related to specific files or directories are normally given with an item id, which should be their inode number. To go any further, you’ll need to convert that to a path and file/directory name. You should therefore copy and paste all reports into a separate file as reference. Resolving an inode to a path and item name is detailed in this article.
In many cases involving items that can be resolved to an existing path, the faulty item is in one of the hidden folders such as .Spotlight-V100 for Spotlight indexes, or .DocumentRevisions-V100 for the document version database. In the former, rebuilding Spotlight’s indexes may resolve the problem, but you’re unlikely to be able to do anything about the latter.
If the inode resolves to a regular file, deleting that can remove the problem, but when you try restoring that file from a backup you may discover the backup has the same problem. Getting to the bottom of a recurrent file system error might require the knowledge and skills of an Apple engineer. Consider reporting this using Feedback, as it should then help iron out any remaining bugs in APFS.
You should also consider whether your Mac might be running old third-party software that is causing recurrent errors. Normally, products should work at a higher level that isolates them from the file system itself, but there are some surprising exceptions. If you can identify a cause, please inform the developers of that software so that it can be fixed.
Old versions of APFS
One potentially dangerous practice occurs when an older version of APFS changes a newer file system. APFS back in High Sierra and Mojave knew nothing of boot volume groups, firmlinks, or many of the features of more modern versions of APFS. If you really must run different versions of macOS on the same Mac, or shared external storage, avoid such version conflicts, and never run an older version of Disk Utility or fsck_apfs on a newer APFS container or volume.
I hope that you enjoyed Saturday’s Mac Riddles, episode 328. Here are my solutions to them.
1:
Carlos Schwabe (1866–1926), Evening Bells (1891), watercolour, dimensions not known, Museu Nacional de Belas Artes (MNBA), Rio de Janeiro, Brazil. Wikimedia Commons.Click for a solution
Angels
Schwabe’s painting shows a chain of angels emerging from a belfry.
2:
Gustave Doré (1832–1883), The Demons Threaten Virgil (c 1857), engraving, dimensions and location not known. Image by Karl Hahn, via Wikimedia Commons.Click for a solution
Daemons
Doré’s engraving shows The Demons Threaten Virgil, from his illustrations to Dante’s Inferno.
3: James Bond, Jason Bourne, George Smiley, Modesty Blaise
Click for a solution
Agents
They are each (secret) agents: James Bond from Ian Fleming, Jason Bourne from Robert Ludlum, George Smiley from John le Carré, and Modesty Blaise from Peter O’Donnell.
The common factor
Click for a solution
They are each run by launchd from property lists in folders titled LaunchAngels (new in Tahoe), LaunchDaemons and LaunchAgents.
For many years, I believed what the log command told me, that log entries could contain any of the 26 or more fields available, although they didn’t. It was only as I was developing utilities like LogUI that I discovered that log entries come in (at least) four types, each with its own format and set of fields. This article is a guide to those, and how they are displayed in LogUI.
Entry fields
Those available in the OSLog API are fewer in number than appear in log command output, and include some of limited interest. Those not exposed in LogUI include:
store category, which is invariably disk storage here.
format string, that used to format the contents of messages. This was introduced following serious security leaks in High Sierra.
components, linking in with the format string.
LogUI displays each entry using the same order of fields and colour-coding. Although they can’t all be seen together in any single log entry, the overall sequence is:
Standard levels are given as text, and chosen from one of the following: fault, error, notice, info, debug, undefined. These are only used with Regular log entries, not other types. LogUI always includes debug level entries when they’re available.
The four types of entry are:
Regular
Activity
Boundary
Signpost.
Regular entries
These are normally by far the most common, and are seen throughout the processes and subsystems writing log entries. They normally contain up to the following fields:
datestamp, [1], activity ID, category, level, sender, process, process ID, subsystem, thread ID, message
These examples include:
datestamp, 1, activity ID, category, level, sender, process, process ID, subsystem, thread ID, message
which is fairly normal.
Activities
These mark specific activities, and vary according to the process and subsystem. Some are valuable waypoints, and all are recognisably shorter than most regular entries, containing only the following fields:
datestamp, [2], activity ID, parent activity ID, sender, process, process ID, thread ID, message
These are examples of one of the most valuable activities reported, indicating a mouse-click or tap. They’re also complete, as they consist of:
datestamp, 2, activity ID, parent activity ID, sender, process, process ID, thread ID, message
Boundaries
These are rare but instantly recognisable because of their brevity. They consist of just three fields:
datestamp,[3], message
Two of the most important are the announcement of the start of kernel boot:
and adjustment of the internal clock:
These are also easy to search for, as their message contains the distinctive === string.
Signposts
By default, LogUI extracts omit Signposts, but if you tick the Show Signposts box before loading log entries, they will also be displayed. In parts, they can outnumber regular entries, and are unlikely to provide you with meaningful information unless you know internal details of their process. Each Signpost adds three type-specific fields, shown after the process ID:
datestamp, [4], activity ID, category, sender, process, process ID, signpost ID, signpost name, signpost type, subsystem, thread ID
These examples come from the most prolific user of Signposts, SkyLight for WindowServer, and contain
datestamp, 4, activity ID, category, sender, process, process ID, signpost ID, signpost name, signpost type, subsystem, thread ID
Note there’s no message field, as their meaning is determined by the signpost fields.
Datestamps and times
The OSLog API doesn’t currently give access to Mach times, only to opaque Date variables. From those, LogUI’s datestamps give:
year–month–day hour:minute:second.microsecond+timezone
All times and time zones given are those current when LogUI obtains that extract, not when that entry was written. This can become extremely confusing when clocks change to and from {summer time, daylight time, daylight saving time, daylight savings time, DST}, and when passing through time zones, and great care is required when reading logs containing such corrections. LogUI tries to make this easier, but care is still required.
If you have used the log command, you may be aware that can return Mach times as ticks, offering precision down to the nanosecond. This currently isn’t possible when using the OSLog API, but given the relatively slow clock of Apple silicon Macs, it’s no longer as useful as it used to be with Intel’s nanosecond Mach ticks.
Censorship
By default, all data in message fields is censored to protect the privacy of the user. This replaces chunks of text with the dreaded <private>, and can render many entries devoid of any useful information. In recent versions of macOS log privacy can be removed by installing a profile. However, that doesn’t apply retrospectively, only to log entries collected after the profile has been installed.
Removing privacy also increases the size in storage of log entries, and may reveal sensitive information. As soon as you have completed acquisition of the logs you need with privacy removed, you should therefore remove the profile, to allow normal censorship to resume.
To install the profile, unzip the archive into a convenient folder and double-click it. You’ll be informed by a notification that you need to review the profile to install it. Open System Settings and select Device Management in its View menu, or search for it. Follow the instructions given there to install and activate it.
Sadly, this doesn’t cover all censorship. Some systems require additional configuration changes, for example CFNetwork diagnostic logging. Jeff Johnson explained how to enable that, but Apple has since blocked that, and I don’t know of a practical alternative. In some cases, additional detail can be obtained by adjusting log settings.
Summary
A short practical summary of LogUI’s log entries is provided in its Help book.
Before macOS Tahoe, the biggest sticking point in virtualising macOS on Apple silicon Macs has been their lack of support for the App Store. From the outset this has been an ironic limitation. Here’s some of Apple’s most advanced technology running on its latest hardware, and it can’t even run the apps that Apple sells, only those supplied direct by their developers.
VMs can now have iCloud and iCloud Drive support, Messages, FaceTime, FileVault, and plentiful shared folders, but the one thing they have lacked that renders them useless for many users and many purposes is that can’t sign into Apple services, particularly the App Store. Some apps, including those in Apple’s iWork suite, will run in a VM despite it being unable to sign into your account, but you can only window-shop in the App Store, and most of its apps will simply refuse to run, even free ones.
I’ve long suspected that this is an example of Apple Commercial constraining Apple Engineering. To be useful, macOS VMs would have to be exempted limits on the number of Macs authorised to access services, and that could open up the possibility of third-parties bypassing FairPlay and the digital rights controls embedded in macOS. It must be deeply frustrating to those working on virtualisation, knowing that it could be done but won’t be.
So the only substantial new feature for macOS virtualisation in Tahoe is the introduction of ASIF disk images. For the time being, I’m not sure they’re going to change much for most of us who host our VMs on local APFS storage. As they still don’t enjoy proper API support, I don’t see any compelling reason to rush into their use, unless you want to host your VMs in the cloud.
Upgrading to Tahoe has, though, drawn attention to problems lurking for those who created VMs of 50 GB or smaller, who now want to enlarge them for this purpose.
Resizing VMs
Don’t skimp when creating a new VM. Give it a useful size, as its Disk.img is stored as a sparse file, so won’t take all that disk space unless you fill it to capacity. I now make my default VMs 100 GB to ensure there’s ample free for updates and anything else that might arise.
If you do have a treasured VM that’s too small, you may well be able to increase its size, either using Disk Utility or the hdiutil resize command tool if you prefer. To do this, start by duplicating your VM in the Finder. That creates a clone, and lets you fall back to the unaltered original if the resizing goes horribly wrong.
To resize the disk image using Disk Utility, you first have to move it out from inside its VM bundle, easily done in the Finder. Then in Disk Utility’s Images menu use the Resize… command, select that Disk.img and enter its new size. Add a little, around 8%, to allow for overheads, and let Disk Utility get on with the work.
Here’s Disk Utility inside this Tahoe VM, showing its 50 GB virtual disk.
I then resized it to just over 100 GB.
Here it is afterwards, now showing a full 100 GB.
I gather from others that resizing doesn’t always work. If you can’t get it to, then the only way forward is to create a new VM with the larger capacity and copy across the contents of your old VM. One obvious way to make that simpler and more thorough would be to use Migration, either during configuration of the new VM, or shortly afterwards.
I’m very grateful to Michael for telling us of his success in migrating from a small to a larger VM in Tahoe. I’m also more than a little jealous, as I’ve so far been unable to get it to work for me.
I’m also mystified as to how two macOS VMs running concurrently on the same Mac could establish a connection to support the file transfers required in migration. Neither can expose its virtual folders as shared folders for the other, and in any case shared folders are strictly circumscribed. Sharing them over AFP runs into a quirk of their bridged networking, that both of the VMs will default to using the same network IP address. In my failed tests, the destination Migration Assistant was able to recognise the source, but failed to connect to it successfully.
For the moment macOS virtualisation hasn’t made any substantial improvements in Tahoe. It still can’t sign into Apple services, and AI remains unavailable. Let’s hope the next year brings more and better, and realises more of its potential.
Here are this weekend’s Mac riddles to entertain you through family time, shopping and recreation.
1:
Carlos Schwabe (1866–1926), Evening Bells (1891), watercolour, dimensions not known, Museu Nacional de Belas Artes (MNBA), Rio de Janeiro, Brazil. Wikimedia Commons.
2:
Gustave Doré (1832–1883), [title withheld] (c 1857), engraving, dimensions and location not known. Image by Karl Hahn, via Wikimedia Commons.
3: James Bond, Jason Bourne, George Smiley, Modesty Blaise.
To help you cross-check your solutions, or confuse you further, there’s a common factor between them.
I’ll post my solutions first thing on Monday morning.
Please don’t post your solutions as comments here: it spoils it for others.
Every self-respecting file system identifies files and directories using numbered data structures. In most modern file systems, those data structures are known as inodes, and their numbers are inode numbers, sometimes shortened to inodes. The term is thought to be a contraction of index node, which certainly makes sense, but is lost in the mists of time.
In any file system, for example an individual APFS volume, the inode numbers uniquely identify each inode, and each object within that file system has its own inode. Whatever else the file system might do, the inode number identifies one and only one object within it. Thus one invariant way of identifying any file is by referencing the file system containing it, and its inode number.
HFS+
The Mac’s original native file systems, ending most recently in Mac OS Extended File System, or HFS+ from its origins in the Hierarchical File System, don’t use inodes as such, and don’t strictly speaking have inode numbers. Instead, the data structures for their files and folders are kept in Catalogue Nodes, and their numbers are Catalogue Node IDs, CNIDs.
With Mac OS X came Unix APIs, and their requirement to use inodes and inode numbers. As CNIDs are unique to each file and folder within an HFS+ volume, for HFS+ they are used as inode numbers, although in some ways they differ. CNIDs are unsigned 32-bit integers, with the numbers 0-15 reserved for system use. For example, CNID 7 is normally used as the Startup file’s ID.
Although not necessarily related to CNIDs, it’s worth noting that the Mac’s original file system MFS allowed a maximum of 4,094 files, its successor HFS was limited to 65,535, and HFS+ to 4,294,967,295. Those are in effect the maximum number of inode numbers or their equivalents allowed in that file system.
APFS
Unlike HFS+, APFS was designed from the outset to support standard Posix features, so has inodes numbered using unsigned 64-bit integers.
Strictly, the APFS inode number is the object identifier in the header of the file-system key. Not all unsigned 64-bit integers can be used as inode numbers, though, as a bit mask is used, and the number includes an encoded object type. APFS also makes special allowance for volume groups consisting of firmlinked System and Data volumes, to allow for their inode numbers to remain unique across both volumes. Officially, those allow for a maximum number of inode numbers of 9,223,372,036,854,775,808, either in single APFS file systems, or shared across two in a volume group.
Every file in APFS is required to have, at an absolute minimum, an inode and its associated attributes, shown above in blue, including a set of timestamps, permissions, and other essential information about that file.
There are also three optional types of component:
although some files may be dataless, most have data, for which they need file extents (green), records linking to the storage blocks containing that file’s data (pink);
smaller extended attributes (yellow), named metadata objects that are stored in a single record;
larger extended attributes (yellow), over 3,804 bytes in size, whose data is stored separately in a data stream.
Interpretation
When looking at inode numbers in volume groups, they can be used to determine which of the firmlinked file systems contains any given file. Both volumes share the same volume ID, and files in the System volume have very high inode numbers, while those in the Data volume are relatively low. I have given further details here.
Inode numbers are more generally useful in distinguishing files whose data appears identical, and the behaviour of various methods of linking files.
Copying a file within the same file system (volume) creates a new file with its own inode number, of course. However, duplicating a file within the same file system results in an APFS clone file, with a distinct inode, although it shares common data, so their inode numbers are also different.
Instead of duplicating everything, only the inode and its attributes (blue and pink) are duplicated, together with their file extent information. There’s a flag in each clone file’s attributes to indicate that cloning has taken place.
A symbolic link or symlink is merely a pointer to the linked file’s path, and doesn’t involve inode numbers at all. Because of that, changing the linked file’s name or path breaks its link. Finder aliases and their kindred bookmarks do contain inode numbers, so should be able to cope with changes to the linked file’s name or path, provided it remains in the same file system and doesn’t change inode number.
Hard links are more complex, and depend on the way in which the file system implements them, although the fundamental rule is that each object that’s hardlinked to the same file has the same inode number. According to Apple’s reference to APFS, this is how it handles hard links.
When you create a hard link to a file (blue), APFS creates two siblings (purple) with their own IDs and links, including different paths and names as appropriate. Those don’t replace the original inode, and there remains a single file object for the whole of that hardlinked file.
Inode attributes keep a count of the number of links they have to siblings in their link (or reference) count. Normally, when a file has no hard links that’s one, and there are no sibling files. When a file is to be deleted, if its link count is only 1, the file and all its associated components can be removed, subject to the requirements of any clones and applicable snapshots. If the link count is greater than 1, then only the sibling being removed is deleted.
Easy access
Inode numbers are readily accessed using command tools in Terminal. For example, ls -i lists items with their inode numbers shown. One free utility that displays full information about inode numbers and much more is Precize.
The volume ID is given as the first number in the volfs path, and the second is the inode number of that file within that. Note that the File Reference URL (FileRefURL) uses a different numbering system, and the Ref count of 1 indicates this file has no hard links.
Browsing through the /System/Library folder in macOS Tahoe you’ll no doubt be surprised to see a new folder, between LaunchAgents and LaunchDaemons, named LaunchAngels. This article takes a preliminary look at what’s in there, and what these new additions to Apple’s bestiary do.
Launch Agents and Launch Daemons
These have been used in macOS for a great many years, probably since the introduction of launchd in Mac OS X 10.4 Tiger in 2005. These folders contain property lists for:
Launch Daemons are standalone background processes managed by launchd, running as root before the user logs in, and communicating indirectly with user processes, normally by XPC. They’re not allowed to connect to WindowServer.
Launch Agents are also managed by launchd, but normally run on the user’s behalf, communicating with other processes and daemons. Although they can have GUI interfaces, they’re normally minimal.
Before you have logged in, launchd runs services and other components specified in property list files in the LaunchAgents and LaunchDaemons folders in /System/Library, and in /Library. Those in /System/Library are all part of macOS, owned by Apple, and locked away on the SSV, but those in /Library can include those installed by third party products, although these days more are being enclosed in app bundles. As they’re run before the user logs in, those work for all users, so are global services.
These property list files contain keyed settings to determine what launchd does with what. Although they can contain many other key-value pairs, two most important ones are ProgramArguments (or Program), which tells launchd what to run, and RunAtLoad, which determines whether launchd should run the service or app whenever your Mac starts up and it loads those agents and services. Other keys determine whether the agent/service should be kept running at all times; if that is set, if it crashes or is otherwise terminated, launchd will automatically start it up again. That’s important for background services that apps rely on to function.
Launch Angels
As of macOS 26.0.1 there are three Launch Angels, each with a property list in /System/Library/LaunchAngels. Those relate to three apps now in /System/Library/CoreServices,
AccessibilityUIServer,
GameOverlayUI,
PosterBoard.
AccessibilityUIServer is an addition to the Accessibility process group, and is listed in the processes in Activity Monitor as Accessibility. It thus runs in the background, supporting Accessibility features in Tahoe. These might perhaps extend the Accessibility enhancements for UIKit provided in UIAccessibility to macOS.
The other two apps aren’t run at load, so must be run on demand. GameOverlayUI appears to be responsible for providing the new Game Overlay features, and I suspect that PosterBoard is responsible for Lock Screen customisation. A key set for each of these in their property list is _ExperimentalNonLaunching, suggesting that these are still in test.
Apple describes Game Overlay as allowing “players to stay in the game when it matters most. Players can easily adjust settings, connect with friends, and check out the latest In-App Events and supported Game Center features, all without leaving their game.”
RunningBoard
What’s most unusual, and may be new with Tahoe, is that all three property lists include settings for RunningBoard and its life cycle management. These are the keys
Managed, to require life cycle management by RunningBoard, set to true for all three;
Reported, presumably to set RunningBoard to report its use of system resources, again set to true for all three.
I’m not aware of any similar RunningBoard settings for property lists in the LaunchAgents or LaunchDaemons folders, though.
Conclusions
Launch Angels are currently three new services for macOS 26 Tahoe, run through launchd using property lists in /System/Library/LaunchAngels.
Those extend Accessibility, provide Game Overlay, and probably support Lock Screen customisation.
They are unusual in having RunningBoard settings in their property lists.
At least for the moment, Apple doesn’t intend anyone else trying to use Launch Angels of their own.
As the LaunchAngels folder is on the SSV, it isn’t exploitable. Whether a LaunchAngels folder might work in the main Library folder is a different question, though.
If you bought an M1 Mac with just a 256 GB internal SSD and have kept up with macOS upgrades and updates, should you be worried that it’s running out of space by the time it makes it to Tahoe? Dare you look at Storage settings to see how much of the SSD is now swallowed up by System Data? This article explains why macOS 26 shouldn’t devour the last of your SSD, and how you can ensure that it doesn’t.
What’s on your Mac’s internal SSD?
Internal boot disk layout is most complex in Apple silicon Macs, as theirs is divided into three partitions (or APFS containers). Two are hidden and contain pre-boot and other low-level support files, and amount to around 6 GB. The Macintosh HD partition then takes the lion’s share, the whole of the remainder. Even on a 256 GB SSD, that’s about 250 GB.
Volumes within Macintosh HD include:
System, just over 12 GB,
VM, varies in size according to how much virtual memory is swapped out to disk,
Preboot, just under 8 GB,
Recovery and others not normally mounted, a total of less than 2 GB,
Data, whose size is determined by what you store there.
The system your Mac actually boots into isn’t the System volume itself, but a snapshot made of it, occupying the same space, plus a little extra for the snapshot’s metadata including its tree of hashes to form its seal and signature. Because this is a snapshot it uses the same data stored for the System volume, and doesn’t double that up.
This should allow your Data volume a maximum of 228 GB, less any space required by the VM volume. Although installation of a macOS upgrade or update will require substantial additional space, once that’s complete the space taken by the System volume and its snapshot should fall to little more than 12 GB.
What happens when macOS is upgraded?
In traditional macOS upgrades, the Installer app was downloaded first, and itself required around 13-15 GB. That was run, and expanded its contents to be installed onto the System volume, replacing much or all of it.
Updates work more economically, as they contain only the files that have changed, so far less than the Installer app. When they’re installed, they replace only those files changed in the System volume, ready for a new snapshot to be made from that, to be used to boot that Mac. So an update-style upgrade, as you should get when going from macOS 15.7 to 26.0, should require a much smaller download, a faster install, and less space to install the new version of macOS. However, the end result should be identical, with exactly the same files installed in the System volume, and exactly the same in the snapshot used when running.
Whichever is used, the installation process is similar. First, the files to be installed are expanded, then they’re written to the mounted System volume, with some going onto the Data volume as well. Once the System volume is complete, a snapshot is made of it, and that’s sealed using a tree hierarchy of hashes, culminating at the top of the tree in the seal.
What is System Data?
Storage settings scans the contents of the boot volume group, Macintosh HD, and divides the storage used into different categories like Applications and Podcasts. It appears to total those up and account for the remainder of storage used in the category System Data. That doesn’t include the size of the System volume, or its snapshot, but can include temporary files like caches, snapshots, and anything else it can’t account for in other categories.
Taking control
If there are substantial amounts of space that aren’t accounted for on your Mac’s internal SSD, and you want to reduce that, you need to account for it before deciding what to do about it.
First check for large snapshots. I hear repeatedly of Macs that turn out to have hundreds of GB being used by snapshots unnecessarily, and the current record is over 400 GB. The easiest place to check for those is in Disk Utility. In the sidebar on the left select the Data volume, then Show APFS Snapshots in the View menu for them to be displayed at the foot of the main view.
Backup utilities including Time Machine normally make a snapshot with each backup, and retain them for 24 hours, following which they’re automatically deleted. As snapshots can’t exclude folders in the way that Time Machine can in its backups, if you’ve been working with a couple of 100 GB VMs then they will be retained in snapshots even though you probably exclude them from being backed up.
Once you’re happy that free space isn’t being retained in snapshots, use a disk mapping utility like DaisyDisk or GrandPerspective to hunt down other large files and folders that you may not need. One reader here recently discovered that their iOS and iPadOS backups had taken over more than half the space on their Mac’s SSD.
DaisyDisk, showing a breakdown of the space occupied by items in one folder.
Wait a day or two after upgrading
Installing a macOS upgrade also changes files on your Data volume, and may retain temporary support files. These are normally cleaned up in the next 24 hours, and you may be able to encourage that by starting your Mac up in Safe mode, leaving it a couple of minutes, then restarting it in normal user mode.
By a couple of days after the upgrade, your Mac should have returned to normal use of storage. If it hasn’t, check snapshots and go hunt that missing space.
Apple has released its weekly update to XProtect, bringing it to version 5317. As usual, it doesn’t release information about what security issues this update might add or change.
This version adds five new detection signatures to its Yara file. These include another newcomer with four signatures, MACOS.DAILYDUMPLING, and MACOS.SOMA.SEEND to add to the large Amos/Soma family.
You can check whether this update has been installed by opening System Information via About This Mac, and selecting the Installations item under Software.
A full listing of security data file versions is given by SilentKnight and SystHist for El Capitan to Tahoe available from their product page. If your Mac hasn’t yet installed this update, you can force it using SilentKnight or at the command line.
If you want to install this as a named update in SilentKnight, its label is XProtectPlistConfigData_10_15-5317
I apologise for the late announcement of this update, which seems to have been released after 22:00 GMT on 30 September, but was still incomplete here through the whole of today, 1 October.
Sequoia and Tahoe systems only
This update has already been released for Sequoia and Tahoe via iCloud. If you want to check it manually, use the Terminal command sudo xprotect check
then enter your admin password. If that returns version 5317 but your Mac still reports an older version is installed, you should be able to force the update using sudo xprotect update
As promised earlier this week, I’m delighted to offer a new version of my log browser LogUI that provides a Diagnostics Tool to help you understand log folders and discover any problems with them.
Open its window using the Diagnostics Tool command in the Window menu, and you’re offered four tools at the top.
The first, Get Info, performs a simple analysis on the files in the selected diagnostics folder. By default, that’s your current live log, in the path /private/var/db/diagnostics, in your Data volume. After telling you how many log files there are in each of its three main folders, and the number of timesync files, it reports the date and time of the oldest Persist log file, marking the start of the continuous log record, in this case nearly 4 days ago.
You can use these tools on any diagnostics folder you can access through its dialog. This includes Time Machine backups, external boot disks, and other bootable systems. Don’t click on the Open button, though, until you’ve selected the diagnostics folder in the view above.
Locating the diagnostics folder in a Time Machine backup can be interesting, but once you’ve found it, LogUI will happily check it for you.
The Catalogue tool lists all the tracev3 log files in the folders inside diagnostics, starting with those in Persist. It gives each file’s creation and modification timestamps, indicating the range for log entries within them, their size in bytes, and an estimate of the period that file covers.
The Analyse tool extracts information from each of logd‘s statistics files, with the number of log entries broken down in frequency order. If you tick the CSV checkbox, they will be delivered in CSV format, ready to import into other software such as a spreadsheet.
The last of the tools, Save Text, saves the contents of the window to a text file for your records.
Further information about locations used for log files is in this article.
LogUI 1.0 build 74 is now available from here: logui174
from Downloads above, and from its Product Page.
One seemingly widespread complaint about recent versions of macOS has been slow launch times of notarized apps even after they have cleared quarantine in their first run. Debate on the cause of this was vigorous in April and May, but was overtaken by Apple’s announcement of macOS 26 Tahoe. I therefore postponed further work on app launch and Gatekeeper until after Tahoe’s release.
This proved worthwhile, as soon after the first beta-release, it was suggested that Tahoe would accelerate the first launch of notarized apps by exempting them from a malware scan, although I have been unable to confirm that from Apple’s published information. That would make good sense: if an app’s CDHashes verify and match those of its notarization ticket, and no known malware was found when it was notarized, then it’s not plausible for it to contain malicious content since notarization was performed. This article considers what has changed in Gatekeeper in macOS 26.0.
Although Apple hasn’t yet updated it for macOS 26, its Platform Security Guide explains what Gatekeeper does in macOS Sequoia. For an app, plug-in or an installer package downloaded from outside the App Store and opened on a Mac, Gatekeeper verifies the software:
is from an identified developer, in signature checks;
is notarised by Apple to be free of known malicious content, in notarization ticket checks;
hasn’t been altered, in CDHash verification;
doesn’t contain known malicious content the first time it’s opened, regardless of how it arrived on the Mac, in a first run XProtect scan.
To assess this, I have used Calibre version 8.11.0 installed in a macOS virtual machine running on a Mac mini M4 Pro. Calibre is a large app at just over 1 GB with many components to be checked. This version has 82 items in its Frameworks folder, 20 executables in its MacOS folder, and 25 dylibs in its Plugins folder, totalling 113 dylibs and others that need to be checked.
Two VMs were prepared, one with macOS 15.7 Sequoia installed, the other with macOS 26.0 Tahoe. Both were run with 5 CPU cores, 16 GB memory, 100 GB disk, and bridged networking.
Calibre was launched three times in Tahoe, first when freshly installed and still in quarantine. Following that, the VM was shut down, started up 4 hours later and Calibre was run a second time. The VM was shut down again, and started up two days later for a third run. Log extracts were collected within a minute using LogUI.
Tahoe: First run in quarantine
This proceeded similarly to first run in Sequoia, with the exception of XProtect malware scanning. Soon after com.apple.syspolicy.exec reported that a GK (Gatekeeper) process assessment was starting, it wrote the log entry Skipping up front XProtect scan on: PST: (path: f0970f7f0ab1ff9f), (team: NTY7FVCEKP), (id: (null)), (bundle_id: (null))
That was reiterated later, shortly before the outcome of the GK evaluation Skipping XProtect scan on seen software: PST: (path: f0970f7f0ab1ff9f), (team: NTY7FVCEKP), (id: (null)), (bundle_id: (null))
There were no other log entries that suggested an XProtect malware scan had been attempted.
As is normal in the first run, notarization was checked using CloudKit, there was abundant evidence of CDHash verification, the user was prompted for their approval, and once that was complete the code was allowed to proceed.
Despite the lack of an XProtect scan, launch was as long as previous first runs in recent versions of macOS, taking 10.4 seconds from the second click to launch the app, to display of the prompt for user approval. During that period, a standard progress dialog was displayed. Entries in the log consisted of about 13,000 messages of SecKeyVerifySignature from syspolicyd and trustd, with repeated errors of SecError com.apple.securityd Malformed anchor records, not an array
Tahoe: Subsequent runs
The second and third runs, out of quarantine, were almost identical in the log, and similar to those in macOS 15.7 (below). com.apple.syspolicy.exec announced early that the code had already been evaluated, and those previous results would be used. Provenance data was found, and the evaluation completed without any CloudKit check of notarization. Times from the second click to launch the app, to loading of the app’s preferences were 0.64 and 0.66 seconds.
At various times, the kernel reported that it was considering a malware scan on one of the executables being checked, for example ASP: considering malware scan (activeRulesVersion: 11716915239283693719 lastScanVersion: 0 chgtime: 1758884893 lastFileScanTime: 1758884893 threshold: 1758884893 pid: 949 info_path: /Applications/calibre.app/Contents/MacOS/calibre proc_path: /Applications/calibre.app/Contents/MacOS/calibre isNewerThanScan: 0 needsVersionScan: 0 is_time_eval_exempt: 0 is_scan_version_exempt: 1
Those appear new to macOS 26, and haven’t been seen in any log records from macOS 15.7 or earlier. Executables cited in those messages extended beyond components of Calibre to others that happened to be running at the time, but none was followed by any report of whether a scan was performed as a result.
Although they didn’t delay app launch, at the same time amfid entered the path of the main executable and 112 dylibs and others to check each individually. For the dylibs and others, each was accompanied by a report from the kernel of AMFI: constraint violation [dylib path] has entitlements but is not a main binary
Those took a period of approximately 3 seconds in each of the two runs.
Sequoia: 2nd and 3rd runs
These were remarkably similar, and in many parts identical, to those in Tahoe, except that there were no messages reporting consideration of malware scans. Times from the second click to launch the app, to loading of the app’s preferences were slightly quicker than Tahoe, at 0.59 and 0.59 seconds. Concurrent time to iterate through all the executable components was also shorter at 2.6 seconds, with identical reports of constraint violations.
Conclusions
macOS 26.0 Tahoe does now skip reported XProtect malware scans when a notarized app is run for the first time, when in quarantine.
Despite that, first run checks undertaken in Tahoe can still take significantly longer than in subsequent runs.
This is the result of a vast number of SecKeyVerifySignature entries written during checks on executables.
Tahoe also considers explicitly whether to perform malware scans on other processes being run, although none were undertaken. These are new in Tahoe.
From this evidence, I’m not convinced of any significant improvement in launch times. Please let me know whether you think that Tahoe has improved the speed of your app launches.
Apple has just released macOS 26.0.1 Tahoe, which fixes the problem upgrading to 26.0 on Mac Studio M3 Ultra models, and apparently fixes other urgent bugs.
For Apple silicon, the update is a 1.76 GB download.
Tahoe 26.0.1 fixes a single vulnerability, although Apple doesn’t report that it’s already being exploited. The same is also fixed in Sequoia 15.7.1, and in Sonoma 14.8.1.
macOS 26.0.1 has build number of 25A362, Safari version 26.0.1 (21622.1.22.11.15), and a Darwin Kernel version of 25.0.0. There has been no change in iBoot firmware, which remains at 13822.1.2.
As Apple hasn’t been forthcoming about what else has changed, here’s my list:
Passwords app has gone from version 2.0 to 2.0.1, suggesting it has at least one significant bug fixed.
AppKit framework has had an increment in build number, also suggesting bug fixes.
CoreText framework likewise, with bug fixes for a higher build number, possibly related to the fixed vulnerability in font handling.
Security framework has a substantial increase in build number, implying bug fixes there as well.
I hope that you enjoyed Saturday’s Mac Riddles, episode 327. Here are my solutions to them.
1: Lost rocket platform as an app for your apps.
Click for a solution
Launchpad
Lost (it has been removed from Tahoe) rocket platform (a launchpad) as an app for your apps (what it was, an app for launching other apps).
2: Burning telegraph and lynx now disconnected.
Click for a solution
FireWire
Burning (fire) telegraph (wire) and lynx (Texas Instruments’ name for FireWire, IEEE 1394) now disconnected (support has been dropped from Tahoe, although oddly its kernel extensions are still present).
3: Happy Christmas 2017 is sad September 2025 for the most powerful Mac.
Click for a solution
iMac Pro
Happy Christmas 2017 (although announced the previous June, it shipped in December 2017) is sad September 2025 (it’s one of the T2 models dropped from Tahoe) for the most powerful Mac (when introduced, it was described as “the most powerful Mac ever made”, at least until the Mac Pro 2019).
By far the most common problem experienced with the Unified log isn’t its large number of entries, but a lack of entries. You go to check your Mac’s security using SilentKnight, or Skint runs its automatic daily check, and they can’t find any log entries recording XProtect Remediator scans. Since those are obtained by analysing the log for the previous 36 hours, when your Mac’s logs only go back 8-12 hours, entries for the last set of scans are likely to be missing. This article looks at why that happens, and how macOS maintains its log.
Traditional Unix-style logs are maintained according to their age. Every 24 hours, routine housekeeping procedures delete log files over a certain age, typically five days, in the process of rolling the log. Because the Unified log could over that five-day period have swallowed many GB of storage, its maintenance service logd deletes log records according to multiple criteria including the space they occupy, their age, and the type of entry. This is considerably more complex, and occurs in three phases, according to where the entry is stored.
Ephemeral entries
Log entries are initially written to memory, before logd writes most of them to permanent storage on disk.
The first substantial purging of entries thus occurs when logd decides which are ephemeral and won’t be written to disk. This can be seen by following the number of entries in a short period of high activity in the log, over time, and is shown in the chart below for a sample period of 3 seconds.
When fetched from the log within a minute of the entries being written, a total of 22,783 entries were recovered. Five minutes later there were only 82% (18,655) of those remaining. Attrition of entries then continued more slowly, leaving 80% (18,309) after 8 hours. Analysis suggests that over this period in which there were about 6,100 log entries per second written to disk, approximately 1,700 log entries per second were only kept in memory and never written to disk. That suggests about 22% were ephemeral, a proportion that’s likely to vary according to the origin and nature of log entries.
Persist entries
The great majority of log entries that survive to be written to permanent storage are kept in the tracev3 files in /private/var/db/diagnostics/Persist, where logd maintains them according to the total size of that folder, with a target of 520-530 MB. As each tracev3 file is up to 10.5 MB in size, that results in logd retaining about 50 files in that folder, although some are smaller than the maximum.
Two of my apps currently provide the datestamp of the start of the current collection of Persist log files as an indicator of the oldest log entry available from them: XProCheck, and Mints with its Logs button. This is a feature I intend adding shortly to LogUI.
However, not all log entries are stored in those Persist files. Looking back in time at total log entries available for a set ten minute period each day, you might see totals like:
1 day old 33,827 in 10 minutes
2 days old 98,534
3 days old 59,296
4 days old 10
5 days old 1
6 days old 40
7 days old 0
8 days old 358
9 days old 1.
Those for the last 3 days are almost all Persist entries, but older entries are those retained in tracev3 files in the Special folder.
Special entries
Fault and Error log entries are normally written to the tracev3 files in the Special folder, and may contain additional message content kept in the warren of folders and files inside /private/var/db/uuidtext. logd purges entries from Special files separately, and apparently on the basis of their type and content rather than size. As a result, the Special folder can contain many tracev3 files of sizes ranging from over 2 MB to just a few KB, with their size tending to reduce with age. Any log entries recovered from dates before the oldest Persist file thus must have come from Special files.
Although files stored in the uuidtext folder are small, there can be a great many of them, and total size of that folder can exceed 1 GB. Those too are maintained by logd.
Other folders and files
tracev3 files stored in the Signpost folder contain only Signpost log entries used for performance assessment, and are purged at a slower rate than Persist files, but not retained as long as Special files. The High Volume folder appears seldom if ever used. The timesync folder contains time synchronisation data, small files that normally cover the whole period of Special files.
The /private/var/db/diagnostics folder contains several other files, including the logs of logd and logd_helper, and most significantly pairs of statistical summaries written during log maintenance, named logdata.statistics.[n] where n is a number starting from 0, in both .txt and .jsonl (JSON) format.
Each time logd performs maintenance on a tracev3 file, or on associated uuidtext files, it records data about the files in the current logdata.statistics files, both as plain text and in JSON format. The most useful of these records occurs when a Persist tracev3 file is rotated from being the file into which new log entries are written, to being retained without further additions. That entry records:
the name of the tracev3 file;
the time of rotation, thus the time immediately following the last log entry to be made to that file;
the total number of log entries in that file, for example 42,365,476;
for the top 20 processes that wrote entries in that period, the number of entries, the percentage of total entries, and the path to the process, listed in order of number of entries.
For example, in that tracev3 file containing a total of 42,365,476 entries, the kernel might have written 13,095,296 entries, 30.9%, and be top of the list, while runningboardd might only have written 1,223,157 or 2.9%. These statistics can be valuable in drawing attention to periods when there were problems, and for discovering which entries are limiting the coverage of Persist files, making it impossible for apps to recover entries for XProtect Remediator scans, for example.
Statistics entries for memory rollovers can also be useful, as are those for Special file rotation, although the latter contain fewer entries than Persist files.
Extending the period of log coverage
Currently, there doesn’t appear to be any way to set logd‘s size allowance for Persist files. When the Unified log was first introduced, it wasn’t unusual for that setting to preserve full log records covering a period of up to 20 days. As more processes now write copious entries in the log, a Mac that’s left awake and running at all times may only retain the last 20 hours of Persist entries, or even less.
Macs that don’t need to be awake and running at all times can extend their log coverage by sleeping or being shut down, when of course no entries can be written. If that isn’t possible, you can write your own XML property lists to /Library/Preferences/Logging to limit the retention of specific categories of entry. However, experience shows that only achieves small extensions to time coverage. It’s also worth bearing in mind that disabling privacy protection in the log will increase the size taken by most log entries, so shortening time covered by the retained logs.
Perhaps the wisest and most effective way to extend the time coverage of logs is to discover the causes of excess entries and address those, although that’s inevitably the most difficult solution.
One little-used technique is to turn log records in backups into logarchives, enabling old log entries to be accessed days or even years after they have been written. As an example of what can be achieved, the log entries below were written eight years ago, on 26 September 2017, saved in a logarchive, and browsed using LogUI on 26 September 2025.
I will explain how to do this in a future article in this series.
Summary
Log maintenance is a sophisticated managed process that discards log messages for several reasons, most generally to keep total log file size within limits, rather than removing entries purely on the basis of age.
A fifth of log entries are likely to be ephemeral, and lost from the log within the first minutes after they’re written. If you want the fullest entries possible, obtain the log excerpt as soon as possible after its entries have been written.
Most retained log entries are written in Persist logs, where tracev3 files are removed by age to keep their total size to just over 500 MB. Those should preserve log entries for hours or days after they’re written.
Entries for Faults and Errors are stored in Special logs, where they’re kept for longer, sometimes for weeks.
logdata.statistics files provide detailed statistics for log files as they’re rotated, and can tell you which processes wrote most entries.
As logs aren’t written during sleep, or when shut down, allowing sleep and shutting down will extend the duration of log records.
Time Machine and other backups can be used to recover old logs as logarchives.
Last week’s outstanding news was the discovery of a potential treatment for Huntington’s disease, that killed Woodie Guthrie at the age of 55, a tragedy I learned of from his son Arlo’s movie Alice’s Restaurant (1969).
That treatment is so complex that even James Gallagher’s diagrammatic account doesn’t do it justice, but it provides a much clearer picture than some of the treatment offered for our Macs. Although in a different league, our novel treatment of the week is Device Recovery Assistant, as I showed here on Friday. It’s sufficiently new that Apple hasn’t quite gone firm on what to call it. Its sole account refers to it as Recovery Assistant, in accordance with the menu command used to open the app in Recovery mode. But when it’s running, it claims to be Device Recovery Assistant, which sounds like it might also be good for your iPhone or iPad, but isn’t. That’s a similar feature added to iOS and iPadOS 26, as explained here.
I’m still a little wary of magic healing tools in Recovery mode. The first is there even now, waiting to catch those who’ve taken AI a little too seriously, and think running repairHomePermissions might be a good idea. Whatever you do, please don’t try this one at home, as its effects can be devastating. I now only run it in a disposable virtual machine, as reversing its changes would be so time-consuming.
In Recovery mode, typing repairHomePermissions into Terminal launches a GUI app to ‘repair permissions’ in a selected Home folder in the Data volume. Far from repairing them, each time I have tried this it locks me out of every folder in my Home folder and wreaks havoc elsewhere. Yet somehow this historical remnant has been left behind in Recovery mode to catch the unwary.
(Device) Recovery Assistant doesn’t appear to do anything so disastrous, but Apple is completely opaque as to what it actually does. Even its description for macOS 26 beta testing used the same words, “Recovery Assistant is a new way to recover your device if it doesn’t start up normally. It can look for problems and attempt to resolve them if found.”
Just what “issues” can it discover, and how might it attempt to “resolve” them? One thing I can report is that it doesn’t attempt to repair the damage done by repairHomePermissions, and doesn’t see anything wrong with a user not having permissions to access their own folders. Maybe it isn’t that smart yet.
One small clue given by Apple is that it can leave your iCloud connection in need of a further recovery process run when back in normal user mode. Once again, though, information is lacking as to what that does, and why it might be needed.
Of course, if your Mac does have an appropriate problem that prevents it from starting up normally, and it instead puts itself into Recovery Assistant, you have little option but to give it a whirl and hope that it fixes whatever was causing the problem. But why might you want to run Recovery Assistant voluntarily from Recovery mode? Is this something worth doing for specific reasons, or is it just a universal panacea?
With Apple silicon Macs, we’re running out of panaceas. If you don’t know of a specific fix for a problem, most of the old tricks such as resetting NVRAM and SMC, repairing permissions, installing the Combo updater, and re-installing macOS have either become impossible or demonstrably futile. We’re currently left with the innocuous procedure of starting up in Safe mode, and quickly run out of ideas after that.
I’m not suggesting for a moment that Recovery Assistant is a placebo, but until we know more about it, neither can it be a new panacea.
If your Mac starts up in this new Recovery Assistant, or you use it manually in Recovery mode, please let us know what happened and whether it did resolve your problem.
One of the many fine details in macOS is its built-in support for a content caching service, both as server and client. This can be used for local distribution of macOS and other system updates, App Store updates, Apple media content such as Music and movie purchases, and iCloud content.
This appears to have originated as one of the new services added to Mac OS X Server 10.4 Tiger in April 2005, initially confined to a Software Update server. Apple’s online services were growing rapidly at the time, with the iTunes Store opening in 2003, and the first of its App Stores for iOS launching in 2008. Those were followed by the iCloud service in 2011. To cater for those, Apple added a separate Content Caching server by OS X Server 2 in 2012.
This shows the Software Update service in OS X Server 2 in 2012, with a list of some of the updates it had in its cache at the time.
At that time, a client Mac’s Software Update pane in System Preferences had to be pointed at the local server for that to be used instead of Apple’s. However, that didn’t work with App Store caching, for which the /Library/Preferences/com.apple.SoftwareUpdate.plist file had to be edited manually on each client to add a new property specifying the IP address of the local server.
macOS Server 5 in 2015 extended this further.
Features of the Software Update server then included the ability to limit the server’s bandwidth in its link back to Apple’s servers, and to control local network bandwidth used to transfer updates from the server to clients.
Amazingly, its original documentation is still available online here, and instructions for setting up clients remain here.
The Caching service worked with all content and apps provided by the Mac App and iTunes Stores, which of course included OS X updates, and is explained here. By this time, Macs and iOS devices connected to the local network would automatically find a server when it was running; there was minimal configuration for the server, and none for the clients.
When macOS 10.13 High Sierra was released in 2017, that brought update and content caching services to client Macs, and no longer required macOS Server, which was already in its terminal decline. These were configured in a new Content Caching feature added to the Sharing pane in System Preferences.
In essence, you designated one or more Macs as ‘parents’, to serve their cached content to ‘children’, which can themselves host caching services, to allow tiered setups. Initially, parents also needed to share their internet connection, required a minimum of iOS 10.3 for iOS devices, required a wired Ethernet connection to your router, and couldn’t sleep, so had to be run on mains power.
Although the content caching service has become quite widely used since, it’s never been as popular as it deserves. It remains remarkably simple to set up, as seen in these screenshots from 2020.
Clicking on the Options button let you set the cache location and its size.
Tabs were made available if you held the Option key before clicking the Options button, which then became Advanced Options. That let you set up clients, as well as other servers functioning as peers or parents, on more extensive networks.
These remain essentially the same today in Tahoe.
When Apple changed macOS updates in Big Sur, life became more complicated. When updating Apple silicon Macs, the first GB of macOS updates had to be downloaded direct from Apple’s servers, and it was only after that the remainder of the update could be obtained from a local caching server.
Apple has further extended the types of content that can be cached locally, to include
macOS updates normally obtained through Software Update or the command tool softwareupdate;
internet Recovery images from macOS 10.13.5 onwards when obtained in Recovery mode;
apps and their updates supplied through the Mac and iOS App Stores;
GarageBand downloadable content;
iCloud documents and data, including Photos libraries;
Apple Books;
downloadable components for Xcode.
Most recently Rosetta 2, screen savers, wallpaper and AI models have been added to the list. Apple’s reference document is here.
Advanced server configurations are catered for by the command tool AssetCacheManagerUtil which can also provide performance information, and there are two additional tools available, AssetCacheLocatorUtil and AssetCacheTetheratorUtil. On the server, performance information is most readily accessed in Activity Monitor’s Cache view, which provides summary statistics for the local cache.
This includes the total size of data served for the last hour, 24 hours, 7 days, and 30 days. To view those graphically, the time period for the charts at the foot can be changed by using it as a popup menu.
These show what happened on my content caching server during the macOS 11.4 update in 2021, for which almost 30 GB still had to be downloaded from Apple’s servers, while just over 20 GB was served from its cache.
Over the last 20 years or so, Software Update and Content Caching services have been remarkably reliable, but in June 2022 there was a period during which updates to XProtect and XProtect Remediator failed to install correctly when attempted through a content caching server. Apple never explained what the cause of that was, but it was eventually fixed and hasn’t recurred since.
Then, out of the blue, iOS and iPadOS 26 introduced a new feature to identify and test a connected caching server.
To access this, in Settings > Wi-Fi tap the ⓘ button on your current active network, scroll to the bottom and tap Content Caches. Tap the active cache to see full details, together with a download test. Don’t bother looking for an equivalent feature in macOS 26 Tahoe, though, as it isn’t available yet. How odd.
One of the features new to macOS 26 Tahoe that you won’t find in Apple’s list is an enhancement to Recovery mode, in Device Recovery Assistant (DRA). This article explains what it is and how to use it.
When you put your Mac into Recovery mode from Tahoe, you should notice that Apple has changed the disk icon there, to one intended to more closely resemble an SSD rather than a hard drive, although of course it’s still quaintly named Macintosh HD.
If your Mac (upgraded to Tahoe) has problems starting up correctly, it should now automatically restart and open DRA. You can also enter it manually by starting up in Recovery, passing through to Options, and using the Recovery Assistant command in the Utilities menu there, where its app menu identifies itself as Device Recovery Assistant. DRA requires an internet connection to function. If you’re asked to choose a connection, opt for a Wi-Fi network if possible.
Distinctive to DRA’s opening window is its first aid symbol ⊕. Click on the Continue button to move on.
The next window invites you to send data to Apple for diagnostic purposes. Make your choice as you move on.
If your startup Data volume is protected by FileVault, you’ll then be prompted for the password to unlock it. Once that has been provided, DRA attempts to perform a ‘recovery’.
At the end of that, you should see one of three outcomes:
no problems were found, and you can restart your Mac back into normal mode;
problems were found and repaired successfully, so you can restart your Mac back into normal mode;
problems were found but aren’t fully repaired.
When your Mac restarts, it may show a notification that you need to recover iCloud data. If so, open System Settings and you should see a new item in its sidebar to Recover iCloud Data.
If DRA doesn’t fix your Mac, you’ll almost certainly need to start up in Recovery and try to fix it there. You can also quit DRA to return to Recovery if you wish.
Apple’s support note doesn’t give any further information about what DRA does.
Following the introduction of the Unified Log, a surprising number of folk you would expect to use it have stopped. Some experienced developers and those providing advice in Apple Support Communities seemingly take pride in their lack of log literacy, claiming that the log is now impossible to use, and only accessible to Apple’s engineers. While it does present obstacles, pretending that the log isn’t a vital tool in diagnosis and understanding is burying your head in the sand. This article shows why.
Why the log?
The log provides support for several purposes. It’s widely used to investigate events such as bugs and unexpected behaviours, to establish their cause before working out how to fix them, in diagnosis and troubleshooting. It’s also used to discover how subsystems within macOS work, and what they do. Examples of those include LaunchServices, DAS-CTS scheduling and dispatching, and RunningBoard, all of which are nearly invisible to other methods, but write copious and explicit entries in the log. With its precise time recording and special Signpost log entries, it’s also invaluable for measuring performance, hence in optimising code.
Concentrating on the log’s use in diagnosis, log entries can be used to answer most of the key questions:
What happened?
When did it happen?
Who made it happen?
How did it happen?
Why did it happen?
What can I do about it?
Diagnose a mystery update
To illustrate those in practice, I’ll use an example that happens to be fresh in my mind, the silent updating of XProtect data last week. The only two clues available outside the log were the fact that XProtect had been updated, and that had occurred at 06:46:43 GMT on the morning of 17 September. There was no record of this event anywhere else that might have given any better information on how it had occurred.
Browsing the log from one second earlier confirmed what and when that had happened. I quickly discovered who made it happen when I found the log entry 2025-09-17 06:46:42.615072 com.apple.duetactivityscheduler REQUESTING START: 0:com.apple.security.syspolicy.xprotect-update:7874AD
revealing that update had been accomplished by a background check scheduled and dispatched by DAS-CTS, and performed by an update service com.apple.security.syspolicy.xprotect-update.
That in turn fired up XProtectUpdateService, which recorded that it promptly completed and activated the update: 2025-09-17 06:46:42.695517 com.apple.xprotect Connecting to XProtectUpdateService
2025-09-17 06:46:42.744182 com.apple.security.XProtectFramework.XProtectUpdateService XProtectUpdateService booting
2025-09-17 06:46:43.157255 com.apple.security.XProtectFramework.XProtectUpdateService Attempting to apply update: [private]
2025-09-17 06:46:43.191178 com.apple.security.XProtectFramework.XProtectUpdateService Update completed. Activated update [private]
XProtectUpdateService initiated a connection to the iCloud service now used to update XProtect in Sequoia and later, but log entries didn’t show the update being downloaded from that source. Instead, there was an error reported in the entry 2025-09-17 06:46:43.193159 com.apple.syspolicy.activities Finished Xprotect update in 496.4100122451782 ms: Error Domain=XProtectUpdateError Code=2 "Activated update LocalUpdate[5315]" UserInfo={NSLocalizedDescription=Activated update LocalUpdate[5315]}
Although the messages in many of these log entries are opaque, that entry makes it clear that XProtectUpdateService hadn’t downloaded the new version from iCloud, but had activated a local update, which we know from experience means the copy already downloaded to the traditional XProtect location had been used to install that update in its new location. That used to be available to the user through the xprotect update command, but is no longer. Thus, the only way that update could have been installed was the result of com.apple.security.syspolicy.xprotect-update being run routinely.
If we can’t intervene and force the update manually, the final piece of information we need is how often com.apple.security.syspolicy.xprotect-update is run, and that’s revealed into a later log entry: 2025-09-17 06:46:43.202474 com.apple.duetactivityscheduler Submitted: 0:com.apple.security.syspolicy.xprotect-update:58B6CE at priority 5 with interval 86400 (Wed Sep 17 22:58:51 2025 - Thu Sep 18 18:58:51 2025)
i.e. every 86,400 seconds, or 24 hours.
Procedure
How difficult was that to discover? Even with minimal prior knowledge, consummately easy, and it only took a couple of minutes.
My starting point was the timestamp reported for the update by xprotect version, of 06:46:43 GMT. I therefore set LogUI to display 5 seconds of log starting from one second before that. In the screenshots below, times are shown in BST, one hour in advance of GMT.
This returned a total of 7,174 log entries, far too many to browse. Knowing that I was looking for entries concerning XProtect, I then typed that into the search box and pressed Return, to display only those entries whose message contained the text xprotect.
That narrowed down the number of entries to just 65, starting with the scoring and dispatch of com.apple.security.syspolicy.xprotect-update by DAS-CTS at 42.608967 seconds, and containing all the entries quoted above. Just to be certain that I hadn’t missed anything relevant, I then cleared the search box and pressed Return to display all log entries again, scrolled down to 42.608967 seconds, and checked through those for the period to 43.19315 seconds, when the update had completed.
Of course, not all log investigations are as simple or successful, but many are just as straightforward. The main limitation isn’t the excessive number of log entries, but those from subsystems that make very few entries, as occurs in Spotlight indexing and search. There’s always a way to filter out unwanted entries, but you can’t magic in entries that were never made in the first place.
Conclusions
Browsing the log might appear daunting, even overwhelming or terrifying at first, but as you become more familiar with it you appreciate the rich information it can provide. Log literacy is one of the basic skills required for anyone who wants or needs to dig deeper into their Mac or Apple device. Without it diagnosis, research and performance measurement are like trying to paint a landscape while wearing a blindfold.
No sooner have we recovered from upgrading and updating macOS to 26.0/15.7/14.8 than Apple has released the next round of betas. This article looks at what’s in store for us over the coming year, as far as macOS is concerned.
With pandemics hopefully behind us, Apple’s planned OS updates have settled into a more regular pattern. Release dates when Sonoma was the current version of macOS (2023-24) were:
14.0 – 26 September
14.1 – 25 October
14.2 – 11 December
14.3 – 22 January
14.4 – 07 March
14.5 – 13 May
14.6 – 29 July
14.7 – 16 September.
Over the last year (2024-25), Sequoia has been almost identical, allowing for the small vagaries resulting from our calendar:
15.0 – 16 September
15.1 – 28 October
15.2 – 11 December
15.3 – 27 January
15.4 – 31 March
15.5 – 12 May
15.6 – 29 July
15.7 – 15 September.
If Tahoe follows the same pattern, you can expect releases to occur on the following dates:
26.0 – 15 September 2025
26.1 – 27 October 2025
26.2 – 15 December 2025
26.3 – 26 January 2026
26.4 – 30 March 2026
26.5 – 11 May 2026
26.6 – 27 July 2026
26.7 – 14 September 2026.
If you’d like a week’s notice of scheduled updates, watch Apple’s Developer Releases newsfeed at feed://developer.apple.com/news/releases/rss/releases.rss for Release Candidates. For minor versions, those are normally released about a week before the intended final release, so RCs seen on 20 or 21 October are likely to be followed by the public release on about 27 October.
Those can of course slip a few days or even a week if there are serious problems remaining with a release candidate, and some may be rescheduled to coincide with hardware announcements. These are also the ‘minor’ version updates, and Apple is likely to intercalate ‘patch’ releases to fix any serious bugs or urgent security vulnerabilities. Those almost never go through beta-testing or release candidacy.
For those staying with Sequoia or Sonoma for the time being, those security updates are most likely on the same dates as those for Tahoe.
Finally, a reminder for those whose Macs are still running macOS 13 Ventura: the final security update to 13.7.8 was released on 20 August this year, and Ventura is no longer officially supported by Apple. If your Mac can run Sonoma or later, and you want continuing security updates, then you’ll need to upgrade it to Sonoma 14.8 or later.
Apple has just released its weekly update to XProtect, bringing it to version 5316. As usual, it doesn’t release information about what security issues this update might add or change.
This version adds nine new detection signatures to its Yara file. These include five with novel names:
MACOS.SULFURSLAB.JS
MACOS.FOXTAIL.DEST
MACOS.FLAMINGOFEET.AR
MACOS.COMPLIANTPIRATE.DEFU
MACOS.TETRAGONE.FU
together with MACOS.ODYSSEY.SOBGO for the recently added Odyssey, and MACOS.SOMA.SEENB, MACOS.SOMA.SEENC and MACOS.SOMA.INGOBA for the prolific Amos/Soma family.
You can check whether this update has been installed by opening System Information via About This Mac, and selecting the Installations item under Software.
A full listing of security data file versions is given by SilentKnight and SystHist for El Capitan to Tahoe available from their product page. If your Mac hasn’t yet installed this update, you can force it using SilentKnight or at the command line.
If you want to install this as a named update in SilentKnight, its label is XProtectPlistConfigData_10_15-5316
Sequoia and Tahoe systems only
This update has already been released for Sequoia and Tahoe via iCloud. If you want to check it manually, use the Terminal command sudo xprotect check
then enter your admin password. If that returns version 5316 but your Mac still reports an older version is installed, you may be able to force the update using sudo xprotect update
The introduction of Mac OS X in 2000-01 brought conventional text-based logging to the Mac, with standard logs including system.log and console.log.
With the release of macOS 10.12 Sierra in 2016, those were almost completely replaced by the Unified Log, which has continued evolving since. Intended to provide a single efficient logging mechanism for user and kernel modes, its design goals are:
to maximise information collection with minimum observer effect;
as much logging on as much of the time as possible;
compression of log data for efficient use of space;
a managed log message lifecycle;
designed-in privacy protection;
to be common across all Apple’s operating systems;
all legacy APIs (NSLog, asl_log_message, syslog, etc.) to be redirected into the single log;
to support debugging, but not system administration or audit.
To achieve this, log entries are written using the OSLog API (or Logger from Swift), handled by the logd daemon and compressed into a buffer. From there entries are either retained in memory if intended to be ephemeral, or written out to a file. Log entries are only made from the start of kernel boot; earlier phases of the boot process instead save breadcrumbs that are largely inaccessible and unintelligible.
Performance of writing log entries is excellent, with a single process able to write sequential entries every 400 ns from a code loop, a rate of 2.5 million entries per second, although that rate is unlikely to be sustainable for long.
Log storage
There are two main groups of files that store log entries: those kept in /var/db/diagnostics/Persist/ in the form of tracev3 files containing regular log entries, and further tracev3 files in /var/db/diagnostics/Special/ containing additional shorter-life entries. Additional and lengthier log data can instead be stored in files named by UUID in /var/db/uuidtext/, and there’s also support for special Signpost entries intended for performance measurement, and scope for high-volume collection.
tracev3 files use a proprietary compressed binary format that remains undocumented to this day, but has been largely reversed. Apple’s APIs don’t give direct access to their contents, only through closed-source utilities such as the log command tool and programmatically through the OSLog API. Where users want a more portable format, Apple recommends conversion to a logarchive package, although that’s also undocumented and only directly accessible using log, the Console app and some third-party utilities. Logarchives still store all log entries in tracev3 files.
Collection and retention of entries from different subsystems is configured in logging profiles, XML property lists stored in /System/Library/Preferences/Logging (read-only, in the System volume) and /Library/Preferences/Logging, which the user controls. You can create your own custom profiles, or modify them on the fly using the log command.
The logd service maintains tracev3 files and their ancillaries, weeding them to remove time-expired entries. It does so to constrain the total size of log files in the system, rather than rolling them to retain all entries for a specified period. Most ephemeral entries are weeded within 5 minutes of being written to the log, leaving persistent entries to remain for the following days, depending on the volume of new entries being written. For example, in a 3 second period of collection, when all entries were obtained within a minute of being written, 22,783 entries were found. Five minutes after they had been written, only 82% of those remained, and over 8 hours later that had fallen to 80%, or 18,309.
Log content
In contrast to traditional text-based logs, entries in the macOS log contain structured data in set fields, such as the datestamp, subsystem and log message. The number of fields available from the log command has risen from 16 to over 25, but entries are constrained in which fields are available, according to their type. Currently there are four types, Regular, Activity, Boundary and Signpost.
Some log entries, notably those written to /var/db/uuidtext/, can have very long message fields, extending to dozens of lines. Among the most verbose is the com.apple.runningboard subsystem, which not infrequently writes the whole of its records for an app into the message field of a single log entry.
Privacy
Privacy protection censors content of log entries when they’re written, replacing sections of the message field with <private> in accordance with the formatting string for that message. This protection can be disabled, but as entries are censored when they’re written, that only affects those written after censorship has been removed, and can’t be applied retrospectively.
One significant change in macOS 26 Tahoe is that the message contents of all log entries written using the old NSLog interface are replaced with <private>, rendering them essentially useless. Since macOS 10.12.4, all access to log entries has required admin privileges.
Access
macOS provides users with two means of accessing entries in the log: the log command tool, and Console app. In common use, log generates text output, so losing the original data fields, one of the major advantages of the Unified Log. Console offers two methods of access: a live stream of entries, or browsing past entries in a saved logarchive.
I have four main tools that provide extensive log access:
LogUI, using the OSLog API and displaying entries as formatted SwiftUI Lists;
Mints, offering special-purpose browsers for Time Machine, APFS, and other domains;
Ulbow, using the log tool and displaying entries as formatted Rich Text using AppKit;
Consolation, using the log tool and displaying entries as formatted Rich Text using AppKit.
This article lists the firmware versions of Macs that have been successfully upgraded to run macOS 26.0 Tahoe.
Apple doesn’t provide an official list of the current firmware versions which should be installed on each model of Mac. Intel models with T2 chips consist of two parts, the second covering iBridge in the T2. Apple silicon Macs just give an iBoot version.
Macs still running older versions of macOS are covered by information at:
The current EFI version is 2092.0.0.0.0 and iBridge is 23.16.10350.0.0,0.
Apple Studio Display
The current version remains 17.0 (build 21A329).
How to check your Mac’s firmware version
The simplest way is to run my free tool SilentKnight, available from its product page.
Alternatively, use the About This Mac command at the top of the Apple menu; hold the Option key and click on the System Information command. In the Hardware Overview listing, this is given as the Boot ROM Version or System Firmware Version.
What to do if your Mac’s firmware is different from that shown
If the version is higher than that given here, it indicates that Mac has installed a more recent version of macOS, which has installed a later version of the firmware. This is almost invariably the result of installing a beta-release of the next version of macOS. This occurs even when the newer macOS is installed to an external disk.
If the installed version of firmware has a version lower than that shown, you can try installing macOS again to see if that updates the firmware correctly. If it still fails to update, you should contact Apple Support.
Firmware updaters are now only distributed as part of macOS updates and upgrades: Apple doesn’t provide them separately.
All T2 and Apple silicon models automatically check the integrity of their firmware in the early part of the boot process anyway. If any errors are found then, the Mac should be put into DFU mode and firmware restored from the current IPSW image file. In Sonoma and later this can be performed in the Finder, and no longer requires Apple Configurator 2. Full instructions are provided in this article. If you don’t have a second Mac or don’t feel that you can perform this yourself, it should be easy to arrange with an Apple store or authorised service provider.
It has been barely a year since XProtect changed from stalwart to bogeyman. Over the course of dozens of updates through to macOS Sonoma, if there was one security data update you could rely on, it was XProtectPlistConfigData containing the many rules for XProtect. They guarded us through the dangerous days of Flash Player, the perils of ransomware, and a succession of stealers.
Then in Sequoia that changed, and XProtect’s data became stored in two locations, each with its own update method. The traditional location in CoreServices continued to be updated through softwareupdated, while the copy in the new location in /var/protected/xprotect has been updated by XProtectUpdateService over a connection to iCloud.
With both locations in play, XProtect updates have become more complicated. Some updates only came for one location, such as versions 5273 and 5275 that were released only to Sequoia’s new location. To help us manage XProtect in its new location, Apple provided a command tool, xprotect. That can check which version is available via iCloud, and update that when the local copy was no longer the latest.
One valuable feature was that it could also use a copy in the traditional location to update the new location, in the event that version was more recent than that available from iCloud, but most recently that has been disabled. Now, if a Mac running Sequoia or Tahoe has successfully updated its traditional location but not the copy in the new location, the user is unable to do anything to rectify that, and has to wait until that update is made available from iCloud. Sometimes both are provided at the same time, but it’s also common for iCloud to lag the traditional version by an hour or more, sometimes even longer.
Last week, with the update to XProtect 5315, the day after many of us were preoccupied with macOS updates, something even stranger happened. At around 18:00 GMT on 16 September, softwareupdated became able to download and install that new version into its traditional location, enabling macOS versions up to Sonoma to update successfully. But no such update was made available via iCloud for Sequoia or newly upgraded Tahoe systems, not for another 24 hours. Over that period attempts to obtain or convert the update using xprotect update were unsuccessful.
However, some hours after the traditional update was installed by those who had upgraded to Tahoe, XProtect’s new location was silently updated to 5315. Its version number had gone bump in the night. But if the xprotect command tool couldn’t accomplish that for the user, how could macOS? Were these silent updates coming by telepathy or radio waves?
Although there was no record in any of the usual places, such as Installations in System Information, or even found by my app SystHist, the xprotect version command disclosed that my Mac mini had updated XProtect’s new location at 06:46 GMT on the morning of 17 September, enabling me to hunt that event down in the log.
That update had been accomplished by a background check scheduled and dispatched by DAS-CTS (I have corrected times here to GMT): 2025-09-17 06:46:42.615072 com.apple.duetactivityscheduler REQUESTING START: 0:com.apple.security.syspolicy.xprotect-update:7874AD
This in turn fired up XProtectUpdateService 2025-09-17 06:46:42.695517 com.apple.xprotect Connecting to XProtectUpdateService
2025-09-17 06:46:42.744182 com.apple.security.XProtectFramework.XProtectUpdateService XProtectUpdateService booting
2025-09-17 06:46:43.157255 com.apple.security.XProtectFramework.XProtectUpdateService Attempting to apply update: [private]
2025-09-17 06:46:43.191178 com.apple.security.XProtectFramework.XProtectUpdateService Update completed. Activated update [private]
So the XProtect update had been completed and activated at 06:46 that morning. But how, given that iCloud was still only offering the old version? 2025-09-17 06:46:43.193159 com.apple.syspolicy.activities Finished Xprotect update in 496.4100122451782 ms: Error Domain=XProtectUpdateError Code=2 "Activated update LocalUpdate[5315]" UserInfo={NSLocalizedDescription=Activated update LocalUpdate[5315]}
2025-09-17 06:46:43.193285 com.apple.syspolicy Sent CloudTelemetry event: Xprotectupdateresult
“Activated update LocalUpdate” can only mean one thing, that XProtectUpdateService did what xprotect update used to do, and used the copy of XProtect 5315 in the traditional location to update the new location, taking just under half a second. In addition, com.apple.syspolicy had sent news of that event to Apple via iCloud.
That didn’t work for my old iMac Pro, still running Sequoia, though, which had to wait for the iCloud version of XProtect data to be updated, and wasn’t using version 5315 until 20:17 GMT on 17 September, over 26 hours after its initial release.
Prior to Sequoia, all supported and many unsupported versions of macOS got the same XProtect updates, available immediately they were released through Apple’s software update servers. Just over a year later,
Macs running Sonoma and unsupported versions of macOS could be updated as soon as the softwareupdated update became available, in the traditional way;
Macs running Sequoia could only be updated 24 hours later, when the iCloud update was made available;
Macs running Tahoe could have been updated at any time after the traditional update had been installed, until the update was finally made available through iCloud.
I’m so looking forward to the time when I don’t need to use SilentKnight, the xprotect command and my log browser LogUI to track XProtect updates, and when those become timely again.
The original 128K Mac from 1984 came with a single Motorola 68000 processor running at 8 MHz that could only run one app at a time. Yet today’s Macs come with multiple CPU cores that can comfortably run several substantial apps simultaneously, while running a Time Machine backup and other tasks in the background. This brief history outlines the journey between them.
A processor with a single core and no support for multi-tasking runs one sequence of instructions at a time. When those call for an operating system function to be performed, the running app is interrupted to hand control over to the system, and once that has completed, control is passed back to the app. That’s what the first Macs did until Andy Hertzfeld wrote Switcher, released by Apple in April 1985. This allowed the user to switch between running more than one app, but was still limited to running just one of them at a time.
Multitasking
Over the next couple of years, some third-party utilities were produced to go further than Switcher, but it wasn’t until 1987 that MultiFinder replaced Switcher, and was integrated into System 7 in 1991. Developed by Erich Ringewald and Phil Goldman, this brought cooperative multitasking, which was to become the mainstay of classic Mac OS.
In computers with a single processor core, multitasking is a way of cheating to give the impression that the processor is doing several things at once, when in fact all it’s doing is switching rapidly between two or more different programs. There are two fundamental models for doing that:
cooperative multitasking, in which individual tasks yield to give others processing time;
preemptive multitasking, in which a scheduler switches between tasks at regular intervals.
When a processor switches from one task to the next, the current task state must be saved so it can be resumed later. Once that’s complete, the next task is loaded to complete the context switch. That incurs overhead, both in terms of processing and in memory storage, which are less when switching between lightweight tasks. Different strategies have been adopted to determine the optimum size of tasks and overhead imposed by context switching, and terminology differs between them, variously using words such as processes, threads and even fibres, which can prove thoroughly confusing.
Classic Mac OS thus has a Process Manager that launches apps in cooperative multitasking. This works well much of the time, but lets badly behaved tasks hog the processor and block other tasks from getting their fair share. It’s greatly aided by the main event loop at the heart of Mac apps that waits for control input to direct the app to perform work for the user. But when an app charges off to spend many seconds tackling a demanding task without polling its main event loop, that app could lock the user out for what seems like an age.
In February 1988 Apple released the first Unix for Macintosh, A/UX, which came with preemptive multitasking. That was added to Mac OS in 1996 in System 7.5.3, in Multiprocessing Services, and further enhanced in Mac OS 8.6 three years later. Cooperative multitasking was also supported by the Thread Manager.
Threads
In 2000 Apple’s hardware and software changed radically. Its first Macs with dual processors (apart from the Power Mac 9600/200MP that was available briefly in 1997) came in PowerPC 7400 (G4) chips in Power Mac G4 desktop systems, and Mac OS X brought several types of thread that could be used to manage processing on multiple processors or CPU cores, together with preemptive multitasking. Thread types include low-level Mach threads, higher-level POSIX threads or Pthreads that replaced Multiprocessing Services, Java Threads, Cocoa’s NSThreads, and cooperatively scheduled threads using the Carbon Thread Manager. The following diagram summarises Apple’s current terminology.
In most cases, we’re considering applications with a GUI, normally run from a bundle structure. These can in turn run their own code, such as privileged helper apps used to perform work that requires elevated privileges. In recent years, there has been a proliferation of additional executable code associated with many apps.
When that app is run, there’s a single runtime instance created from its single executable code, and given its own virtual memory and access to system resources that it needs. This is a process, and listed as such in Activity Monitor, for example.
Each process has a main thread, a single flow of code execution, and may create additional threads, perhaps to run in the background. Threads don’t get their own virtual memory, but share that allocated to the process, although they have their own stack. On Apple silicon Macs they’re easy to tell apart as they can only run on a single core, although they may be moved between cores, sometimes rapidly.
Within each thread are individual tasks, each a quantity of work to be performed. These can be brief sections of code and are more interdependent than threads. They’re often divided into synchronous and asynchronous tasks, depending on whether they need to be run as part of a strict sequence.
In 2005 the Power Mac G5 was the first Mac to use dual-core PowerPC G5 processors, then the iMac 17-inch of the following year used Apple’s first Intel Core Duo processor with two cores.
Grand Central Dispatch
In 2009 Mac OS X 10.6 Snow Leopard introduced a new dispatcher, named Grand Central Dispatch (GCD) after Grand Central Terminal in New York City, and that was enhanced in macOS Sierra a decade later. More recently it has been referred to simply as Dispatch.
At its heart, GCD is a dispatcher managing queues of tasks, activating those that need most to be run, and leaving the less pressing to wait a bit longer. It has its own queues, as well as those assembled by apps. Some are run as simple queues with a first in first out rule, others using sophisticated heuristics to determine relative priorities. There’s a detailed account of GCD internals in Jonathan Levin’s book *OS Internals volume 1, and Apple’s current developer documentation is here.
GCD was introduced for Macs with multiple identical cores, to support their symmetric multiprocessing (SMP), and with the release of the first Apple silicon Macs in November 2020 it has managed queues of threads to be dispatched for execution on two CPU core types, Performance and Efficiency. Core allocation is now managed according to the Quality of Service (QoS) assigned to each thread. When used on SMP processors with no contention for core availability, QoS has limited effects on thread performance, but performance on P and E cores may differ by a factor of 10.
Over the last 41 years, macOS has gained thorough support for getting the best performance from multiple tasks, threads, and processes in chips that contain up to 32 CPU cores of two types – a far cry from that single 68000 processor.