Dev:Mounting APFS
From The Apple Wiki
More actions
APFS is a file system developed and deployed by Apple Inc..
Mounting APFS requires pointer to data specific to apfs to be passed to the fourth argument of mount(2).
The struct for this data is supposedly available in apfs/apfs_mount.h, but this header is not public.
Reverse Engineered Header
#include <sys/types.h>
/* APFS mode modes */
#define APFS_MOUNT_DEFAULT_SNAPSHOT 0x0 /* mount the default snapshot */
#define APFS_MOUNT_LIVEFS 0x1 /* mount live fs */
#define APFS_MOUNT_CUSTOM_SNAPSHOT 0x2 /* mount custom snapshot in args->snapshot */
#define APFS_MOUNT_AUTHENTICATED_SNAPSHOT 0x3 /* authenticated snapshot mount with im4p and im4m */
#define APFS_MOUNT_FUSION_T1_T2 0x4 /* Fusion mount with tier 1 & 2, set by mount_apfs when -C is used (Conversion mount) */
#define APFS_MOUNT_FUSION_T1_ONLY 0x5 /* Fusion mount with tier 1 only, set by mount_apfs when -c is used */
#define APFS_MOUNT_MODE_SIX 0x6 /* ??????? */
#define APFS_MOUNT_FOR_INVERT 0x7 /* ??? mount for invert */
#define APFS_MOUNT_IMG4 0x8 /* authenticated mount with im4p and im4m */
/* End APFS mount modes*/
#define APFS_MOUNT_IMG4_MAXSZ 0x100000
#define APFS_AUTH_ENV_GENERIC 4
#define APFS_AUTH_ENV_SUPPLEMENTAL 5
#define APFS_AUTH_ENV_PDI_NONCE 6
#define APFS_CRYPTEX_TYPE_GENERIC 0x67746776 /* vgtg */
#define APFS_CRYPTEX_TYPE_BRAIN 0x73796162 /* bays */
#define APFS_FLAGS_SMALL_N_OPT 0x400000000 /* mount_apfs -n */
#define APFS_FLAGS_LARGE_R_OPT 0x200000000 /* mount_apfs -R */
#define APFS_FLAGS_LARGET_S_OPT 0x800000000 /* mount_apfs -S */
/* Fourth argument to mount(2) when mounting apfs */
struct apfs_mount_args {
#ifndef KERNEL
char* fspec; /* path to device to mount from */
#endif
uint64_t apfs_flags; /* The standard mount flags, OR'd with apfs-specific flags (APFS_FLAGS_* above) */
uint32_t mount_mode; /* APFS_MOUNT_* */
uint32_t pad1; /* padding */
uint32_t unk_flags; /* yet another type some sort of flags (bitfield), possibly volume role related */
union {
char snapshot[256]; /* snapshot name */
struct {
char tier1_dev[128]; /* Tier 1 device (Fusion mount) */
char tier2_dev[128]; /* Tier 2 device (Fusion mount) */
};
};
void* im4p_ptr;
uint32_t im4p_size;
uint32_t pad2; /* padding */
void* im4m_ptr;
uint32_t im4m_size;
uint32_t pad3; /* padding */
uint32_t cryptex_type; /* APFS_CRYPTEX_TYPE_* */
int32_t auth_mode; /* APFS_AUTH_ENV_* */
uid_t uid;
gid_t gid;
}__attribute__((packed, aligned(4)));
typedef struct apfs_mount_args apfs_mount_args_t;
Mounting Live FS
To mount /dev/disk0s1s1 onto / in read-write mode:
apfs_mount_args_t args = { "/dev/disk0s1s1", 0, APFS_MOUNT_LIVEFS };
mount("apfs", "/", 0, &args);
To mount /dev/disk0s1s1 onto / in read-only mode:
apfs_mount_args_t args = { "/dev/disk0s1s1", MNT_RDONLY, APFS_MOUNT_LIVEFS };
mount("apfs", "/", MNT_RDONLY, &args);
- Setting
args->apfs_flagsis not required for the mount to go through (0 works), butmount_apfsdoes it.
Mounting snapshot
To mount the default snapshot com.apple.os.update-${boot_manifest_hash} of /dev/disk0s1s1 onto /:
apfs_mount_args_t args = { "/dev/disk0s1s1", MNT_RDONLY, APFS_MOUNT_DEFAULT_SNAPSHOT };
mount("apfs", "/", MNT_RDONLY, &args); /* remember the snapshots must be read-only */
To mount a custom snapshot named orig-fs:
apfs_mount_args_t args = { "/dev/disk0s1s1", MNT_RDONLY, APFS_MOUNT_CUSTOM_SNAPSHOT, 0, 0, "orig-fs" };
mount("apfs", "/", MNT_RDONLY, &args); /* remember the snapshots must be read-only */
Update mount
To remount an APFS volume /dev/disk0s1s3 mounted at /private/preboot as read-write:
apfs_mount_args_t args = { "/dev/disk0s1s3", MNT_UPDATE, APFS_MOUNT_LIVEFS };
mount("apfs", "/", MNT_UPDATE, &args);
args->fspeccan actually be arbitrary values, which allows for spoofing source volumes.