internal_mount_ops.c [plain text]
#include "internal_mount_ops.h"
#ifdef MOUNT_INTERNAL
#if (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
#include <APFS/APFS.h>
#include <sys/syslimits.h>
#include <sys/param.h>
#define DATA_PARTITION_MOUNT_POINT "/private/var"
#define DEFAULT_MOUNT_OPTS "rw,nosuid,nodev"
#define LOG_PARTITION_MOUNT_POINT DATA_PARTITION_MOUNT_POINT "/logs"
static char log_volume_dev_node[NAME_MAX];
static struct fstab log_volume;
#define SCRATCH_PARTITION_MOUNT_POINT DATA_PARTITION_MOUNT_POINT "/internal"
static char scratch_volume_dev_node[NAME_MAX];
static struct fstab scratch_volume;
static bool
mount_point_exists(const char *mount_point, uint16_t vol_role)
{
char mount_path[MAXPATHLEN];
if (realpath(mount_point, mount_path) == NULL) {
fprintf(stderr, "WARNING volume role (0x%x) will not be mounted! Cant resolve mount point: %s - %s\n",
vol_role, mount_point, mount_path);
return false;
}
return true;
}
static CFMutableArrayRef
get_volume_with_role(const char *container, uint16_t role)
{
int err = 0;
CFMutableArrayRef matches = NULL;
err = APFSVolumeRoleFind(container, role, &matches);
if (err) {
if (err_get_code(err) != ENOATTR) {
fprintf(stderr, "failed to lookup volume role 0x%x - %s\n",
role, strerror(err_get_code(err)));
}
return NULL;
} else if (CFArrayGetCount(matches) > 1) {
CFRelease(matches);
fprintf(stderr, "multiple volumes with role 0x%x\n", role);
return NULL;
}
return matches;
}
struct fstab *
get_log_volume(const char *container)
{
CFStringRef log_volume_dev;
CFMutableArrayRef matches = NULL;
matches = get_volume_with_role(container, APFS_VOL_ROLE_INSTALLER);
if (!matches) {
return NULL;
}
log_volume_dev = (CFStringRef)CFArrayGetValueAtIndex(matches, 0);
CFStringGetCString(log_volume_dev, log_volume_dev_node, NAME_MAX, kCFStringEncodingUTF8);
CFRelease(matches);
log_volume.fs_spec = log_volume_dev_node;
log_volume.fs_file = LOG_PARTITION_MOUNT_POINT;
log_volume.fs_type = FSTAB_RW;
log_volume.fs_vfstype = EDTVolumeFSType;
log_volume.fs_mntops = DEFAULT_MOUNT_OPTS;
log_volume.fs_freq = 0;
log_volume.fs_passno = 2;
if (mount_point_exists(LOG_PARTITION_MOUNT_POINT ,APFS_VOL_ROLE_INSTALLER))
return &log_volume;
else
return NULL;
}
struct fstab *
get_scratch_volume(const char *container)
{
CFStringRef scratch_volume_dev;
CFMutableArrayRef matches = NULL;
matches = get_volume_with_role(container, APFS_VOL_ROLE_INTERNAL);
if (!matches) {
return NULL;
}
scratch_volume_dev = (CFStringRef)CFArrayGetValueAtIndex(matches, 0);
CFStringGetCString(scratch_volume_dev, scratch_volume_dev_node, NAME_MAX, kCFStringEncodingUTF8);
CFRelease(matches);
scratch_volume.fs_spec = scratch_volume_dev_node;
scratch_volume.fs_file = SCRATCH_PARTITION_MOUNT_POINT;
scratch_volume.fs_type = FSTAB_RW;
scratch_volume.fs_vfstype = EDTVolumeFSType;
scratch_volume.fs_mntops = DEFAULT_MOUNT_OPTS;
scratch_volume.fs_freq = 0;
scratch_volume.fs_passno = 2;
if (mount_point_exists(SCRATCH_PARTITION_MOUNT_POINT ,APFS_VOL_ROLE_INTERNAL))
return &scratch_volume;
else
return NULL;
}
#endif
#endif