int fork_xenbus(void) { char path[50]; char *flag = "fork", *err; xenbus_event_queue events = NULL; sprintf(path,"fork/requests"); xenbus_watch_path_token(XBT_NIL, path, path, &events); xenbus_write(XBT_NIL, path, "fork"); while(1){ xenbus_wait_for_watch(&events); if ((err = xenbus_read(XBT_NIL, path, &flag))) { free(err); continue; } if (!strcmp(flag, "") || !strcmp(flag, "fork")) { free(flag); flag = NULL; continue; }else if (!strcmp(flag, "0")) return 0; else if (!strcmp(flag, "1")) return 1; err = xenbus_write(XBT_NIL, path, ""); free(err); free(flag); flag = NULL; } return -1; }
static void shutdown_thread(void *p) { const char *path = "control/shutdown"; const char *token = path; xenbus_event_queue events = NULL; char *shutdown = NULL, *err; unsigned int shutdown_reason; xenbus_watch_path_token(XBT_NIL, path, token, &events); while ((err = xenbus_read(XBT_NIL, path, &shutdown)) != NULL || !strcmp(shutdown, "")) { free(err); free(shutdown); shutdown = NULL; xenbus_wait_for_watch(&events); } err = xenbus_unwatch_path_token(XBT_NIL, path, token); free(err); err = xenbus_write(XBT_NIL, path, ""); free(err); printk("Shutting down (%s)\n", shutdown); if (!strcmp(shutdown, "poweroff")) shutdown_reason = SHUTDOWN_poweroff; else if (!strcmp(shutdown, "reboot")) shutdown_reason = SHUTDOWN_reboot; else /* Unknown */ shutdown_reason = SHUTDOWN_crash; app_shutdown(shutdown_reason); free(shutdown); }
static int wait_for_backend_closed(xenbus_event_queue* events, char* path) { int state; TPMFRONT_LOG("Waiting for backend to close..\n"); while(1) { state = xenbus_read_integer(path); if ( state < 0) state = XenbusStateUnknown; switch(state) { case XenbusStateUnknown: TPMFRONT_ERR("Backend Unknown state, forcing shutdown\n"); return -1; case XenbusStateClosed: TPMFRONT_LOG("Backend Closed\n"); return 0; case XenbusStateInitWait: TPMFRONT_LOG("Backend Closed (waiting for reconnect)\n"); return 0; default: xenbus_wait_for_watch(events); } } }
static int wait_for_backend_connect(xenbus_event_queue* events, char* path) { int state; TPMFRONT_LOG("Waiting for backend connection..\n"); /* Wait for the backend to connect */ while(1) { state = xenbus_read_integer(path); if ( state < 0) state = XenbusStateUnknown; switch(state) { /* Bad states, we quit with error */ case XenbusStateUnknown: case XenbusStateClosing: case XenbusStateClosed: TPMFRONT_ERR("Unable to connect to backend\n"); return -1; /* If backend is connected then break out of loop */ case XenbusStateConnected: TPMFRONT_LOG("Backend Connected\n"); return 0; default: xenbus_wait_for_watch(events); } } }
char* xenbus_wait_for_value(const char* path, const char* value, xenbus_event_queue *queue) { if (!queue) queue = &xenbus_events; for(;;) { char *res, *msg; int r; msg = xenbus_read(XBT_NIL, path, &res); if(msg) return msg; r = strcmp(value,res); free(res); if(r==0) break; else xenbus_wait_for_watch(queue); } return NULL; }
char* xenbus_wait_for_value(const char* path, const char* value, struct xenbus_event_queue *queue) { if (!queue) queue = &xenbus_default_watch_queue; for(;;) { char *res, *msg; int r; msg = xenbus_read(XBT_NIL, path, &res); if(msg) return msg; r = bmk_strcmp(value,res); bmk_memfree(res, BMK_MEMWHO_WIREDBMK); if(r==0) break; else xenbus_wait_for_watch(queue); } return NULL; }
char *xenbus_wait_for_state_change(const char* path, XenbusState *state, xenbus_event_queue *queue) { if (!queue) queue = &xenbus_events; for(;;) { char *res, *msg; XenbusState rs; msg = xenbus_read(XBT_NIL, path, &res); if(msg) return msg; rs = (XenbusState) (res[0] - 48); free(res); if (rs == *state) xenbus_wait_for_watch(queue); else { *state = rs; break; } } return NULL; }
char *xenbus_wait_for_state_change(const char* path, XenbusState *state, struct xenbus_event_queue *queue) { if (!queue) queue = &xenbus_default_watch_queue; for(;;) { char *res, *msg; XenbusState rs; msg = xenbus_read(XBT_NIL, path, &res); if(msg) return msg; rs = (XenbusState) (res[0] - 48); bmk_memfree(res, BMK_MEMWHO_WIREDBMK); if (rs == *state) xenbus_wait_for_watch(queue); else { *state = rs; break; } } return NULL; }
void pcifront_watches(void *opaque) { XenbusState state; char *err = NULL, *msg = NULL; char *be_path, *be_state; char* nodename = opaque ? opaque : "device/pci/0"; char path[strlen(nodename) + 9]; char fe_state[strlen(nodename) + 7]; xenbus_event_queue events = NULL; snprintf(path, sizeof(path), "%s/backend", nodename); snprintf(fe_state, sizeof(fe_state), "%s/state", nodename); while (1) { printk("pcifront_watches: waiting for backend path to appear %s\n", path); xenbus_watch_path_token(XBT_NIL, path, path, &events); while ((err = xenbus_read(XBT_NIL, path, &be_path)) != NULL) { free(err); xenbus_wait_for_watch(&events); } xenbus_unwatch_path_token(XBT_NIL, path, path); printk("pcifront_watches: waiting for backend to get into the right state %s\n", be_path); be_state = (char *) malloc(strlen(be_path) + 7); snprintf(be_state, strlen(be_path) + 7, "%s/state", be_path); xenbus_watch_path_token(XBT_NIL, be_state, be_state, &events); while ((err = xenbus_read(XBT_NIL, be_state, &msg)) != NULL || msg[0] > '4') { free(msg); free(err); xenbus_wait_for_watch(&events); } xenbus_unwatch_path_token(XBT_NIL, be_state, be_state); if (init_pcifront(NULL) == NULL) { free(be_state); free(be_path); continue; } xenbus_watch_path_token(XBT_NIL, be_state, be_state, &events); state = XenbusStateConnected; printk("pcifront_watches: waiting for backend events %s\n", be_state); while ((err = xenbus_wait_for_state_change(be_state, &state, &events)) == NULL && (err = xenbus_read(XBT_NIL, pcidev->backend, &msg)) == NULL) { free(msg); printk("pcifront_watches: backend state changed: %s %d\n", be_state, state); if (state == XenbusStateReconfiguring) { printk("pcifront_watches: writing %s %d\n", fe_state, XenbusStateReconfiguring); if ((err = xenbus_switch_state(XBT_NIL, fe_state, XenbusStateReconfiguring)) != NULL) { printk("pcifront_watches: error changing state to %d: %s\n", XenbusStateReconfiguring, err); if (!strcmp(err, "ENOENT")) { xenbus_write(XBT_NIL, fe_state, "7"); free(err); } } } else if (state == XenbusStateReconfigured) { printk("pcifront_watches: writing %s %d\n", fe_state, XenbusStateConnected); printk("pcifront_watches: changing state to %d\n", XenbusStateConnected); if ((err = xenbus_switch_state(XBT_NIL, fe_state, XenbusStateConnected)) != NULL) { printk("pcifront_watches: error changing state to %d: %s\n", XenbusStateConnected, err); if (!strcmp(err, "ENOENT")) { xenbus_write(XBT_NIL, fe_state, "4"); free(err); } } } else if (state == XenbusStateClosing) break; } if (err) { printk("pcifront_watches: done waiting err=%s\n", err); free(err); } else printk("pcifront_watches: done waiting\n"); err = xenbus_unwatch_path_token(XBT_NIL, be_state, be_state); shutdown_pcifront(pcidev); free(be_state); free(be_path); free(err); pcidev = NULL; } xenbus_unwatch_path_token(XBT_NIL, path, path); }