What exactly is chflags opaque, nodump?

Short answer: nothing particularly relevant on modern macOS.

Long answer: both of these flags relate to Unix features that you probably never use.

  • The opaque flag relates to "union mounts" -- mounting one filesystem over another, so that you can see the files and folders of both mixed together in (what appears to be) a single folder tree. Setting the opaque flag on a folder makes it... well, opaque, so if there's also a folder by the same name in the other filesystem, you won't see its contents merged in. Union mounts don't seem to work at all in recent versions of macOS, making this flag completely irrelevant.

  • The nodump flag tells the dump program (a backup utility) that the item doesn't need to be backed up. macOS doesn't even include the dump program (though you could probably add it through homebrew or something). You can tell the tar program to skip nodump files with its --nodump options, and I suppose other backup programs could also take this as a "don't back up" flag, but I don't know of any that do this. So again this is pretty irrelevant on macOS.


The nodump file flag can still be used by macOS. Apparently, the opaque file flag has never been used by macOS or OS X since at least Snow Leopard.


Here is an example of the use of the nodump file flag.

Below is the output from the command ls -lO hi.txt bye.txt. Note bye.txt has the nodump flag.

-rw-r--r--  1 davidanderson  staff  nodump 8 Mar 20 12:13 bye.txt
-rw-r--r--  1 davidanderson  staff  -      9 Mar 20 12:13 hi.txt

Next, the command tar --nodump -cf mytarball hi.txt bye.txt is executed to create the archive file mytarball. Afterwards, if the command tar -tvf mytarball is entered, the contents of the archive will be printed. Below is the output.

-rw-r--r--  0 davidanderson staff       9 Mar 20 12:13 hi.txt

Note that the file bye.txt was omitted from the archive because of the nodump flag.


Here is an example of the use of the opaque file flag.

While I can provide an example, the example will not work with macOS. Instead the example will use the current version of FreeBSD.

The macOS operating system is derived from parts of BSD Unix. BSD implements two forms of unioning: the -o union option to the mount command and the mount_unionfs command. When testing various versions of OS X and macOS, I found Snow Leopard does implement the -o union option, while High Sierra and Big Sur ignore this option. All three versions do not include the mount_unionfs command. AFAIK, the opaque file flag is only used by this latter form of unioning. So to provide an example, I will turn to FreeBSD, which does include the mount_unionfs command.

The basic idea here is to allow modifications to be made to a read-only mount. In the following example, I will remove a directory containing a file, then create a new empty directory with the same name.

In this example, I have a DVD with two directories named dog and cat. The directory dog contains the file poodle and the directory cat contains the file siamese. After putting the DVD in the optical drive, I entered the following commands as root user to mount the DVD and view the contents. The current directory is the root user's home directory /root.

mkdir pets
mount -t cd9660 /dev/cd0 pets
ls -lRFo pets

Below is the sample output.

To allow modifications, I created and mounted the empty directory changes using the -t unionfs option. Also, I printed out the mounts to pets. The mount command actually uses the mount_unionfs command to perform the mount.

mkdir changes
mount -t unionfs changes pets
mount | grep pets

Below is sample output.

Next, I used the commands below remove the directory named dog and confirm the change.

rm -fr pets/dog
ls -lRFo pets
ls -lRFo changes

Below is a sample output. Note that the directory dog no longer appears in directory pets. Also, the directory changes appears to have only gained the empty directory cat.

However, a whiteout named dog was added to the directory changes and thus the directory pets. To see the whiteout, the -W option needs to be added to the ls command, as shown below.

ls -lRFoW pets
ls -lRFoW changes

Below is a sample output.

The whiteout dog masks the directory dog on the DVD. Next, I used the commands below to create a new empty directory named dog and show the changes.

mkdir pets/dog
ls -lRFoW pets
ls -lRFoW changes

Below is a sample output.

Here, the whiteout dog was replaced by the directory dog with the opaque file flag set. This directory masks the directory dog on the DVD. To demonstrate the need for the opaque file flag, I used the commands shown below to remove the opaque file flag and show the results.

chflags noopaque changes/dog
ls -lRFoW pets
ls -lRFoW changes

Below is a sample output.

Without the opaque file flag, the file poodle incorrectly appears in the pets/dog directory.

The final commands below just undo all the mounts and changes made in this example.

umount pets
umount pets
ls -lRFoW pets
ls -lRFoW changes
rmdir pets
rm -fr changes

Below is a sample output.


References

Unioning file systems: Architecture, features, and design choices
Union file systems: Implementations, part I
Wikipedia: macOS
Unionfs: document reasons for opaque directories
FreeBSD ls command
FreeBSD mount command
FreeBSD mount_unionfs command

Note: FreeBSD was executed by first downloading the virtual machine ready file named FreeBSD-12.2-RELEASE-amd64.vmdk.xz. This file was used to create a VirtualBox virtual machine with a 2013 iMac as host. This file should also be compatible with VMware Fusion Player.


They are POSIX standard flags defined in stat.h and any unix program can read them with the stat call and the system writes and removes them in a standard pattern for compatibility with the dump and unionfs functionality.

/*
 * Definitions of flags stored in file flags word.
 *
 * Super-user and owner changeable flags.
 */
#define UF_SETTABLE 0x0000ffff  /* mask of owner changeable flags */
#define UF_NODUMP   0x00000001  /* do not dump file */
#define UF_IMMUTABLE    0x00000002  /* file may not be changed */
#define UF_APPEND   0x00000004  /* writes to file may only append */
#define UF_OPAQUE   0x00000008  /* directory is opaque wrt. union */
/*