void libxl__remus_devices_setup(libxl__egc *egc, libxl__remus_devices_state *rds) { int i, rc; STATE_AO_GC(rds->ao); rc = init_device_subkind(rds); if (rc) goto out; rds->num_devices = 0; rds->num_nics = 0; rds->num_disks = 0; if (rds->device_kind_flags & (1 << LIBXL__DEVICE_KIND_VIF)) rds->nics = libxl_device_nic_list(CTX, rds->domid, &rds->num_nics); if (rds->device_kind_flags & (1 << LIBXL__DEVICE_KIND_VBD)) rds->disks = libxl_device_disk_list(CTX, rds->domid, &rds->num_disks); if (rds->num_nics == 0 && rds->num_disks == 0) goto out; GCNEW_ARRAY(rds->devs, rds->num_nics + rds->num_disks); for (i = 0; i < rds->num_nics; i++) { rds->devs[rds->num_devices++] = remus_device_init(egc, rds, LIBXL__DEVICE_KIND_VIF, &rds->nics[i]); } for (i = 0; i < rds->num_disks; i++) { rds->devs[rds->num_devices++] = remus_device_init(egc, rds, LIBXL__DEVICE_KIND_VBD, &rds->disks[i]); } remus_devices_setup(egc, rds); return; out: rds->callback(egc, rds, rc); }
void libxl__colo_save_setup(libxl__egc *egc, libxl__colo_save_state *css) { libxl__domain_save_state *dss = CONTAINER_OF(css, *dss, css); /* Convenience aliases */ libxl__checkpoint_devices_state *const cds = &dss->cds; libxl__srm_save_autogen_callbacks *const callbacks = &dss->sws.shs.callbacks.save.a; STATE_AO_GC(dss->ao); if (dss->type != LIBXL_DOMAIN_TYPE_HVM) { LOGD(ERROR, dss->domid, "COLO only supports hvm now"); goto out; } css->send_fd = dss->fd; css->recv_fd = dss->recv_fd; css->svm_running = false; css->paused = true; css->qdisk_setuped = false; css->qdisk_used = false; libxl__ev_child_init(&css->child); css->cps.is_userspace_proxy = libxl_defbool_val(dss->remus->userspace_colo_proxy); if (dss->remus->netbufscript) css->colo_proxy_script = libxl__strdup(gc, dss->remus->netbufscript); else css->colo_proxy_script = GCSPRINTF("%s/colo-proxy-setup", libxl__xen_script_dir_path()); cds->ops = colo_ops; cds->callback = colo_save_setup_done; cds->ao = ao; cds->domid = dss->domid; cds->concrete_data = css; /* If enable userspace proxy mode, we don't need VIF */ if (css->cps.is_userspace_proxy) { cds->device_kind_flags = (1 << LIBXL__DEVICE_KIND_VBD); /* Use this args we can connect to qemu colo-compare */ cds->nics = libxl__device_list(gc, &libxl__nic_devtype, cds->domid, &cds->num_nics); if (cds->num_nics > 0) { css->cps.checkpoint_host = cds->nics[0].colo_checkpoint_host; css->cps.checkpoint_port = cds->nics[0].colo_checkpoint_port; } } else { cds->device_kind_flags = (1 << LIBXL__DEVICE_KIND_VIF) | (1 << LIBXL__DEVICE_KIND_VBD); } css->srs.ao = ao; css->srs.fd = css->recv_fd; css->srs.back_channel = true; libxl__stream_read_start(egc, &css->srs); css->cps.ao = ao; if (colo_proxy_setup(&css->cps)) { LOGD(ERROR, cds->domid, "COLO: failed to setup colo proxy for guest"); goto out; } if (init_device_subkind(cds)) goto out; callbacks->suspend = libxl__colo_save_domain_suspend_callback; callbacks->checkpoint = libxl__colo_save_domain_checkpoint_callback; callbacks->postcopy = libxl__colo_save_domain_resume_callback; callbacks->wait_checkpoint = libxl__colo_save_domain_wait_checkpoint_callback; libxl__checkpoint_devices_setup(egc, &dss->cds); return; out: dss->callback(egc, dss, ERROR_FAIL); }