Commit 4b3be262 authored by Josh Kunz's avatar Josh Kunz

Don't update the `prev_owner` when granting sealer/unsealers

`membrane_grant_single` would skip the grant if someone tried to grant
a sealer unsealer (since sealer/unsealers are not supposed to ever be
wrapped). However, `cn_membrane_grant` would still update the previous
owner to be the membrane's secret cspace despite the fact that the grant
never occurred so the sealer/unsealer did not exist in that c-space.

This commit adds a new error code ESKIPPED that can be returned to
signal that an operation was skipped, so tracking data structures don't
necessarily need to be updated.
parent 56552b88
......@@ -16,6 +16,8 @@ static const char * ERROR_DESCs[] = {
"Attempted to create an item when that item already exists",
// ENOTEXISTS
"The item does not exists",
// ESKIPPED
"The operation was skipped because it didn't need to be performed.",
};
static inline int error_index(int err) {
......
......@@ -12,9 +12,10 @@
#define EBADSEALER -14
#define EEXISTS -15
#define ENOTEXISTS -16
#define ESKIPPED -17
/* Update this when you add a new error */
#define __ERROR_MAX 16
#define __ERROR_MAX 17
const char * cn_error_desc(int err);
......
......@@ -847,7 +847,7 @@ static int cn_membrane_grant_single(cn_membrane_t * membrane,
/* TODO: Move check to cn_membrane_grant instead. */
if (cn_cnode_type(granted_cnode) == CN_SEALER_UNSEALER) {
cncwarn("skipping wrapping for sealer/unsealer\n");
res = 0;
res = ESKIPPED;
goto finish1;
}
......@@ -953,16 +953,21 @@ int cn_membrane_grant(cn_cnode_meta_t * send_meta,
recv_type = cn_membrane_annotation_type(recv_annotation);
}
if (cn_membrane_grant_single(membrane, send_type, recv_type,
prev_owner, prev_cap,
&prev_cap) != 0) {
res = cn_membrane_grant_single(membrane, send_type, recv_type,
prev_owner, prev_cap,
&prev_cap);
if (res == 0) {
cn_obj_lock(membrane);
prev_owner = membrane->secret;
cn_obj_unlock(membrane);
} else if (res == ESKIPPED) {
// pass
} else {
cncerr("Failed to do single grant with membrane %p\n", membrane);
res = -1;
goto fail;
}
cn_obj_lock(membrane);
prev_owner = membrane->secret;
cn_obj_unlock(membrane);
#ifndef NDEBUG
char * _annotation_string = cn_annotation_string(send_annotation);
......@@ -987,16 +992,20 @@ int cn_membrane_grant(cn_cnode_meta_t * send_meta,
enum cn_membrane_type recv_type = cn_membrane_annotation_type(recv_annotation);
enum cn_membrane_type send_type = cn_membrane_type_opposite(recv_type);
if (cn_membrane_grant_single(membrane, send_type, recv_type,
prev_owner, prev_cap,
&prev_cap) != 0) {
int res = cn_membrane_grant_single(membrane, send_type, recv_type,
prev_owner, prev_cap,
&prev_cap);
if (res == 0) {
cn_obj_lock(membrane);
prev_owner = membrane->secret;
cn_obj_unlock(membrane);
} else if (res == ESKIPPED) {
// just pass
} else {
cncerr("Failed to add membrane wrap for membrane %p\n", membrane);
goto fail;
}
cn_obj_lock(membrane);
prev_owner = membrane->secret;
cn_obj_unlock(membrane);
/* Don't need to track handled state because the recv-ers hash table
* guarantees uniqueness. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment