int configure_mn(cfg_t *cfg) { lisp_xtr_t *xtr; shash_t *lcaf_ht; /* CREATE AND CONFIGURE MN */ if (ctrl_dev_create(MN_MODE, &ctrl_dev) != GOOD) { OOR_LOG(LCRIT, "Failed to create mobile node. Aborting!"); exit_cleanup(); } lcaf_ht = parse_lcafs(cfg); xtr = CONTAINER_OF(ctrl_dev, lisp_xtr_t, super); if (configure_tunnel_router(cfg, xtr, lcaf_ht)!=GOOD){ return (BAD); } if (parse_map_servers(cfg, xtr) != GOOD){ return (BAD); } if (parse_proxy_etrs(cfg, xtr) != GOOD){ return (BAD); } if (parse_proxy_itrs(cfg, xtr) != GOOD){ return (BAD); } if (parse_database_mapping(cfg, xtr, lcaf_ht) != GOOD){ return (BAD); } /* destroy the hash table */ shash_destroy(lcaf_ht); return (GOOD); }
//-------------------------------------------------------------------------------------------------- le_mem_PoolRef_t _le_mem_FindPool ( const char* componentName, ///< [IN] Name of the component. const char* name ///< [IN] Name of the pool inside the component. ) { le_mem_PoolRef_t result = NULL; // Construct the component-scoped pool name. // Note: Don't check for truncation because if it is truncated, it will be consistent with // the truncation that would have occurred in InitPool(). char fullName[MAX_POOL_NAME_BYTES]; (void)snprintf(fullName, sizeof(fullName), "%s.%s", componentName, name); Lock(); // Search all pools except for the first one because the first pool is always the sub-pools pool. le_dls_Link_t* poolLinkPtr = le_dls_Peek(&ListOfPools); poolLinkPtr = le_dls_PeekNext(&ListOfPools, poolLinkPtr); while (poolLinkPtr) { MemPool_t* memPoolPtr = CONTAINER_OF(poolLinkPtr, MemPool_t, poolLink); if (strcmp(fullName, memPoolPtr->name) == 0) { result = memPoolPtr; break; } poolLinkPtr = le_dls_PeekNext(&ListOfPools, poolLinkPtr); } Unlock(); return result; }
//-------------------------------------------------------------------------------------------------- le_mrc_ScanInformation_Ref_t le_mrc_GetNextCellularNetworkScan ( le_mrc_ScanInformation_ListRef_t scanInformationListRef ///< [IN] The list of scan information. ) { pa_mrc_ScanInformation_t* nodePtr; le_dls_Link_t* linkPtr; le_mrc_ScanInformationList_t* scanInformationListPtr = le_ref_Lookup(ScanInformationListRefMap, scanInformationListRef); if (scanInformationListPtr == NULL) { LE_KILL_CLIENT("Invalid reference (%p) provided!", scanInformationListRef); return NULL; } linkPtr = le_dls_PeekNext(&(scanInformationListPtr->paScanInformationList), scanInformationListPtr->currentLink); if (linkPtr != NULL) { nodePtr = CONTAINER_OF(linkPtr, pa_mrc_ScanInformation_t, link); scanInformationListPtr->currentLink = linkPtr; le_mrc_ScanInformationSafeRef_t* newScanInformationPtr = le_mem_ForceAlloc(ScanInformationSafeRefPool); newScanInformationPtr->safeRef = le_ref_CreateRef(ScanInformationRefMap,nodePtr); newScanInformationPtr->link = LE_DLS_LINK_INIT; le_dls_Queue(&(scanInformationListPtr->safeRefScanInformationList),&(newScanInformationPtr->link)); return (le_mrc_ScanInformation_Ref_t)newScanInformationPtr->safeRef; } else { return NULL; } }
/** レディーキューから動作可能なスレッドを取得する @param[in] rdq レディーキュー @retval NULL レディーキューが空だった @retval スレッド管理情報のアドレス レディーキュー中の実行可能スレッド */ thread_t * rdq_find_runnable_thread(void){ psw_t psw; thread_t *thr; int idx, rc; thread_ready_queue_t *rdq = &rd_queue; psw_disable_and_save_interrupt(&psw); rc = find_msr_bit(rdq->bitmap, &idx); if ( rc != 0 ) { thr = NULL; goto out; } kassert( !list_is_empty( &rdq->head[idx] ) ); thr = CONTAINER_OF( list_ref_top(&rdq->head[idx]), thread_t, link); out: psw_restore_interrupt(&psw); return thr; }
static ret_code_t block_dev_empty_write_req(nrf_block_dev_t const * p_blk_dev, nrf_block_req_t const * p_blk) { ASSERT(p_blk_dev); ASSERT(p_blk); nrf_block_dev_empty_t const * p_empty_dev = CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev); nrf_block_dev_empty_work_t * p_work = p_empty_dev->p_work; if (p_work->ev_handler) { /*Asynchronous operation (simulation)*/ const nrf_block_dev_event_t ev = { NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE, NRF_BLOCK_DEV_RESULT_SUCCESS, p_blk, p_work->p_context }; p_work->ev_handler(p_blk_dev, &ev); } return NRF_SUCCESS; }
static void colo_disable_logdirty(libxl__colo_restore_state *crs, libxl__egc *egc) { libxl__domain_create_state *dcs = CONTAINER_OF(crs, *dcs, crs); libxl__colo_restore_checkpoint_state *crcs = crs->crcs; /* Convenience aliases */ const uint32_t domid = crs->domid; libxl__logdirty_switch *const lds = &crcs->lds; EGC_GC; /* we need to know which pages are dirty to restore the guest */ if (xc_shadow_control(CTX->xch, domid, XEN_DOMCTL_SHADOW_OP_OFF, NULL, 0, NULL, 0, NULL) < 0) LOGD(WARN, domid, "cannot disable secondary vm's logdirty"); if (crs->hvm) { libxl__domain_common_switch_qemu_logdirty(egc, domid, 0, lds); return; } lds->callback(egc, lds, 0); }
static void colo_suspend_primary_vm_done(libxl__egc *egc, libxl__domain_suspend_state *dsps, int rc) { libxl__domain_save_state *dss = CONTAINER_OF(dsps, *dss, dsps); EGC_GC; if (rc) { LOGD(ERROR, dss->domid, "cannot suspend primary vm"); goto out; } /* Convenience aliases */ libxl__checkpoint_devices_state *const cds = &dss->cds; cds->callback = colo_postsuspend_cb; libxl__checkpoint_devices_postsuspend(egc, cds); return; out: dss->rc = rc; libxl__xc_domain_saverestore_async_callback_done(egc, &dss->sws.shs, !rc); }
//-------------------------------------------------------------------------------------------------- void le_sig_SetEventHandler ( int sigNum, ///< The signal to set the event handler for. See /// parameter documentation in comments above. le_sig_EventHandlerFunc_t sigEventHandler ///< The event handler to call when a signal is /// received. ) { // Check parameters. if ( (sigNum == SIGKILL) || (sigNum == SIGSTOP) || (sigNum == SIGFPE) || (sigNum == SIGILL) || (sigNum == SIGSEGV) || (sigNum == SIGBUS) || (sigNum == SIGABRT) || (sigNum == SIGIOT) || (sigNum == SIGTRAP) || (sigNum == SIGSYS) ) { LE_FATAL("Signal event handler for %s is not allowed.", strsignal(sigNum)); } // Get the monitor object for this thread. MonitorObj_t* monitorObjPtr = pthread_getspecific(SigMonKey); if (monitorObjPtr == NULL) { if (sigEventHandler == NULL) { // Event handler already does not exist so we don't need to do anything, just return. return; } else { // Create the monitor object monitorObjPtr = le_mem_ForceAlloc(MonitorObjPool); monitorObjPtr->handlerObjList = LE_DLS_LIST_INIT; monitorObjPtr->fd = -1; monitorObjPtr->monitorRef = NULL; // Add it to the thread's local data. LE_ASSERT(pthread_setspecific(SigMonKey, monitorObjPtr) == 0); } } // See if a handler for this signal already exists. HandlerObj_t* handlerObjPtr = FindHandlerObj(sigNum, &(monitorObjPtr->handlerObjList)); if (handlerObjPtr == NULL) { if (sigEventHandler == NULL) { // Event handler already does not exist so we don't need to do anything, just return. return; } else { // Create the handler object. handlerObjPtr = le_mem_ForceAlloc(HandlerObjPool); // Set the handler. handlerObjPtr->link = LE_DLS_LINK_INIT; handlerObjPtr->handler = sigEventHandler; handlerObjPtr->sigNum = sigNum; // Add the handler object to the list. le_dls_Queue(&(monitorObjPtr->handlerObjList), &(handlerObjPtr->link)); } } else { if (sigEventHandler == NULL) { // Remove the handler object from the list. le_dls_Remove(&(monitorObjPtr->handlerObjList), &(handlerObjPtr->link)); } else { // Just update the handler. handlerObjPtr->handler = sigEventHandler; } } // Recreate the signal mask. sigset_t sigSet; LE_ASSERT(sigemptyset(&sigSet) == 0); le_dls_Link_t* handlerLinkPtr = le_dls_Peek(&(monitorObjPtr->handlerObjList)); while (handlerLinkPtr != NULL) { HandlerObj_t* handlerObjPtr = CONTAINER_OF(handlerLinkPtr, HandlerObj_t, link); LE_ASSERT(sigaddset(&sigSet, handlerObjPtr->sigNum) == 0); handlerLinkPtr = le_dls_PeekNext(&(monitorObjPtr->handlerObjList), handlerLinkPtr); } // Update or create the signal fd. monitorObjPtr->fd = signalfd(monitorObjPtr->fd, &sigSet, SFD_NONBLOCK); if (monitorObjPtr->fd == -1) { LE_FATAL("Could not set signal event handler: %m"); } // Create a monitor fd if it doesn't already exist. if (monitorObjPtr->monitorRef == NULL) { // Create the monitor name using SIG_STR + thread name. char monitorName[LIMIT_MAX_THREAD_NAME_BYTES + sizeof(SIG_STR)] = SIG_STR; LE_ASSERT(le_utf8_Copy(monitorName + sizeof(SIG_STR), le_thread_GetMyName(), LIMIT_MAX_THREAD_NAME_BYTES + sizeof(SIG_STR), NULL) == LE_OK); // Create the monitor. monitorObjPtr->monitorRef = le_fdMonitor_Create(monitorName, monitorObjPtr->fd, OurSigHandler, POLLIN); } }
/* * In return, the script writes the name of REMUS_IFB device (during setup) * to be used for output buffering into XENBUS_PATH/ifb */ static void netbuf_setup_script_cb(libxl__egc *egc, libxl__async_exec_state *aes, int rc, int status) { libxl__ao_device *aodev = CONTAINER_OF(aes, *aodev, aes); libxl__checkpoint_device *dev = CONTAINER_OF(aodev, *dev, aodev); libxl__remus_device_nic *remus_nic = dev->concrete_data; libxl__checkpoint_devices_state *cds = dev->cds; libxl__remus_state *rs = cds->concrete_data; const char *out_path_base, *hotplug_error = NULL; STATE_AO_GC(cds->ao); /* Convenience aliases */ const uint32_t domid = cds->domid; const int devid = remus_nic->devid; const char *const vif = remus_nic->vif; const char **const ifb = &remus_nic->ifb; if (status && !rc) rc = ERROR_FAIL; if (rc) goto out; /* * we need to get ifb first because it's needed for teardown */ rc = libxl__xs_read_checked(gc, XBT_NULL, GCSPRINTF("%s/remus/netbuf/%d/ifb", libxl__xs_libxl_path(gc, domid), devid), ifb); if (rc) goto out; if (!(*ifb)) { LOGD(ERROR, domid, "Cannot get ifb dev name for domain %u dev %s", domid, vif); rc = ERROR_FAIL; goto out; } out_path_base = GCSPRINTF("%s/remus/netbuf/%d", libxl__xs_libxl_path(gc, domid), devid); rc = libxl__xs_read_checked(gc, XBT_NULL, GCSPRINTF("%s/hotplug-error", out_path_base), &hotplug_error); if (rc) goto out; if (hotplug_error) { LOGD(ERROR, domid, "netbuf script %s setup failed for vif %s: %s", rs->netbufscript, vif, hotplug_error); rc = ERROR_FAIL; goto out; } if (status) { rc = ERROR_FAIL; goto out; } LOGD(DEBUG, domid, "%s will buffer packets from vif %s", *ifb, vif); rc = init_qdisc(cds, remus_nic); out: aodev->rc = rc; aodev->callback(egc, aodev); }
static void bootloader_display_copyfail(libxl__egc *egc, libxl__datacopier_state *dc, int onwrite, int errnoval) { libxl__bootloader_state *bl = CONTAINER_OF(dc, *bl, display); bootloader_copyfail(egc, "bootloader output", bl, 1, onwrite, errnoval); }
static void bootloader_gotptys(libxl__egc *egc, libxl__openpty_state *op) { libxl__bootloader_state *bl = CONTAINER_OF(op, *bl, openpty); STATE_AO_GC(bl->ao); int rc, r; char *const env[] = { "TERM", "vt100", NULL }; if (bl->openpty.rc) { rc = bl->openpty.rc; goto out; } /* * We need to present the bootloader's tty as a pty slave that xenconsole * can access. Since the bootloader itself needs a pty slave, * we end up with a connection like this: * * xenconsole -- (slave pty1 master) <-> (master pty2 slave) -- bootloader * * where we copy characters between the two master fds, as well as * listening on the bootloader's fifo for the results. */ char *dom_console_xs_path; char dom_console_slave_tty_path[PATH_MAX]; rc = setup_xenconsoled_pty(egc, bl, &dom_console_slave_tty_path[0], sizeof(dom_console_slave_tty_path)); if (rc) goto out; char *dompath = libxl__xs_get_dompath(gc, bl->domid); if (!dompath) { rc = ERROR_FAIL; goto out; } dom_console_xs_path = GCSPRINTF("%s/console/tty", dompath); rc = libxl__xs_write(gc, XBT_NULL, dom_console_xs_path, "%s", dom_console_slave_tty_path); if (rc) { LOGE(ERROR,"xs write console path %s := %s failed", dom_console_xs_path, dom_console_slave_tty_path); rc = ERROR_FAIL; goto out; } bl->deathcheck.what = "stopping bootloader"; bl->deathcheck.domid = bl->domid; bl->deathcheck.callback = bootloader_domaindeath; rc = libxl__domaindeathcheck_start(gc, &bl->deathcheck); if (rc) goto out; if (bl->console_available) bl->console_available(egc, bl); int bootloader_master = libxl__carefd_fd(bl->ptys[0].master); int xenconsole_master = libxl__carefd_fd(bl->ptys[1].master); libxl_fd_set_nonblock(CTX, bootloader_master, 1); libxl_fd_set_nonblock(CTX, xenconsole_master, 1); bl->keystrokes.writefd = bl->display.readfd = bootloader_master; bl->keystrokes.writewhat = bl->display.readwhat = "bootloader pty"; bl->keystrokes.readfd = bl->display.writefd = xenconsole_master; bl->keystrokes.readwhat = bl->display.writewhat = "xenconsole client pty"; bl->keystrokes.ao = ao; bl->keystrokes.maxsz = BOOTLOADER_BUF_OUT; bl->keystrokes.copywhat = GCSPRINTF("bootloader input for domain %"PRIu32, bl->domid); bl->keystrokes.callback = bootloader_keystrokes_copyfail; bl->keystrokes.callback_pollhup = bootloader_keystrokes_copyfail; /* pollhup gets called with errnoval==-1 which is not otherwise * possible since errnos are nonnegative, so it's unambiguous */ rc = libxl__datacopier_start(&bl->keystrokes); if (rc) goto out; bl->display.ao = ao; bl->display.maxsz = BOOTLOADER_BUF_IN; bl->display.copywhat = GCSPRINTF("bootloader output for domain %"PRIu32, bl->domid); bl->display.callback = bootloader_display_copyfail; bl->display.callback_pollhup = bootloader_display_copyfail; rc = libxl__datacopier_start(&bl->display); if (rc) goto out; LOG(DEBUG, "executing bootloader: %s", bl->args[0]); for (const char **blarg = bl->args; *blarg; blarg++) LOG(DEBUG, " bootloader arg: %s", *blarg); struct termios termattr; pid_t pid = libxl__ev_child_fork(gc, &bl->child, bootloader_finished); if (pid == -1) { rc = ERROR_FAIL; goto out; } if (!pid) { /* child */ r = login_tty(libxl__carefd_fd(bl->ptys[0].slave)); if (r) { LOGE(ERROR, "login_tty failed"); exit(-1); } libxl__exec(gc, -1, -1, -1, bl->args[0], (char **) bl->args, env); exit(-1); } /* parent */ /* * On Solaris, the master pty side does not have terminal semantics, * so don't try to set any attributes, as it will fail. */ #if !defined(__sun__) tcgetattr(bootloader_master, &termattr); cfmakeraw(&termattr); tcsetattr(bootloader_master, TCSANOW, &termattr); #endif return; out: bootloader_callback(egc, bl, rc); }
static void spawn_stub_launch_dm(libxl__egc *egc, libxl__multidev *multidev, int ret) { libxl__stub_dm_spawn_state *sdss = CONTAINER_OF(multidev, *sdss, multidev); STATE_AO_GC(sdss->dm.spawn.ao); libxl_ctx *ctx = libxl__gc_owner(gc); int i, num_console = STUBDOM_SPECIAL_CONSOLES; libxl__device_console *console; /* convenience aliases */ libxl_domain_config *const dm_config = &sdss->dm_config; libxl_domain_config *const guest_config = sdss->dm.guest_config; const int guest_domid = sdss->dm.guest_domid; libxl__domain_build_state *const d_state = sdss->dm.build_state; libxl__domain_build_state *const stubdom_state = &sdss->dm_state; uint32_t dm_domid = sdss->pvqemu.guest_domid; if (ret) { LOG(ERROR, "error connecting disk devices"); goto out; } for (i = 0; i < dm_config->num_nics; i++) { /* We have to init the nic here, because we still haven't * called libxl_device_nic_add at this point, but qemu needs * the nic information to be complete. */ ret = libxl__device_nic_setdefault(gc, &dm_config->nics[i], dm_domid); if (ret) goto out; } ret = libxl__device_vfb_add(gc, dm_domid, &dm_config->vfbs[0]); if (ret) goto out; ret = libxl__device_vkb_add(gc, dm_domid, &dm_config->vkbs[0]); if (ret) goto out; if (guest_config->b_info.u.hvm.serial) num_console++; console = libxl__calloc(gc, num_console, sizeof(libxl__device_console)); if (!console) { ret = ERROR_NOMEM; goto out; } for (i = 0; i < num_console; i++) { console[i].devid = i; console[i].consback = LIBXL__CONSOLE_BACKEND_IOEMU; /* STUBDOM_CONSOLE_LOGGING (console 0) is for minios logging * STUBDOM_CONSOLE_SAVE (console 1) is for writing the save file * STUBDOM_CONSOLE_RESTORE (console 2) is for reading the save file */ switch (i) { char *filename; char *name; case STUBDOM_CONSOLE_LOGGING: name = libxl__sprintf(gc, "qemu-dm-%s", libxl_domid_to_name(ctx, guest_domid)); libxl_create_logfile(ctx, name, &filename); console[i].output = libxl__sprintf(gc, "file:%s", filename); free(filename); break; case STUBDOM_CONSOLE_SAVE: console[i].output = libxl__sprintf(gc, "file:%s", libxl__device_model_savefile(gc, guest_domid)); break; case STUBDOM_CONSOLE_RESTORE: if (d_state->saved_state) console[i].output = libxl__sprintf(gc, "pipe:%s", d_state->saved_state); break; default: console[i].output = "pty"; break; } ret = libxl__device_console_add(gc, dm_domid, &console[i], i == STUBDOM_CONSOLE_LOGGING ? stubdom_state : NULL); if (ret) goto out; } sdss->pvqemu.spawn.ao = ao; sdss->pvqemu.guest_domid = dm_domid; sdss->pvqemu.guest_config = &sdss->dm_config; sdss->pvqemu.build_state = &sdss->dm_state; sdss->pvqemu.callback = spawn_stubdom_pvqemu_cb; libxl__spawn_local_dm(egc, &sdss->pvqemu); return; out: assert(ret); spawn_stubdom_pvqemu_cb(egc, &sdss->pvqemu, ret); }
static void device_model_startup_failed(libxl__egc *egc, libxl__spawn_state *spawn) { libxl__dm_spawn_state *dmss = CONTAINER_OF(spawn, *dmss, spawn); device_model_spawn_outcome(egc, dmss, ERROR_FAIL); }
int configure_rtr(cfg_t *cfg) { lisp_xtr_t *xtr; shash_t *lcaf_ht; mapping_t *mapping; map_local_entry_t *map_loc_e; void *fwd_map_inf; int n,i; /* CREATE AND CONFIGURE RTR (xTR in fact) */ if (ctrl_dev_create(RTR_MODE, &ctrl_dev) != GOOD) { OOR_LOG(LCRIT, "Failed to create RTR. Aborting!"); return (BAD); } lcaf_ht = parse_lcafs(cfg); xtr = CONTAINER_OF(ctrl_dev, lisp_xtr_t, super); if (configure_tunnel_router(cfg, xtr, lcaf_ht)!=GOOD){ return (BAD); } /* INTERFACES CONFIG */ n = cfg_size(cfg, "rtr-ifaces"); if (n) { cfg_t *rifs = cfg_getsec(cfg, "rtr-ifaces"); int nr = cfg_size(rifs, "rtr-iface"); for(i = 0; i < nr; i++) { cfg_t *ri = cfg_getnsec(rifs, "rtr-iface", i); if (add_rtr_iface(xtr, cfg_getstr(ri, "iface"), cfg_getint(ri, "ip_version"), cfg_getint(ri, "priority"), cfg_getint(ri, "weight")) == GOOD) { OOR_LOG(LDBG_1, "Configured interface %s for RTR", cfg_getstr(ri, "iface")); } else{ OOR_LOG(LERR, "Can't configure iface %s for RTR", cfg_getstr(ri, "iface")); } } } /* RTR DATABASE MAPPINGS (like for instance replication lists) */ n = cfg_size(cfg, "rtr-database-mapping"); for (i = 0; i < n; i++) { mapping = parse_mapping(cfg_getnsec(cfg, "rtr-database-mapping",i),&(xtr->super),lcaf_ht,TRUE); if (mapping == NULL){ continue; } map_loc_e = map_local_entry_new_init(mapping); if (map_loc_e == NULL){ mapping_del(mapping); continue; } fwd_map_inf = xtr->fwd_policy->new_map_loc_policy_inf(xtr->fwd_policy_dev_parm,mapping,NULL); if (fwd_map_inf == NULL){ OOR_LOG(LERR, "Couldn't create forward information for rtr database mapping with EID: %s. Discarding it...", lisp_addr_to_char(mapping_eid(mapping))); map_local_entry_del(map_loc_e); continue; } map_local_entry_set_fwd_info(map_loc_e, fwd_map_inf, xtr->fwd_policy->del_map_loc_policy_inf); if (add_local_db_map_local_entry(map_loc_e,xtr) != GOOD){ map_local_entry_del(map_loc_e); continue; } if (add_local_db_map_local_entry(map_loc_e,xtr) != GOOD){ map_local_entry_del(map_loc_e); } } /* Deallocate PiTRs and PeTRs elements */ glist_destroy(xtr->pitrs); xtr->pitrs = NULL; shash_destroy(lcaf_ht); return(GOOD); }
/* Bind a server to each address that getaddrinfo() reported. */ static void do_bind(uv_getaddrinfo_t *req, int status, struct addrinfo *addrs) { char addrbuf[INET6_ADDRSTRLEN + 1]; unsigned int ipv4_naddrs; unsigned int ipv6_naddrs; server_state *state; server_config *cf; struct addrinfo *ai; const void *addrv; const char *what; uv_loop_t *loop; server_ctx *sx; unsigned int n; int err; union { struct sockaddr addr; struct sockaddr_in addr4; struct sockaddr_in6 addr6; } s; state = CONTAINER_OF(req, server_state, getaddrinfo_req); loop = state->loop; cf = &state->config; if (status < 0) { pr_err("getaddrinfo(\"%s\"): %s", cf->bind_host, uv_strerror(status)); uv_freeaddrinfo(addrs); return; } ipv4_naddrs = 0; ipv6_naddrs = 0; for (ai = addrs; ai != NULL; ai = ai->ai_next) { if (ai->ai_family == AF_INET) { ipv4_naddrs += 1; } else if (ai->ai_family == AF_INET6) { ipv6_naddrs += 1; } } if (ipv4_naddrs == 0 && ipv6_naddrs == 0) { pr_err("%s has no IPv4/6 addresses", cf->bind_host); uv_freeaddrinfo(addrs); return; } state->servers = xmalloc((ipv4_naddrs + ipv6_naddrs) * sizeof(state->servers[0])); n = 0; for (ai = addrs; ai != NULL; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) { continue; } if (ai->ai_family == AF_INET) { s.addr4 = *(const struct sockaddr_in *) ai->ai_addr; s.addr4.sin_port = htons(cf->bind_port); addrv = &s.addr4.sin_addr; } else if (ai->ai_family == AF_INET6) { s.addr6 = *(const struct sockaddr_in6 *) ai->ai_addr; s.addr6.sin6_port = htons(cf->bind_port); addrv = &s.addr6.sin6_addr; } else { UNREACHABLE(); } if (uv_inet_ntop(s.addr.sa_family, addrv, addrbuf, sizeof(addrbuf))) { UNREACHABLE(); } sx = state->servers + n; sx->loop = loop; sx->idle_timeout = state->config.idle_timeout; CHECK(0 == uv_tcp_init(loop, &sx->tcp_handle)); what = "uv_tcp_bind"; err = uv_tcp_bind(&sx->tcp_handle, &s.addr, 0); if (err == 0) { what = "uv_listen"; err = uv_listen((uv_stream_t *) &sx->tcp_handle, 128, on_connection); } if (err != 0) { pr_err("%s(\"%s:%hu\"): %s", what, addrbuf, cf->bind_port, uv_strerror(err)); while (n > 0) { n -= 1; uv_close((uv_handle_t *) (state->servers + n), NULL); } break; } pr_info("listening on %s:%hu", addrbuf, cf->bind_port); n += 1; } uv_freeaddrinfo(addrs); }
int main(int argc, char **argv) { oor_dev_type_e dev_type; lisp_xtr_t *tunnel_router; initial_setup(); handle_oor_command_line(argc, argv); /* see if we need to daemonize, and if so, do it */ demonize_start(); /* create socket master, timer wheel, initialize interfaces */ smaster = sockmstr_create(); oor_timers_init(); ifaces_init(); /* create control. Only one instance for now */ if ((lctrl = ctrl_create())==NULL){ exit_cleanup(); } /* Detect the data plane type */ data_plane_select(); /* parse config and create ctrl_dev */ if (parse_config_file() != GOOD){ exit_cleanup(); } dev_type = ctrl_dev_mode(ctrl_dev); if (dev_type == xTR_MODE || dev_type == RTR_MODE || dev_type == MN_MODE) { OOR_LOG(LDBG_2, "Configuring data plane"); tunnel_router = CONTAINER_OF(ctrl_dev, lisp_xtr_t, super); if (data_plane->datap_init(dev_type,tr_get_encap_type(tunnel_router))!=GOOD){ exit_cleanup(); } OOR_LOG(LDBG_1, "Data plane initialized"); } /* The control should be initialized after data plane */ ctrl_init(lctrl); init_netlink(); /* run lisp control device xtr/ms */ if (!ctrl_dev) { OOR_LOG(LDBG_1, "device NULL"); exit(0); } ctrl_dev_run(ctrl_dev); OOR_LOG(LINF,"\n\n Open Overlay Router (%s): started... \n\n",OOR_VERSION); #ifndef ANDROID /* Initialize API for external access */ oor_api_init_server(&oor_api_connection); for (;;) { sockmstr_wait_on_all_read(smaster); sockmstr_process_all(smaster); oor_api_loop(&oor_api_connection); } #else for (;;) { sockmstr_wait_on_all_read(smaster); sockmstr_process_all(smaster); } #endif /* event_loop returned: bad! */ OOR_LOG(LINF, "Exiting..."); exit_cleanup(); return(0); }
static inline block_device_t *bdev_get(LinkedList *_ptr) { return CONTAINER_OF(block_device_t, list_ptr, _ptr); }
static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev, int ret) { libxl__domain_create_state *dcs = CONTAINER_OF(multidev, *dcs, multidev); STATE_AO_GC(dcs->ao); int i; /* convenience aliases */ const uint32_t domid = dcs->guest_domid; libxl_domain_config *const d_config = dcs->guest_config; libxl__domain_build_state *const state = &dcs->build_state; if (ret) { LOG(ERROR, "unable to add disk devices"); goto error_out; } for (i = 0; i < d_config->b_info.num_ioports; i++) { libxl_ioport_range *io = &d_config->b_info.ioports[i]; LOG(DEBUG, "dom%d ioports %"PRIx32"-%"PRIx32, domid, io->first, io->first + io->number - 1); ret = xc_domain_ioport_permission(CTX->xch, domid, io->first, io->number, 1); if ( ret<0 ){ LOGE(ERROR, "failed give dom%d access to ioports %"PRIx32"-%"PRIx32, domid, io->first, io->first + io->number - 1); ret = ERROR_FAIL; } } for (i = 0; i < d_config->b_info.num_irqs; i++) { uint32_t irq = d_config->b_info.irqs[i]; LOG(DEBUG, "dom%d irq %"PRIx32, domid, irq); ret = xc_domain_irq_permission(CTX->xch, domid, irq, 1); if ( ret<0 ){ LOGE(ERROR, "failed give dom%d access to irq %"PRId32, domid, irq); ret = ERROR_FAIL; } } for (i = 0; i < d_config->num_nics; i++) { /* We have to init the nic here, because we still haven't * called libxl_device_nic_add at this point, but qemu needs * the nic information to be complete. */ ret = libxl__device_nic_setdefault(gc, &d_config->nics[i], domid); if (ret) goto error_out; } switch (d_config->c_info.type) { case LIBXL_DOMAIN_TYPE_HVM: { libxl__device_console console; libxl_device_vkb vkb; ret = init_console_info(&console, 0); if ( ret ) goto error_out; libxl__device_console_add(gc, domid, &console, state); libxl__device_console_dispose(&console); libxl_device_vkb_init(&vkb); libxl__device_vkb_add(gc, domid, &vkb); libxl_device_vkb_dispose(&vkb); dcs->dmss.dm.guest_domid = domid; if (libxl_defbool_val(d_config->b_info.device_model_stubdomain)) libxl__spawn_stub_dm(egc, &dcs->dmss); else libxl__spawn_local_dm(egc, &dcs->dmss.dm); return; } case LIBXL_DOMAIN_TYPE_PV: { int need_qemu = 0; libxl__device_console console; for (i = 0; i < d_config->num_vfbs; i++) { libxl__device_vfb_add(gc, domid, &d_config->vfbs[i]); libxl__device_vkb_add(gc, domid, &d_config->vkbs[i]); } ret = init_console_info(&console, 0); if ( ret ) goto error_out; need_qemu = libxl__need_xenpv_qemu(gc, 1, &console, d_config->num_vfbs, d_config->vfbs, d_config->num_disks, &d_config->disks[0]); libxl__device_console_add(gc, domid, &console, state); libxl__device_console_dispose(&console); if (need_qemu) { dcs->dmss.dm.guest_domid = domid; libxl__spawn_local_dm(egc, &dcs->dmss.dm); return; } else { assert(!dcs->dmss.dm.guest_domid); domcreate_devmodel_started(egc, &dcs->dmss.dm, 0); return; } } default: ret = ERROR_INVAL; goto error_out; } abort(); /* not reached */ error_out: assert(ret); domcreate_complete(egc, dcs, ret); }
static void domcreate_bootloader_done(libxl__egc *egc, libxl__bootloader_state *bl, int rc) { libxl__domain_create_state *dcs = CONTAINER_OF(bl, *dcs, bl); STATE_AO_GC(bl->ao); /* convenience aliases */ const uint32_t domid = dcs->guest_domid; libxl_domain_config *const d_config = dcs->guest_config; libxl_domain_build_info *const info = &d_config->b_info; const int restore_fd = dcs->restore_fd; libxl__domain_build_state *const state = &dcs->build_state; libxl__srm_restore_autogen_callbacks *const callbacks = &dcs->shs.callbacks.restore.a; if (rc) { domcreate_rebuild_done(egc, dcs, rc); return; } /* consume bootloader outputs. state->pv_{kernel,ramdisk} have * been initialised by the bootloader already. */ state->pv_cmdline = bl->cmdline; /* We might be going to call libxl__spawn_local_dm, or _spawn_stub_dm. * Fill in any field required by either, including both relevant * callbacks (_spawn_stub_dm will overwrite our trespass if needed). */ dcs->dmss.dm.spawn.ao = ao; dcs->dmss.dm.guest_config = dcs->guest_config; dcs->dmss.dm.build_state = &dcs->build_state; dcs->dmss.dm.callback = domcreate_devmodel_started; dcs->dmss.callback = domcreate_devmodel_started; if ( restore_fd < 0 ) { rc = libxl__domain_build(gc, &d_config->b_info, domid, state); domcreate_rebuild_done(egc, dcs, rc); return; } /* Restore */ rc = libxl__build_pre(gc, domid, info, state); if (rc) goto out; /* read signature */ int hvm, pae, superpages; switch (info->type) { case LIBXL_DOMAIN_TYPE_HVM: hvm = 1; superpages = 1; pae = libxl_defbool_val(info->u.hvm.pae); callbacks->toolstack_restore = libxl__toolstack_restore; break; case LIBXL_DOMAIN_TYPE_PV: hvm = 0; superpages = 0; pae = 1; break; default: rc = ERROR_INVAL; goto out; } libxl__xc_domain_restore(egc, dcs, hvm, pae, superpages, 1); return; out: libxl__xc_domain_restore_done(egc, dcs, rc, 0, 0); }
//-------------------------------------------------------------------------------------------------- void fa_event_RunLoop ( void ) { event_PerThreadRec_t* perThreadRecPtr = thread_GetEventRecPtr(); int epollFd = CONTAINER_OF(perThreadRecPtr, event_LinuxPerThreadRec_t, portablePerThreadRec)->epollFd; struct epoll_event epollEventList[MAX_EPOLL_EVENTS]; // Make sure nobody calls this function more than once in the same thread. LE_ASSERT(perThreadRecPtr->state == LE_EVENT_LOOP_INITIALIZED); // Update the state of the Event Loop. perThreadRecPtr->state = LE_EVENT_LOOP_RUNNING; // Enter the infinite loop itself. for (;;) { // Wait for something to happen on one of the file descriptors that we are monitoring // using our epoll fd. int result = epoll_wait(epollFd, epollEventList, NUM_ARRAY_MEMBERS(epollEventList), -1); // If something happened on one or more of the monitored file descriptors, if (result > 0) { int i; // Check if someone has cancelled the thread and terminate the thread now, if so. pthread_testcancel(); // For each fd event reported by epoll_wait(), if it is any file descriptor other // than the eventfd (which is used to indicate that there is something on the // Event Queue), queue an Event Report to the Event Queue for that fd. for (i = 0; i < result; i++) { // Get the pointer that we registered with epoll_ctl(2) along with this fd. // The value of this pointer will either be NULL or a Safe Reference for an // FD Monitor object. If it is NULL, then the Event Queue's eventfd is the // fd that experienced the event. void* safeRef = epollEventList[i].data.ptr; if (safeRef != NULL) { fdMon_Report(safeRef, EPollToPoll(epollEventList[i].events)); } } // Process all the Event Reports on the Event Queue. event_ProcessEventReports(perThreadRecPtr); } // Otherwise, if an epoll_wait() reported an error, hopefully it's just an interruption // by a signal (EINTR). Anything else is a fatal error. else if (result < 0) { if (errno != EINTR) { LE_FATAL("epoll_wait() failed. errno = %d.", errno); } // It was just EINTR, so we are okay to go back to sleep. But first, // check if someone has cancelled the thread and terminate the thread now, if so. pthread_testcancel(); } // Otherwise, if epoll_wait() returned zero, something has gone horribly wrong, because // it should never return zero. else { LE_FATAL("epoll_wait() returned zero!"); } } }
//-------------------------------------------------------------------------------------------------- le_result_t le_event_ServiceLoop ( void ) { event_PerThreadRec_t* perThreadRecPtr = thread_GetEventRecPtr(); int epollFd = CONTAINER_OF(perThreadRecPtr, event_LinuxPerThreadRec_t, portablePerThreadRec)->epollFd; struct epoll_event epollEventList[MAX_EPOLL_EVENTS]; LE_DEBUG("perThreadRecPtr->liveEventCount is" "%" PRIu64, perThreadRecPtr->liveEventCount); // If there are still live events remaining in the queue, process a single event, then return if (perThreadRecPtr->liveEventCount > 0) { perThreadRecPtr->liveEventCount--; // This function assumes the mutex is NOT locked. event_ProcessOneEventReport(perThreadRecPtr); return LE_OK; } int result; do { // If no events on the queue, try to refill the event queue. // Ask epoll what, if anything, has happened on any of the file descriptors that we are // monitoring using our epoll fd. (NOTE: This is non-blocking.) result = epoll_wait(epollFd, epollEventList, NUM_ARRAY_MEMBERS(epollEventList), 0); if ((result < 0) && (EINTR == errno)) { // If epoll was interrupted, // Check if someone has cancelled the thread and terminate the thread now, if so. pthread_testcancel(); } } while ((result < 0) && (EINTR == errno)); // If something happened on one or more of the monitored file descriptors, if (result > 0) { int i; // Check if someone has cancelled the thread and terminate the thread now, if so. pthread_testcancel(); // For each fd event reported by epoll_wait(), if it is any file descriptor other // than the eventfd (which is used to indicate that there is something on the // Event Queue), queue an Event Report to the Event Queue for that fd. for (i = 0; i < result; i++) { // Get the pointer that we registered with epoll_ctl(2) along with this fd. // The value of this pointer will either be NULL or a Safe Reference for an // FD Monitor object. If it is NULL, then the Event Queue's eventfd is the // fd that experienced the event, which we will deal with later in this function. void* safeRef = epollEventList[i].data.ptr; if (safeRef != NULL) { fdMon_Report(safeRef, EPollToPoll(epollEventList[i].events)); } } } // Otherwise, check if an epoll_wait() reported an error. // Interruptions are tested above, so this is always a fatal error. else if (result < 0) { LE_FATAL("epoll_wait() failed. errno = %d.", errno); } // Otherwise, if epoll_wait() returned zero, then either this function was called without // waiting for the eventfd to be readable, or the eventfd was readable momentarily, but // something changed between the time the application code detected the readable condition // and now that made the eventfd not readable anymore. else { LE_DEBUG("epoll_wait() returned zero."); return LE_WOULD_BLOCK; } // Read the eventfd to reset it to zero so epoll stops telling us about it until more // are added. perThreadRecPtr->liveEventCount = fa_event_WaitForEvent(perThreadRecPtr); LE_DEBUG("perThreadRecPtr->liveEventCount is" "%" PRIu64, perThreadRecPtr->liveEventCount); // If events were read, process the top event if (perThreadRecPtr->liveEventCount > 0) { perThreadRecPtr->liveEventCount--; event_ProcessOneEventReport(perThreadRecPtr); return LE_OK; } else { return LE_WOULD_BLOCK; } }
static void process_request_work_cb(uv_work_t *req) { conn *incoming; Request r; Response resp; incoming = CONTAINER_OF(req, conn, work); client_ctx *cx = incoming->client; r.ParseFromArray(incoming->buf + 2, incoming->req_size); switch (r.type()) { case Request::CREATE_QUEUE: pr_info("CREATE_QUEUE"); { CreateQueueResponse *create = new CreateQueueResponse(); std::string queueid = cx->sx->qs->CreateQueue(r.createqueue().name()); create->set_queueid(queueid); resp.set_type(Response::CREATE_QUEUE); resp.set_allocated_createqueue(create); } break; case Request::GET_QUEUE: pr_info("GET_QUEUE"); { GetQueueResponse *get = new GetQueueResponse(); std::string queueid = cx->sx->qs->GetQueue(r.getqueue().name()); get->set_queueid(queueid); resp.set_type(Response::GET_QUEUE); resp.set_allocated_getqueue(get); } break; case Request::DEL_QUEUE: pr_info("DEL_QUEUE"); { DelQueueResponse *del = new DelQueueResponse(); cx->sx->qs->DeleteQueue(r.delqueue().queueid()); del->set_status(SUCCESS); resp.set_type(Response::DEL_QUEUE); resp.set_allocated_delqueue(del); } break; case Request::ENQUEUE: pr_info("ENQUEUE"); { EnqueueResponse *enqueue = new EnqueueResponse(); cx->sx->qs->enqueue(r.enqueue().queueid(), r.enqueue().data().c_str(), r.enqueue().data().length()); enqueue->set_status(SUCCESS); resp.set_type(Response::ENQUEUE); resp.set_allocated_enqueue(enqueue); } break; case Request::READ: pr_info("READ"); { ReadResponse *read = new ReadResponse(); *read = cx->sx->qs->read(r.read().queueid(), r.read().timeout()); resp.set_type(Response::READ); resp.set_allocated_read(read); } break; case Request::DEQUEUE: pr_info("DEQUEUE"); { DequeueResponse *dequeue = new DequeueResponse(); bool ret = cx->sx->qs->dequeue(r.dequeue().queueid(), r.dequeue().queueentitiyid()); dequeue->set_status(ret ? SUCCESS : NOTFOUND); resp.set_type(Response::DEQUEUE); resp.set_allocated_dequeue(dequeue); } break; } *((uint16_t *)(&incoming->resp_buf)) = htons(resp.ByteSize()); resp.SerializeToArray(&incoming->resp_buf[2], sizeof(incoming->resp_buf) - 2); incoming->resp_size = resp.ByteSize() + 2; }
static void device_model_detached(libxl__egc *egc, libxl__spawn_state *spawn) { libxl__dm_spawn_state *dmss = CONTAINER_OF(spawn, *dmss, spawn); device_model_spawn_outcome(egc, dmss, 0); }
int configure_ms(cfg_t *cfg) { char *iface_name; iface_t *iface; lisp_site_prefix_t *site; shash_t *lcaf_ht; int i; lisp_ms_t *ms; mapping_t *mapping; /* create and configure xtr */ if (ctrl_dev_create(MS_MODE, &ctrl_dev) != GOOD) { OOR_LOG(LCRIT, "Failed to create MS. Aborting!"); exit_cleanup(); } ms = CONTAINER_OF(ctrl_dev, lisp_ms_t, super); /* create lcaf hash table */ lcaf_ht = parse_lcafs(cfg); /* CONTROL INTERFACE */ /* TODO: should work with all interfaces in the future */ iface_name = cfg_getstr(cfg, "control-iface"); if (iface_name) { iface = add_interface(iface_name); if (iface == NULL) { return(BAD); } } if (iface_address(iface, AF_INET) == NULL){ iface_setup_addr(iface, AF_INET); data_plane->datap_add_iface_addr(iface,AF_INET); lctrl->control_data_plane->control_dp_add_iface_addr(lctrl,iface,AF_INET); } if (iface_address(iface, AF_INET6) == NULL){ iface_setup_addr(iface, AF_INET6); data_plane->datap_add_iface_addr(iface,AF_INET6); lctrl->control_data_plane->control_dp_add_iface_addr(lctrl,iface,AF_INET6); } /* LISP-SITE CONFIG */ for (i = 0; i < cfg_size(cfg, "lisp-site"); i++) { cfg_t *ls = cfg_getnsec(cfg, "lisp-site", i); site = build_lisp_site_prefix(ms, cfg_getstr(ls, "eid-prefix"), cfg_getint(ls, "iid"), cfg_getint(ls, "key-type"), cfg_getstr(ls, "key"), cfg_getbool(ls, "accept-more-specifics") ? 1:0, cfg_getbool(ls, "proxy-reply") ? 1:0, cfg_getbool(ls, "merge") ? 1 : 0, lcaf_ht); if (site != NULL) { if (mdb_lookup_entry(ms->lisp_sites_db, site->eid_prefix) != NULL){ OOR_LOG(LDBG_1, "Configuration file: Duplicated lisp-site: %s . Discarding...", lisp_addr_to_char(site->eid_prefix)); lisp_site_prefix_del(site); continue; } OOR_LOG(LDBG_1, "Adding lisp site prefix %s to the lisp-sites " "database", lisp_addr_to_char(site->eid_prefix)); ms_add_lisp_site_prefix(ms, site); }else{ OOR_LOG(LERR, "Can't add lisp-site prefix %s. Discarded ...", cfg_getstr(ls, "eid-prefix")); } } /* LISP REGISTERED SITES CONFIG */ for (i = 0; i< cfg_size(cfg, "ms-static-registered-site"); i++ ) { cfg_t *mss = cfg_getnsec(cfg, "ms-static-registered-site", i); mapping = parse_mapping(mss,&(ms->super),lcaf_ht,FALSE); if (mapping == NULL){ OOR_LOG(LERR, "Can't create static register site for %s", cfg_getstr(mss, "eid-prefix")); continue; } /* If the mapping doesn't exist, add it the the database */ if (mdb_lookup_entry_exact(ms->reg_sites_db, mapping_eid(mapping)) == NULL){ if (ms_add_registered_site_prefix(ms, mapping) == GOOD){ OOR_LOG(LDBG_1, "Added static registered site for %s to the registered sites list!", lisp_addr_to_char(mapping_eid(mapping))); }else{ OOR_LOG(LERR, "Failed to add static registered site for %s to the registered sites list!", lisp_addr_to_char(mapping_eid(mapping))); mapping_del(mapping); } }else{ OOR_LOG(LERR, "Configuration file: Duplicated static registered site for %s. Discarded ...", cfg_getstr(mss, "eid-prefix")); mapping_del(mapping); continue; } } /* destroy the hash table */ shash_destroy(lcaf_ht); return(GOOD); }
static void datacopier_readable(libxl__egc *egc, libxl__ev_fd *ev, int fd, short events, short revents) { libxl__datacopier_state *dc = CONTAINER_OF(ev, *dc, toread); STATE_AO_GC(dc->ao); if (datacopier_pollhup_handled(egc, dc, fd, revents, 0)) return; if (revents & ~(POLLIN|POLLHUP)) { LOG(ERROR, "unexpected poll event 0x%x on fd %d (expected POLLIN " "and/or POLLHUP) reading %s during copy of %s", revents, fd, dc->readwhat, dc->copywhat); datacopier_callback(egc, dc, ERROR_FAIL, -1, EIO); return; } assert(revents & (POLLIN|POLLHUP)); for (;;) { libxl__datacopier_buf *buf = NULL; int r; if (dc->readbuf) { r = read(ev->fd, dc->readbuf + dc->used, dc->bytes_to_read); } else { while (dc->used >= dc->maxsz) { libxl__datacopier_buf *rm = LIBXL_TAILQ_FIRST(&dc->bufs); dc->used -= rm->used; assert(dc->used >= 0); LIBXL_TAILQ_REMOVE(&dc->bufs, rm, entry); free(rm); } buf = LIBXL_TAILQ_LAST(&dc->bufs, libxl__datacopier_bufs); if (!buf || buf->used >= sizeof(buf->buf)) { buf = libxl__malloc(NOGC, sizeof(*buf)); buf->used = 0; LIBXL_TAILQ_INSERT_TAIL(&dc->bufs, buf, entry); } r = read(ev->fd, buf->buf + buf->used, min_t(size_t, sizeof(buf->buf) - buf->used, (dc->bytes_to_read == -1) ? SIZE_MAX : dc->bytes_to_read)); } if (r < 0) { if (errno == EINTR) continue; assert(errno); if (errno == EWOULDBLOCK) { if (revents & POLLHUP) { LOG(ERROR, "poll reported HUP but fd read gave EWOULDBLOCK" " on %s during copy of %s", dc->readwhat, dc->copywhat); datacopier_callback(egc, dc, ERROR_FAIL, -1, 0); return; } break; } LOGE(ERROR, "error reading %s during copy of %s", dc->readwhat, dc->copywhat); datacopier_callback(egc, dc, ERROR_FAIL, 0, errno); return; } if (r == 0) { if (dc->callback_pollhup) { /* It might be that this "eof" is actually a HUP. If * the caller cares about the difference, * double-check using poll(2). */ struct pollfd hupchk; hupchk.fd = ev->fd; hupchk.events = POLLIN; hupchk.revents = 0; r = poll(&hupchk, 1, 0); if (r < 0) LIBXL__EVENT_DISASTER(egc, "unexpected failure polling fd for datacopier eof hup check", errno, 0); if (datacopier_pollhup_handled(egc, dc, fd, hupchk.revents, 0)) return; } libxl__ev_fd_deregister(gc, &dc->toread); break; } if (dc->log) { int wrote = fwrite(buf->buf + buf->used, 1, r, dc->log); if (wrote != r) { assert(ferror(dc->log)); assert(errno); LOGE(ERROR, "error logging %s", dc->copywhat); datacopier_callback(egc, dc, ERROR_FAIL, 0, errno); return; } } if (!dc->readbuf) { buf->used += r; assert(buf->used <= sizeof(buf->buf)); } dc->used += r; if (dc->bytes_to_read > 0) dc->bytes_to_read -= r; if (dc->bytes_to_read == 0) break; } datacopier_check_state(egc, dc); }
static inline device_t *device_get(LinkedList *_ptr) { return CONTAINER_OF(device_t, list_ptr, _ptr); }
static void bootloader_keystrokes_copyfail(libxl__egc *egc, libxl__datacopier_state *dc, int onwrite, int errnoval) { libxl__bootloader_state *bl = CONTAINER_OF(dc, *bl, keystrokes); bootloader_copyfail(egc, "bootloader input", bl, 0, onwrite, errnoval); }
void libxl__colo_restore_setup(libxl__egc *egc, libxl__colo_restore_state *crs) { libxl__domain_create_state *dcs = CONTAINER_OF(crs, *dcs, crs); libxl__colo_restore_checkpoint_state *crcs; int rc = ERROR_FAIL; /* Convenience aliases */ libxl__srm_restore_autogen_callbacks *const callbacks = &dcs->srs.shs.callbacks.restore.a; const int domid = crs->domid; STATE_AO_GC(crs->ao); GCNEW(crcs); crs->crcs = crcs; crcs->crs = crs; crs->qdisk_setuped = false; crs->qdisk_used = false; if (dcs->colo_proxy_script) crs->colo_proxy_script = libxl__strdup(gc, dcs->colo_proxy_script); else crs->colo_proxy_script = GCSPRINTF("%s/colo-proxy-setup", libxl__xen_script_dir_path()); /* setup dsps */ crcs->dsps.ao = ao; crcs->dsps.domid = domid; if (init_dsps(&crcs->dsps)) goto out; callbacks->postcopy = libxl__colo_restore_domain_resume_callback; callbacks->wait_checkpoint = libxl__colo_restore_domain_wait_checkpoint_callback; callbacks->suspend = libxl__colo_restore_domain_suspend_callback; callbacks->checkpoint = libxl__colo_restore_domain_checkpoint_callback; /* * Secondary vm is running in colo mode, so we need to call * libxl__xc_domain_restore_done() to create secondary vm. * But we will exit in domain_create_cb(). So replace the * callback here. */ crs->saved_cb = dcs->callback; dcs->callback = libxl__colo_domain_create_cb; crcs->state_file = GCSPRINTF(LIBXL_DEVICE_MODEL_RESTORE_FILE".%d", domid); crcs->status = LIBXL_COLO_SETUPED; libxl__logdirty_init(&crcs->lds); crcs->lds.ao = ao; crcs->sws.fd = crs->send_back_fd; crcs->sws.ao = ao; crcs->sws.back_channel = true; dcs->cds.concrete_data = crs; libxl__stream_write_start(egc, &crcs->sws); rc = 0; out: crs->callback(egc, crs, rc); return; }
static void bootloader_domaindeath(libxl__egc *egc, libxl__domaindeathcheck *dc) { libxl__bootloader_state *bl = CONTAINER_OF(dc, *bl, deathcheck); bootloader_stop(egc, bl, ERROR_FAIL); }
//-------------------------------------------------------------------------------------------------- void le_mem_Release ( void* objPtr ///< [IN] Pointer to the object to be released. ) { MemBlock_t* blockPtr; // Get the block from the object pointer. #ifdef USE_GUARD_BAND uint8_t* dataPtr = objPtr; dataPtr -= GUARD_BAND_SIZE; blockPtr = CONTAINER_OF(dataPtr, MemBlock_t, data); #else blockPtr = CONTAINER_OF(objPtr, MemBlock_t, data); #endif #ifdef USE_GUARD_BAND CheckGuardBands(blockPtr); #endif Lock(); switch (blockPtr->refCount) { case 1: { MemPool_t* poolPtr = blockPtr->poolPtr; // The reference count has reached zero. blockPtr->refCount = 0; // Call the destructor, if there is one. if (poolPtr->destructor) { // Make sure that the destructor is not called with the mutex locked, because // it is not a recursive mutex and therefore will deadlock if locked again by // the same thread. Also, fetch the destructor function address before unlocking // the mutex so that we don't touch the pool object while the mutex is unlocked. le_mem_Destructor_t destructor = poolPtr->destructor; Unlock(); destructor(objPtr); // Re-lock the mutex now so that it is safe to access the pool object again. Lock(); } #ifndef LE_MEM_VALGRIND // Release the memory back into the pool. // Note that we don't do this before calling the destructor because the destructor // still needs to access it, but after it goes back on the free list, it could get // reallocated by another thread (or even the destructor itself) and have its // contents clobbered. le_sls_Stack(&(poolPtr->freeList), &(blockPtr->link)); #else free(blockPtr); #endif poolPtr->numBlocksInUse--; break; } case 0: LE_EMERG("Releasing free block."); LE_FATAL("Free block released from pool %p (%s).", blockPtr->poolPtr, blockPtr->poolPtr->name); default: blockPtr->refCount--; } Unlock(); }