-
-
Notifications
You must be signed in to change notification settings - Fork 779
app_loader: add uninstall functionality #4528
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
I implemented a helper that iterates over loaded processes to detect and remove any matching instance in the kernel. I did not want to the async loader to track these additional states |
kernel_data | ||
.schedule_upcall(upcall::UNINSTALL_DONE, (into_statuscode(result), 0, 0)) | ||
.ok(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kernel_data | |
.schedule_upcall(upcall::UNINSTALL_DONE, (into_statuscode(result), 0, 0)) | |
.ok(); | |
let _ = kernel_data | |
.schedule_upcall(upcall::UNINSTALL_DONE, (into_statuscode(result), 0, 0)); |
/// Call to uninstall an app with given ShortId and app version. | ||
fn uninstall(&self, short_id: usize, app_version: usize) -> Result<(), ErrorCode>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why isn't this short_id: ShortId
using the actual type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't have "install" so maybe we shouldn't have "uninstall" in this trait. What about "remove" or "erase"? I think the arguments make sense because it is the only general way to identify a unique app binary.
The comment should be more specific about what this operation has to do exactly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because I wanted to keep all this within the dynamic_binary_storage
capsule. It can be changed to app_loader
.
Hm. Essentially we aim to terminate the process and then erase. Which is two operations. Hence, the name uninstall for this function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But why would the trait responsible for storing an app also be expected to track the state of the app, possibly terminate, and do whatever else is required? I would expect the implementor to just have to worry about how apps are stored.
/// Terminate a process if it exists, and remove it from ProcessArray. | ||
pub(crate) fn reclaim_app_memory(&self, shortid: process::ShortId) { | ||
for slot in self.processes.iter() { | ||
if let Some(process) = slot.get() { | ||
if process.short_app_id() == shortid { | ||
process.terminate(None); | ||
slot.proc.set(None); | ||
break; | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree this reclaims the slot in the processes array, but the app memory is still effectively lost isn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the memory is lost because of how the SequentialProcessLoadingMachine
is implemented. We need to scan RAM for new memory availability similar to scan_flash_for_binaries()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the iteration before this change, the memory region shrinks, so uninstalling the app and reinstalling it still placed the new memory region at 0x20016000.
kernel/src/process_binary.rs
Outdated
|
||
/// Credential to vaildate if the app needs to be loaded | ||
pub valid_app: bool, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of duplicating this information, we can just call self.header.enabled()
if we need to know this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, makes sense
// If this is an app but it isn't enabled, then we can return an error. | ||
if !tbf_header.enabled() { | ||
if config::CONFIG.debug_load_processes { | ||
debug!( | ||
"Process not enabled flash={:#010X}-{:#010X} process={:?}", | ||
app_flash.as_ptr() as usize, | ||
app_flash.as_ptr() as usize + app_flash.len() - 1, | ||
tbf_header.get_package_name().unwrap_or("(no name)") | ||
); | ||
} | ||
return Err(ProcessBinaryError::NotEnabledProcess); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this no longer an error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because if this errors out, we don't get the process binary object to compute the ShortId from.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that's fine, but the error variant needs to be removed entirely.
I think that adding a dynamic RAM slice approach needs to be its own PR. There is a lot going on in that change and it really needs independent scrutiny. My initial thought is I think the size of the memory region has to remain in |
Pull Request Overview
This pr introduces an
uninstall(ShortId, app_version)
function to the dynamic process loader.The uninstall operation supports two cases:
The uninstall procedure involves three steps:
Locate the Binary
Terminate if Running
If the binary corresponds to a currently running process:
If the binary is not enabled, this step does nothing.
Testing Strategy
This pull request was tested by running a blink app on an nRF52840dk and then using a helper app to uninstall it.
TODO or Help Wanted
N/A
Documentation Updated
/docs
, or no updates are required.Formatting
make prepush
.