Add notifyError/onError notification for VM errors
For now, microdroid_manager shuts down a VM instance when it fails to
verify the VM payload. This change adds a new "error" notification to
deliver the error to the VM app.
Fow now this doesn't change the workflow. In a follow-up change this
will be changed so that VM app can decide to shutdown or not "onError".
Bug: 205778374
Test: MicrodroidHostTestCases
Change-Id: If7fdac3996b69601be0eda17da3e4cf218b4d1d8
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index 5d64684..1c88174 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -714,6 +714,16 @@
}
}
+ /// Call all registered callbacks to say that the VM encountered an error.
+ pub fn notify_error(&self, cid: Cid, error_code: i32, message: &str) {
+ let callbacks = &*self.0.lock().unwrap();
+ for callback in callbacks {
+ if let Err(e) = callback.onError(cid as i32, error_code, message) {
+ error!("Error notifying error event from VM CID {}: {}", cid, e);
+ }
+ }
+ }
+
/// Call all registered callbacks to say that the VM has died.
pub fn callback_on_died(&self, cid: Cid) {
let callbacks = &*self.0.lock().unwrap();
@@ -879,10 +889,10 @@
vm.callbacks.notify_payload_started(cid, stream);
Ok(())
} else {
- error!("notifyPayloadStarted is called from an unknown cid {}", cid);
+ error!("notifyPayloadStarted is called from an unknown CID {}", cid);
Err(new_binder_exception(
ExceptionCode::SERVICE_SPECIFIC,
- format!("cannot find a VM with cid {}", cid),
+ format!("cannot find a VM with CID {}", cid),
))
}
}
@@ -896,10 +906,10 @@
vm.callbacks.notify_payload_ready(cid);
Ok(())
} else {
- error!("notifyPayloadReady is called from an unknown cid {}", cid);
+ error!("notifyPayloadReady is called from an unknown CID {}", cid);
Err(new_binder_exception(
ExceptionCode::SERVICE_SPECIFIC,
- format!("cannot find a VM with cid {}", cid),
+ format!("cannot find a VM with CID {}", cid),
))
}
}
@@ -913,10 +923,27 @@
vm.callbacks.notify_payload_finished(cid, exit_code);
Ok(())
} else {
- error!("notifyPayloadFinished is called from an unknown cid {}", cid);
+ error!("notifyPayloadFinished is called from an unknown CID {}", cid);
Err(new_binder_exception(
ExceptionCode::SERVICE_SPECIFIC,
- format!("cannot find a VM with cid {}", cid),
+ format!("cannot find a VM with CID {}", cid),
+ ))
+ }
+ }
+
+ fn notifyError(&self, error_code: i32, message: &str) -> binder::Result<()> {
+ let cid = self.cid;
+ if let Some(vm) = self.state.lock().unwrap().get_vm(cid) {
+ info!("VM having CID {} encountered an error", cid);
+ vm.update_payload_state(PayloadState::Finished)
+ .map_err(|e| new_binder_exception(ExceptionCode::ILLEGAL_STATE, e.to_string()))?;
+ vm.callbacks.notify_error(cid, error_code, message);
+ Ok(())
+ } else {
+ error!("notifyPayloadStarted is called from an unknown CID {}", cid);
+ Err(new_binder_exception(
+ ExceptionCode::SERVICE_SPECIFIC,
+ format!("cannot find a VM with CID {}", cid),
))
}
}