Skip to content

Commit

Permalink
vm(qemu): move loadvm to monitor command
Browse files Browse the repository at this point in the history
Also clean up the names for the other snapshot commands.
This resolves the issue where the cursor was not restored properly.

Fixes #4665
  • Loading branch information
osy committed Mar 21, 2023
1 parent 6163761 commit 8c372b1
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 41 deletions.
18 changes: 0 additions & 18 deletions Configuration/UTMConfigurationWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -141,24 +141,6 @@ import Foundation
}
}

@objc var qemuSnapshotName: String? {
get {
if wrappedValue is UTMQemuConfiguration {
return qemuConfig!._qemu.snapshotName
} else {
fatalError()
}
}

set {
if wrappedValue is UTMQemuConfiguration {
qemuConfig!._qemu.snapshotName = newValue
} else {
fatalError()
}
}
}

// FIXME: @MainActor here is a HACK and does nothing in Obj-C!
@MainActor @objc var qemuSpiceSocketURL: URL {
if wrappedValue is UTMQemuConfiguration {
Expand Down
5 changes: 1 addition & 4 deletions Configuration/UTMQemuConfiguration+Arguments.swift
Original file line number Diff line number Diff line change
Expand Up @@ -796,10 +796,7 @@ import Foundation
@QEMUArgumentBuilder private var miscArguments: [QEMUArgument] {
f("-name")
f(information.name)
if let snapshotName = qemu.snapshotName {
f("-loadvm")
f(snapshotName)
} else if qemu.isDisposable {
if qemu.isDisposable {
f("-snapshot")
}
f("-uuid")
Expand Down
3 changes: 0 additions & 3 deletions Configuration/UTMQemuConfigurationQEMU.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,6 @@ struct UTMQemuConfigurationQEMU: Codable {
/// Additional QEMU arguments.
var additionalArguments: [QEMUArgument] = []

/// If set, attempt to boot from a snapshot with the following name. Not saved.
var snapshotName: String?

/// If true, changes to the VM will not be committed to disk. Not saved.
var isDisposable: Bool = false

Expand Down
5 changes: 3 additions & 2 deletions Managers/UTMQemuMonitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ NS_ASSUME_NONNULL_BEGIN
- (void)qemuStopWithCompletion:(void (^ _Nullable)(NSError * _Nullable))completion;
- (void)qemuResumeWithCompletion:(void (^ _Nullable)(NSError * _Nullable))completion;
- (void)qemuQuitWithCompletion:(void (^ _Nullable)(NSError * _Nullable))completion;
- (void)qemuSaveStateWithCompletion:(void (^ _Nullable)(NSString * _Nullable, NSError * _Nullable))completion snapshotName:(NSString *)name;
- (void)qemuDeleteStateWithCompletion:(void (^)(NSString * _Nullable, NSError * _Nullable))completion snapshotName:(NSString *)name;
- (void)qemuSaveSnapshot:(NSString *)snapshot withCompletion:(void (^)(NSString * _Nullable, NSError * _Nullable))completion;
- (void)qemuDeleteSnapshot:(NSString *)snapshot withCompletion:(void (^)(NSString * _Nullable, NSError * _Nullable))completion;
- (void)qemuRestoreSnapshot:(NSString *)snapshot withCompletion:(void (^)(NSString * _Nullable, NSError * _Nullable))completion;

- (void)mouseIndexForAbsolute:(BOOL)absolute withCompletion:(void (^)(int64_t, NSError * _Nullable))completion;
- (void)mouseSelect:(int64_t)index withCompletion:(void (^)(NSString * _Nullable, NSError * _Nullable))completion;
Expand Down
13 changes: 9 additions & 4 deletions Managers/UTMQemuMonitor.m
Original file line number Diff line number Diff line change
Expand Up @@ -229,13 +229,18 @@ - (void)qemuQuitWithCompletion:(void (^ _Nullable)(NSError * _Nullable))completi
[self qmpPowerCommand:@"quit" completion:completion];
}

- (void)qemuSaveStateWithCompletion:(void (^)(NSString * _Nullable, NSError * _Nullable))completion snapshotName:(NSString *)name {
NSString *cmd = [NSString stringWithFormat:@"savevm %@", name];
- (void)qemuSaveSnapshot:(NSString *)snapshot withCompletion:(void (^)(NSString * _Nullable, NSError * _Nullable))completion {
NSString *cmd = [NSString stringWithFormat:@"savevm %@", snapshot];
[self qmpHmpCommand:cmd completion:completion];
}

- (void)qemuDeleteStateWithCompletion:(void (^)(NSString * _Nullable, NSError * _Nullable))completion snapshotName:(NSString *)name {
NSString *cmd = [NSString stringWithFormat:@"delvm %@", name];
- (void)qemuDeleteSnapshot:(NSString *)snapshot withCompletion:(void (^)(NSString * _Nullable, NSError * _Nullable))completion {
NSString *cmd = [NSString stringWithFormat:@"delvm %@", snapshot];
[self qmpHmpCommand:cmd completion:completion];
}

- (void)qemuRestoreSnapshot:(NSString *)snapshot withCompletion:(void (^)(NSString * _Nullable, NSError * _Nullable))completion {
NSString *cmd = [NSString stringWithFormat:@"loadvm %@", snapshot];
[self qmpHmpCommand:cmd completion:completion];
}

Expand Down
35 changes: 25 additions & 10 deletions Managers/UTMQemuVirtualMachine.m
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,6 @@ - (void)_vmStartWithCompletion:(void (^)(NSError * _Nullable))completion {
}

self.config.qemuIsDisposable = self.isRunningAsSnapshot;
if (!self.isRunningAsSnapshot) {
// Loading save states isn't possible when -snapshot is used
if (self.registryEntry.hasSaveState) {
self.config.qemuSnapshotName = kSuspendSnapshotName;
}
}

NSArray<NSString *> *arguments = self.config.qemuArguments;
NSArray<NSURL *> *resources = self.config.qemuResources;
Expand Down Expand Up @@ -306,6 +300,27 @@ - (void)_vmStartWithCompletion:(void (^)(NSError * _Nullable))completion {
return;
}
assert(self.qemu.isConnected);
// load saved state if requested
if (!self.isRunningAsSnapshot && self.registryEntry.hasSaveState) {
__block NSError *restoreError = nil;
dispatch_semaphore_t restoreSnapshotEvent = dispatch_semaphore_create(0);
[self.qemu qemuRestoreSnapshot:kSuspendSnapshotName withCompletion:^(NSString *result, NSError *error) {
if (error) {
restoreError = error;
} else if ([result localizedCaseInsensitiveContainsString:@"Error"]) {
restoreError = [self errorWithMessage:result]; // error message
}
dispatch_semaphore_signal(restoreSnapshotEvent);
}];
if (dispatch_semaphore_wait(restoreSnapshotEvent, DISPATCH_TIME_FOREVER) != 0) {
completion([self errorGeneric]);
return;
}
if (restoreError) {
completion(restoreError);
return;
}
}
// continue VM boot
if (![self.qemu continueBootWithError:&err]) {
UTMLog(@"Failed to boot: %@", err);
Expand Down Expand Up @@ -478,7 +493,7 @@ - (void)vmPauseSave:(BOOL)save completion:(void (^)(NSError * _Nullable))complet
- (void)_vmSaveStateWithCompletion:(void (^)(NSError * _Nullable))completion {
__block NSError *saveError = nil;
dispatch_semaphore_t saveTriggeredEvent = dispatch_semaphore_create(0);
[self.qemu qemuSaveStateWithCompletion:^(NSString *result, NSError *err) {
[self.qemu qemuSaveSnapshot:kSuspendSnapshotName withCompletion:^(NSString *result, NSError *err) {
UTMLog(@"save callback: %@", result);
if (err) {
UTMLog(@"error: %@", err);
Expand All @@ -493,7 +508,7 @@ - (void)_vmSaveStateWithCompletion:(void (^)(NSError * _Nullable))completion {
saveError = [self errorWithMessage:newMsg];
}
dispatch_semaphore_signal(saveTriggeredEvent);
} snapshotName:kSuspendSnapshotName];
}];
if (dispatch_semaphore_wait(saveTriggeredEvent, dispatch_time(DISPATCH_TIME_NOW, kStopTimeout)) != 0) {
UTMLog(@"Save operation timeout");
saveError = [self errorGeneric];
Expand Down Expand Up @@ -521,7 +536,7 @@ - (void)_vmDeleteStateWithCompletion:(void (^)(NSError * _Nullable))completion {
__block NSError *deleteError = nil;
if (self.qemu) { // if QEMU is running
dispatch_semaphore_t deleteTriggeredEvent = dispatch_semaphore_create(0);
[self.qemu qemuDeleteStateWithCompletion:^(NSString *result, NSError *err) {
[self.qemu qemuDeleteSnapshot:kSuspendSnapshotName withCompletion:^(NSString *result, NSError *err) {
UTMLog(@"delete save callback: %@", result);
if (err) {
UTMLog(@"error: %@", err);
Expand All @@ -531,7 +546,7 @@ - (void)_vmDeleteStateWithCompletion:(void (^)(NSError * _Nullable))completion {
deleteError = [self errorWithMessage:result]; // error message
}
dispatch_semaphore_signal(deleteTriggeredEvent);
} snapshotName:kSuspendSnapshotName];
}];
if (dispatch_semaphore_wait(deleteTriggeredEvent, dispatch_time(DISPATCH_TIME_NOW, kStopTimeout)) != 0) {
UTMLog(@"Delete save operation timeout");
deleteError = [self errorGeneric];
Expand Down

0 comments on commit 8c372b1

Please sign in to comment.