static void libxl__colo_restore_teardown_done(libxl__egc *egc, libxl__colo_restore_state *crs, int rc) { libxl__domain_create_state *dcs = CONTAINER_OF(crs, *dcs, crs); EGC_GC; /* convenience aliases */ const int domid = crs->domid; const libxl_ctx *const ctx = libxl__gc_owner(gc); xc_interface *const xch = ctx->xch; if (!rc) /* failover, no need to destroy the secondary vm */ goto out; xc_domain_destroy(xch, domid); out: if (crs->saved_cb) { dcs->callback = crs->saved_cb; crs->saved_cb = NULL; } dcs->callback(egc, dcs, rc, crs->domid); }
static int build(xc_interface *xch) { char cmdline[512]; uint32_t ssid; xen_domain_handle_t handle = { 0 }; int rv, xs_fd; struct xc_dom_image *dom = NULL; int limit_kb = (memory + 1) * 1024; xs_fd = open("/dev/xen/xenbus_backend", O_RDWR); if ( xs_fd == -1 ) { fprintf(stderr, "Could not open /dev/xen/xenbus_backend\n"); return -1; } if ( flask ) { rv = xc_flask_context_to_sid(xch, flask, strlen(flask), &ssid); if ( rv ) { fprintf(stderr, "xc_flask_context_to_sid failed\n"); goto err; } } else { ssid = SECINITSID_DOMU; } rv = xc_domain_create(xch, ssid, handle, XEN_DOMCTL_CDF_xs_domain, &domid, NULL); if ( rv ) { fprintf(stderr, "xc_domain_create failed\n"); goto err; } rv = xc_domain_max_vcpus(xch, domid, 1); if ( rv ) { fprintf(stderr, "xc_domain_max_vcpus failed\n"); goto err; } rv = xc_domain_setmaxmem(xch, domid, limit_kb); if ( rv ) { fprintf(stderr, "xc_domain_setmaxmem failed\n"); goto err; } rv = xc_domain_set_memmap_limit(xch, domid, limit_kb); if ( rv ) { fprintf(stderr, "xc_domain_set_memmap_limit failed\n"); goto err; } rv = ioctl(xs_fd, IOCTL_XENBUS_BACKEND_SETUP, domid); if ( rv < 0 ) { fprintf(stderr, "Xenbus setup ioctl failed\n"); goto err; } if ( param ) snprintf(cmdline, 512, "--event %d --internal-db %s", rv, param); else snprintf(cmdline, 512, "--event %d --internal-db", rv); dom = xc_dom_allocate(xch, cmdline, NULL); rv = xc_dom_kernel_file(dom, kernel); if ( rv ) { fprintf(stderr, "xc_dom_kernel_file failed\n"); goto err; } if ( ramdisk ) { rv = xc_dom_ramdisk_file(dom, ramdisk); if ( rv ) { fprintf(stderr, "xc_dom_ramdisk_file failed\n"); goto err; } } rv = xc_dom_boot_xen_init(dom, xch, domid); if ( rv ) { fprintf(stderr, "xc_dom_boot_xen_init failed\n"); goto err; } rv = xc_dom_parse_image(dom); if ( rv ) { fprintf(stderr, "xc_dom_parse_image failed\n"); goto err; } rv = xc_dom_mem_init(dom, memory); if ( rv ) { fprintf(stderr, "xc_dom_mem_init failed\n"); goto err; } rv = xc_dom_boot_mem_init(dom); if ( rv ) { fprintf(stderr, "xc_dom_boot_mem_init failed\n"); goto err; } rv = xc_dom_build_image(dom); if ( rv ) { fprintf(stderr, "xc_dom_build_image failed\n"); goto err; } rv = xc_dom_boot_image(dom); if ( rv ) { fprintf(stderr, "xc_dom_boot_image failed\n"); goto err; } rv = xc_domain_set_virq_handler(xch, domid, VIRQ_DOM_EXC); if ( rv ) { fprintf(stderr, "xc_domain_set_virq_handler failed\n"); goto err; } rv = xc_domain_unpause(xch, domid); if ( rv ) { fprintf(stderr, "xc_domain_unpause failed\n"); goto err; } rv = 0; err: if ( dom ) xc_dom_release(dom); if ( xs_fd >= 0 ) close(xs_fd); /* if we failed then destroy the domain */ if ( rv && domid != ~0 ) xc_domain_destroy(xch, domid); return rv; }
int destroy_domain(char *domname) { int domid, rcode, i, DMid, status; int __attribute__((__unused__)) ret; #ifdef XENCTRL_HAS_XC_INTERFACE xc_interface *xc_handle = NULL; #else int xc_handle = 0; #endif unsigned int len; char *s; char path[256]; struct xs_handle *xsh = NULL; FILE *f; char buf[256]; char *backend; xsh = xs_daemon_open(); if (!xsh) { perror("Couldn't get xsh handle."); rcode = 1; goto out; } domid = getDomidByName(xsh, domname); if (domid < 1) { perror("Error,Can't destroy domId, domId should > 0\n"); rcode = 1; goto out; } #ifdef XENCTRL_HAS_XC_INTERFACE xc_handle = xc_interface_open(NULL, NULL, 0); if (xc_handle == NULL) { #else xc_handle = xc_interface_open(); if (xc_handle < 0) { #endif perror("Couldn't open xc handle."); rcode = 1; goto out; } /* TODO PCI clean paths = self._prepare_phantom_paths() if self.dompath is not None: self._cleanup_phantom_devs(paths) xc_domain_destroy_hook(xc_handle, domid); */ xc_domain_pause(xc_handle, domid); rcode = xc_domain_destroy(xc_handle, domid); // free Device Model sprintf(path,"/local/domain/%d/image/device-model-pid", domid); s = xs_read(xsh, XBT_NULL, path, &len); if( s != NULL) { DMid = atoi(s); free(s); DEBUG("Deivce Model Id is %d\n", DMid); } else { rcode = 1; DEBUG("can't read Deivce Model Id\n"); goto out; } kill(DMid, SIGHUP); for( i=0; i< 100; i++) { if(DMid == waitpid(DMid, &status, WNOHANG)) break; sleep(0.1); } if( i == 100) { DEBUG("DeviceModel %d took more than 10s " "to terminate: sending SIGKILL\n", DMid); kill(DMid, SIGKILL); waitpid(DMid, &status, 0); } sprintf(path,"/local/domain/0/device-model/%i", domid); xs_rm(xsh, XBT_NULL, path); // unlink pipe sprintf(path,"/var/run/tap/qemu-read-%d", domid); ret = unlink(path); sprintf(path,"/var/run/tap/qemu-write-%d", domid); ret = unlink(path); //notify backend to reap the source assigned to this VM sprintf(path, "xenstore-ls /local/domain/%d/device > /var/tmp/xdestroy_device.%d", domid, domid); ret = system(path); sprintf(path, "/var/tmp/xdestroy_device.%d", domid); f = fopen(path, "r"); if ( f == NULL) { DEBUG(" error to open device file\n"); return -1; } DEBUG("- begin to reap\n"); while(1) { if( fgets(buf, 256, f)== NULL) break; else { if( buf[0] != 0x20) { backend = device_backend(xsh, buf, domid); if( backend != NULL) { notify_backend(xsh, backend); free(backend); } } } } DEBUG("- end to reap\n"); fclose(f); sprintf(path, "rm /var/tmp/xdestroy_device.%d", domid); ret = system(path); extra_call(domname, DMid); out: if (xsh) xs_daemon_close(xsh); if (xc_handle) xc_interface_close(xc_handle); return rcode; } int main(int argc, char **argv) { if (argc != 2) { printf("Miss destroy name\n"); return -1; } xlist(argc, argv); //shutdown_domain(argv[1]); destroy_domain(argv[1]); return 0; }