"unclone",
"edit",
"sysctl",
+ "fi",
"catch for illegal requests"
};
static int known_request_types[] = {
RS_UNCLONE,
RS_EDIT,
RS_SYSCTL,
+ RS_FI,
0
};
#define ILLEGAL_REQUEST sizeof(known_requests)/sizeof(char *)
fprintf(stderr, " %s restart <label>\n", app_name);
fprintf(stderr, " %s clone <label>\n", app_name);
fprintf(stderr, " %s unclone <label>\n", app_name);
+ fprintf(stderr, " %s fi <label>\n", app_name);
fprintf(stderr, " %s sysctl <srv_status|upd_start|upd_run|upd_stop|upd_status>\n", app_name);
fprintf(stderr, " %s shutdown\n", app_name);
fprintf(stderr, " Options:\n");
}
}
else if (req_nr == RS_DOWN || req_nr == RS_REFRESH || req_nr == RS_RESTART
- || req_nr == RS_CLONE || req_nr == RS_UNCLONE) {
+ || req_nr == RS_CLONE || req_nr == RS_UNCLONE || req_nr == RS_FI) {
/* Verify argument count. */
if (argc - 1 < optind+ARG_LABEL) {
case RS_RESTART:
case RS_CLONE:
case RS_UNCLONE:
+ case RS_FI:
m.m_rs_req.addr = req_label;
m.m_rs_req.len = strlen(req_label);
break;
#define RS_LU_PREPARE (RS_RQ_BASE + 21) /* prepare to update message */
#define RS_EDIT (RS_RQ_BASE + 22) /* edit system service */
#define RS_SYSCTL (RS_RQ_BASE + 23) /* perform system ctl action */
+#define RS_FI (RS_RQ_BASE + 24) /* inject fault into service */
/* Subfunctions for RS_SYSCTL. */
#define RS_SYSCTL_SRV_STATUS 1
#define RS_SYSCTL_UPD_STOP 4
#define RS_SYSCTL_UPD_STATUS 5
+/* Subfunctions for RS_FI. */
+#define RS_FI_CRASH 1
+
/*===========================================================================*
* Messages for the Data Store Server *
*===========================================================================*/
typedef struct {
cp_grant_id_t gid;
size_t size;
+ int subtype;
- uint8_t padding[48];
+ uint8_t padding[44];
} mess_lsys_fi_ctl;
_ASSERT_MSG_SIZE(mess_lsys_fi_ctl);
*===========================================================================*/
int do_sef_fi_request(message *m_ptr)
{
+ /* See if we are simply asked to crash. */
+ if (m_ptr->m_lsys_fi_ctl.subtype == RS_FI_CRASH)
+ panic("Crash!");
+
#if SEF_FI_ALLOW_EDFI
/* Forward the request to the EDFI fault injector, if linked in. */
if(edfi_ctl_process_request)
case RS_UNCLONE: result = do_unclone(&m); break;
case RS_EDIT: result = do_edit(&m); break;
case RS_SYSCTL: result = do_sysctl(&m); break;
+ case RS_FI: result = do_fi(&m); break;
case RS_GETSYSINFO: result = do_getsysinfo(&m); break;
case RS_LOOKUP: result = do_lookup(&m); break;
/* Ready messages. */
int do_getsysinfo(message *m);
int do_lookup(message *m);
int do_sysctl(message *m);
+int do_fi(message *m);
/* manager.c */
int check_call_permission(endpoint_t caller, int call, struct rproc
/* utility.c */
int init_service(struct rproc *rp, int type, int flags);
+int fi_service(struct rproc *rp);
void fill_send_mask(sys_map_t *send_mask, int set_bits);
void fill_call_mask( int *calls, int tot_nr_calls,
bitchunk_t *call_mask, int call_base, int is_init);
return OK;
}
+/*===========================================================================*
+ * do_fi *
+ *===========================================================================*/
+int do_fi(message *m_ptr)
+{
+ struct rproc *rp;
+ struct rprocpub *rpub;
+ int s, r;
+ char label[RS_MAX_LABEL_LEN];
+
+ /* Copy label. */
+ s = copy_label(m_ptr->m_source, m_ptr->m_rs_req.addr,
+ m_ptr->m_rs_req.len, label, sizeof(label));
+ if(s != OK) {
+ return s;
+ }
+
+ /* Lookup slot by label. */
+ rp = lookup_slot_by_label(label);
+ if(!rp) {
+ if(rs_verbose)
+ printf("RS: do_fi: service '%s' not found\n", label);
+ return(ESRCH);
+ }
+ rpub = rp->r_pub;
+
+ /* Check if the call can be allowed. */
+ if((r = check_call_permission(m_ptr->m_source, RS_FI, rp)) != OK)
+ return r;
+
+ /* Inject fault into the service as requested. */
+ s = fi_service(rp);
+
+ return s;
+}
+
/*===========================================================================*
* check_request *
*===========================================================================*/
return r;
}
+/*===========================================================================*
+ * fi_service *
+ *===========================================================================*/
+int fi_service(struct rproc *rp)
+{
+ message m;
+
+ /* Send fault injection message. */
+ m.m_type = COMMON_REQ_FI_CTL;
+ m.m_lsys_fi_ctl.subtype = RS_FI_CRASH;
+ return rs_asynsend(rp, &m, 0);
+}
+
/*===========================================================================*
* fill_send_mask *
*===========================================================================*/