Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 38 additions & 4 deletions macosvm/VMInstance.m
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,14 @@ - (void) addFileStorage: (NSString*) path type: (NSString*) type options: (NSArr
@"file" : path
};
NSMutableDictionary *root = [NSMutableDictionary dictionaryWithDictionary:initial];
for (NSString *option in options)
[root setValue: @(YES) forKey: option];
for (NSString *option in options) {
NSRange eq = [option rangeOfString: @"="];
if (eq.location == NSNotFound) /* boolean flag, e.g. "readOnly", "keep" */
[root setValue: @(YES) forKey: option];
else /* key=value, e.g. "sync=none", "cache=cached" */
[root setValue: [option substringFromIndex: eq.location + 1]
forKey: [option substringToIndex: eq.location]];
}
storage = storage ? [storage arrayByAddingObject:root] : @[root];
}

Expand Down Expand Up @@ -712,8 +718,36 @@ that a previously created socket (especially not a link) */
if ([tmp isEqualToString:@"disk"] || [tmp isEqualToString:@"usb"]) {
NSError *err = nil;
NSURL *imageURL = url ? url : [NSURL fileURLWithPath:path];
NSLog(@" + %@ image %@ (%@)", tmp, imageURL, ro ? @"read-only" : @"read-write");
VZDiskImageStorageDeviceAttachment *a = [[VZDiskImageStorageDeviceAttachment alloc] initWithURL:imageURL readOnly:ro error:&err];
NSString *syncStr = d[@"sync"]; /* full (default) | fsync | none */
NSString *cacheStr = d[@"cache"]; /* auto (default) | cached | uncached */
NSLog(@" + %@ image %@ (%@%@%@)", tmp, imageURL, ro ? @"read-only" : @"read-write",
syncStr ? [@", sync=" stringByAppendingString: syncStr] : @"",
cacheStr ? [@", cache=" stringByAppendingString: cacheStr] : @"");
VZDiskImageStorageDeviceAttachment *a = nil;
/* Opt-in: only take the macOS 12+ path when sync= or cache= was requested.
With neither set, behaviour is identical to before (full sync, automatic caching). */
#if (TARGET_OS_OSX && __MAC_OS_X_VERSION_MAX_ALLOWED >= 120000)
if (syncStr || cacheStr) if (@available(macOS 12.0, *)) {
VZDiskImageSynchronizationMode syncMode = VZDiskImageSynchronizationModeFull;
if ([syncStr isEqualToString:@"none"]) syncMode = VZDiskImageSynchronizationModeNone;
else if ([syncStr isEqualToString:@"fsync"]) syncMode = VZDiskImageSynchronizationModeFsync;
else if (syncStr && ![syncStr isEqualToString:@"full"])
@throw [NSException exceptionWithName:@"VMConfigDiskStorageError"
reason:[@"invalid disk sync mode (want full|fsync|none): " stringByAppendingString:syncStr] userInfo:nil];
VZDiskImageCachingMode cacheMode = VZDiskImageCachingModeAutomatic;
if ([cacheStr isEqualToString:@"cached"]) cacheMode = VZDiskImageCachingModeCached;
else if ([cacheStr isEqualToString:@"uncached"]) cacheMode = VZDiskImageCachingModeUncached;
else if (cacheStr && ![cacheStr isEqualToString:@"auto"] && ![cacheStr isEqualToString:@"automatic"])
@throw [NSException exceptionWithName:@"VMConfigDiskStorageError"
reason:[@"invalid disk cache mode (want auto|cached|uncached): " stringByAppendingString:cacheStr] userInfo:nil];
a = [[VZDiskImageStorageDeviceAttachment alloc] initWithURL:imageURL readOnly:ro
cachingMode:cacheMode
synchronizationMode:syncMode
error:&err];
}
#endif
if (!a) /* default / pre-12 fallback: unchanged behaviour */
a = [[VZDiskImageStorageDeviceAttachment alloc] initWithURL:imageURL readOnly:ro error:&err];
if (err)
@throw [NSException exceptionWithName:@"VMConfigDiskStorageError" reason:[err description] userInfo:nil];
if ([tmp isEqualToString:@"disk"])
Expand Down
9 changes: 8 additions & 1 deletion macosvm/main.m
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,7 @@ int main(int ac, char**av) {
if (!strcmp(av[i], "--disk") || !strcmp(av[i], "--usb") || !strcmp(av[i], "--aux") || !strcmp(av[i], "--initrd")) {
BOOL readOnly = NO;
BOOL keep = NO;
const char *syncMode = NULL, *cacheMode = NULL;
size_t create_size = 0;
char *c, *dop;
if (++i >= ac) {
Expand All @@ -540,6 +541,10 @@ int main(int ac, char**av) {
return 1;
}
create_size = (size_t) sz;
} else if (!strncmp(dop, "sync=", 5)) {
syncMode = dop + 5;
} else if (!strncmp(dop, "cache=", 6)) {
cacheMode = dop + 6;
} else {
fprintf(stderr, "ERROR: invalid disk option: '%s'\n", dop);
return 1;
Expand Down Expand Up @@ -569,6 +574,8 @@ int main(int ac, char**av) {
av[i - 1] + 2, readOnly ? "read-only" : "read-write", keep ? "keep" : "");
if (readOnly) [options addObject:@"readOnly"];
if (keep) [options addObject:@"keep"];
if (syncMode) [options addObject:[NSString stringWithFormat:@"sync=%s", syncMode]];
if (cacheMode) [options addObject:[NSString stringWithFormat:@"cache=%s", cacheMode]];
[spec addFileStorage:[NSString stringWithUTF8String:av[i]]
type:[NSString stringWithUTF8String:av[i - 1] + 2]
options:options];
Expand Down Expand Up @@ -694,7 +701,7 @@ int main(int ac, char**av) {
printf("\n\
Usage: %s [-g|--[no-]gui] [--[no-]audio]\n\
[--restore <path>] [--ephemeral] [--recovery]\n\
[--{disk|usb} <path>[,ro][,size=<spec>][,keep]] [--aux <path>]\n\
[--{disk|usb} <path>[,ro][,size=<spec>][,keep][,sync=<full|fsync|none>][,cache=<auto|cached|uncached>]] [--aux <path>]\n\
[--vol <path>[,ro][,{name=<name>|automount}]]\n\
[--net <spec>] [--mac <addr>] [-c <cpus>] [-r <ram>]\n\
[--no-serial] [--pty] [--pid-file <path>] [--script <cmd>]\n\
Expand Down