monitor: bugfixes in the revocation protocol
authorReto Achermann <reto.achermann@inf.ethz.ch>
Wed, 5 Aug 2015 15:18:40 +0000 (17:18 +0200)
committerReto Achermann <reto.achermann@inf.ethz.ch>
Wed, 5 Aug 2015 15:19:29 +0000 (17:19 +0200)
revoke_local was called twice resulting in state corruption

Signed-off-by: Reto Achermann <reto.achermann@inf.ethz.ch>

usr/monitor/capops/internal.h
usr/monitor/capops/retrieve.c
usr/monitor/capops/revoke.c

index 0da4d21..c8f44bd 100644 (file)
@@ -37,6 +37,7 @@ struct result_closure {
 
 #define GOTO_IF_ERR(err, label) do { \
     if (err_is_fail(err)) { \
+        DEBUG_ERR(err, "%s:%u -> goto err\n", __FUNCTION__, __LINE__); \
         goto label; \
     } \
 } while (0)
index 332fb37..49d006d 100644 (file)
@@ -51,15 +51,14 @@ capops_retrieve(struct domcapref cap,
 {
     errval_t err;
 
+    DEBUG_CAPOPS("%s ## start transfer ownership \n", __FUNCTION__);
+
     distcap_state_t state;
     err = dom_cnode_get_state(cap, &state);
     GOTO_IF_ERR(err, report_error);
     if (distcap_state_is_busy(state)) {
         err = MON_ERR_REMOTE_CAP_RETRY;
     }
-    if (distcap_state_is_foreign(state)) {
-        err = MON_ERR_CAP_FOREIGN;
-    }
     GOTO_IF_ERR(err, report_error);
 
     err = monitor_lock_cap(cap.croot, cap.cptr, cap.bits);
@@ -73,6 +72,9 @@ capops_retrieve(struct domcapref cap,
     rst->result_handler = result_handler;
     rst->st = st;
 
+    err = monitor_domains_cap_identify(cap.croot, cap.cptr, cap.bits, &rst->rawcap);
+    GOTO_IF_ERR(err, free_st);
+
     err = monitor_get_domcap_owner(cap, &rst->prev_owner);
     GOTO_IF_ERR(err, free_st);
 
@@ -98,6 +100,9 @@ report_error:
 static void
 retrieve_ownership__rx(errval_t status, struct retrieve_rpc_st *st)
 {
+    DEBUG_CAPOPS("%s ## transfer ownership done. calling %p\n", __FUNCTION__,
+                 st->result_handler);
+
     caplock_unlock(st->cap);
     st->result_handler(status, st->st);
     free(st);
@@ -133,6 +138,7 @@ retrieve_owner__send(struct intermon_binding *b,
     return;
 
 report_error:
+    DEBUG_CAPOPS("%s failed \n", __FUNCTION__);
     retrieve_ownership__rx(err, st);
 }
 
@@ -144,6 +150,8 @@ retrieve_request__rx(struct intermon_binding *b,
     errval_t err, err2;
     struct intermon_state *inter_st = (struct intermon_state*)b->st;
 
+    DEBUG_CAPOPS("%s ## transfer ownership request\n", __FUNCTION__);
+
     struct retrieve_response_st *rst;
     err = calloce(1, sizeof(*rst), &rst);
     PANIC_IF_ERR(err, "allocating retrieve respones state");
@@ -229,6 +237,9 @@ retrieve_result__rx(struct intermon_binding *b, errval_t status,
     errval_t err;
     struct retrieve_rpc_st *rst = (struct retrieve_rpc_st*)(lvaddr_t)st;
 
+    DEBUG_CAPOPS("%s ## ownership transferred: %s \n", __FUNCTION__,
+                 err_getstring(status));
+
     if (err_is_fail(status)) {
         err = status;
         goto report_error;
@@ -239,11 +250,15 @@ retrieve_result__rx(struct intermon_binding *b, errval_t status,
                                           NULL);
     PANIC_IF_ERR(err, "setting rrels for retrieved cap");
 
+    DEBUG_CAPOPS("%s broadcast updates to other monitors.\n", __FUNCTION__);
+
     struct event_closure updated_cont
         = MKCONT(retrieve_ownership_update__fin, rst);
     err = capsend_update_owner(rst->cap, updated_cont);
     PANIC_IF_ERR(err, "updating retrieve ownership");
 
+    return;
+
 report_error:
     retrieve_ownership__rx(err, rst);
 }
@@ -253,5 +268,7 @@ retrieve_ownership_update__fin(void *st)
 {
     struct retrieve_rpc_st *rst = (struct retrieve_rpc_st*)st;
 
+    DEBUG_CAPOPS("%s updated in ownership broadcasted.\n", __FUNCTION__);
+
     retrieve_ownership__rx(SYS_ERR_OK, rst);
 }
index 7236e60..5cc0914 100644 (file)
@@ -67,6 +67,8 @@ capops_revoke(struct domcapref cap,
 {
     errval_t err;
 
+    DEBUG_CAPOPS("%s ## start revocation protocol\n", __FUNCTION__);
+
     distcap_state_t state;
     err = dom_cnode_get_state(cap, &state);
     GOTO_IF_ERR(err, report_error);
@@ -87,6 +89,7 @@ capops_revoke(struct domcapref cap,
 
     if (distcap_state_is_foreign(state)) {
         // need to retrieve ownership
+        DEBUG_CAPOPS("%s getting cap ownership\n", __FUNCTION__);
         capops_retrieve(rst->cap, revoke_retrieve__rx, rst);
     }
     else {
@@ -133,8 +136,10 @@ revoke_result__rx(errval_t result,
         }
     }
 
+    DEBUG_CAPOPS("%s ## revocation completed, calling %p\n", __FUNCTION__,
+                 st->result_handler);
+
     st->result_handler(result, st->st);
-    free(st);
 }
 
 static void
@@ -146,6 +151,7 @@ revoke_retrieve__rx(errval_t result, void *st_)
         revoke_result__rx(result, st, false);
     }
     else {
+
 #ifndef NDEBUG
         distcap_state_t state;
         errval_t err = dom_cnode_get_state(st->cap, &state);
@@ -170,6 +176,8 @@ revoke_local(struct revoke_master_st *st)
                                      st->cap.bits);
     PANIC_IF_ERR(err, "marking revoke");
 
+
+    DEBUG_CAPOPS("%s ## revocation: mark phase\n", __FUNCTION__);
     // XXX: could check whether remote copies exist here(?), -SG, 2014-11-05
     err = capsend_relations(&st->rawcap, revoke_mark__send,
             &st->revoke_mc_st, &st->dests);
@@ -294,7 +302,7 @@ revoke_ready__rx(struct intermon_binding *b, genvaddr_t st)
         return;
     }
 
-    DEBUG_CAPOPS("%s: sending commit\n", __FUNCTION__);
+    DEBUG_CAPOPS("%s ## revocation: commit phase\n", __FUNCTION__);
     err = capsend_relations(&rvk_st->rawcap, revoke_commit__send,
             &rvk_st->revoke_mc_st, &rvk_st->dests);
     PANIC_IF_ERR(err, "enqueing revoke_commit multicast");
@@ -398,12 +406,16 @@ void
 revoke_done__rx(struct intermon_binding *b,
                 genvaddr_t st)
 {
+    DEBUG_CAPOPS("%s\n", __FUNCTION__);
+
     struct revoke_master_st *rvk_st = (struct revoke_master_st*)(lvaddr_t)st;
+
     if (!capsend_handle_mc_reply(&rvk_st->revoke_mc_st)) {
         // multicast not complete
         return;
     }
 
+    DEBUG_CAPOPS("%s ## revocation: fin phase\n", __FUNCTION__);
     rvk_st->remote_fin = true;
     if (rvk_st->local_fin) {
         revoke_result__rx(SYS_ERR_OK, rvk_st, true);