void xen_pause(xen_interface_t *xen, domid_t domID) { xc_dominfo_t info = { 0 }; if (1 == xc_domain_getinfo(xen->xc, domID, 1, &info) && info.domid == domID && !info.paused) xc_domain_pause(xen->xc, domID); }
void run_drakvuf(gpointer data, gpointer user_data) { UNUSED(user_data); struct start_drakvuf *start = data; char *command; gint rc; GThread *timer, *tcpd; restart: command = NULL; rc = 0; printf("[%i] Starting %s on domid %u\n", start->threadid, start->input, start->cloneID); start->timer = 180; g_mutex_lock(&start->timer_lock); timer = g_thread_new("timer", timer_thread, start); command = g_malloc0(snprintf(NULL, 0, CONFIG_CMD, config_script, rekall_profile, start->cloneID, injection_pid, start->threadid+1, run_folder, start->input, out_folder) + 1); sprintf(command, CONFIG_CMD, config_script, rekall_profile, start->cloneID, injection_pid, start->threadid+1, run_folder, start->input, out_folder); printf("[%i] ** RUNNING COMMAND: %s\n", start->threadid, command); g_spawn_command_line_sync(command, NULL, NULL, &rc, NULL); g_free(command); g_mutex_unlock(&start->timer_lock); g_thread_join(timer); printf("[%i] ** Preconfig finished with RC %i. Timer: %i.\n", start->threadid, rc, start->timer); if (!start->timer) goto end; tcpd = g_thread_new("tcpdump", tcpdump, start); xc_domain_unpause(xen->xc, start->cloneID); // Preconfigure script takes a bit to run in the guest sleep(30); xc_domain_pause(xen->xc, start->cloneID); start->timer = 180; g_mutex_lock(&start->timer_lock); timer = g_thread_new("timer", timer_thread, start); command = g_malloc0(snprintf(NULL, 0, DRAKVUF_CMD, drakvuf_script, rekall_profile, start->cloneID, injection_pid, start->threadid+1, run_folder, start->input, out_folder) + 1); sprintf(command, DRAKVUF_CMD, drakvuf_script, rekall_profile, start->cloneID, injection_pid, start->threadid+1, run_folder, start->input, out_folder); printf("[%i] ** RUNNING COMMAND: %s\n", start->threadid, command); g_spawn_command_line_sync(command, NULL, NULL, &rc, NULL); g_free(command); g_mutex_unlock(&start->timer_lock); g_thread_join(timer); g_thread_join(tcpd); printf("[%i] ** DRAKVUF finished with RC %i. Timer: %i\n", start->threadid, rc, start->timer); if ( start->timer ) { printf("[%i] Finished processing %s\n", start->threadid, start->input); g_mutex_unlock(&locks[start->threadid]); g_mutex_clear(&start->timer_lock); g_free(start->input); g_free(start->clone_name); g_free(start); return; } else cleanup(start->cloneID, start->threadid+1); end: printf("[%i] %s failed to execute on %u because of a timeout, creating new clone\n", start->threadid, start->input, start->cloneID); prepare(NULL, start); goto restart; }
void *xc_vm_event_enable(xc_interface *xch, domid_t domain_id, int param, uint32_t *port) { void *ring_page = NULL; uint64_t pfn; xen_pfn_t ring_pfn, mmap_pfn; unsigned int op, mode; int rc1, rc2, saved_errno; if ( !port ) { errno = EINVAL; return NULL; } /* Pause the domain for ring page setup */ rc1 = xc_domain_pause(xch, domain_id); if ( rc1 != 0 ) { PERROR("Unable to pause domain\n"); return NULL; } /* Get the pfn of the ring page */ rc1 = xc_hvm_param_get(xch, domain_id, param, &pfn); if ( rc1 != 0 ) { PERROR("Failed to get pfn of ring page\n"); goto out; } ring_pfn = pfn; mmap_pfn = pfn; rc1 = xc_get_pfn_type_batch(xch, domain_id, 1, &mmap_pfn); if ( rc1 || mmap_pfn & XEN_DOMCTL_PFINFO_XTAB ) { /* Page not in the physmap, try to populate it */ rc1 = xc_domain_populate_physmap_exact(xch, domain_id, 1, 0, 0, &ring_pfn); if ( rc1 != 0 ) { PERROR("Failed to populate ring pfn\n"); goto out; } } mmap_pfn = ring_pfn; ring_page = xc_map_foreign_pages(xch, domain_id, PROT_READ | PROT_WRITE, &mmap_pfn, 1); if ( !ring_page ) { PERROR("Could not map the ring page\n"); goto out; } switch ( param ) { case HVM_PARAM_PAGING_RING_PFN: op = XEN_VM_EVENT_ENABLE; mode = XEN_DOMCTL_VM_EVENT_OP_PAGING; break; case HVM_PARAM_MONITOR_RING_PFN: op = XEN_VM_EVENT_ENABLE; mode = XEN_DOMCTL_VM_EVENT_OP_MONITOR; break; case HVM_PARAM_SHARING_RING_PFN: op = XEN_VM_EVENT_ENABLE; mode = XEN_DOMCTL_VM_EVENT_OP_SHARING; break; /* * This is for the outside chance that the HVM_PARAM is valid but is invalid * as far as vm_event goes. */ default: errno = EINVAL; rc1 = -1; goto out; } rc1 = xc_vm_event_control(xch, domain_id, op, mode, port); if ( rc1 != 0 ) { PERROR("Failed to enable vm_event\n"); goto out; } /* Remove the ring_pfn from the guest's physmap */ rc1 = xc_domain_decrease_reservation_exact(xch, domain_id, 1, 0, &ring_pfn); if ( rc1 != 0 ) PERROR("Failed to remove ring page from guest physmap"); out: saved_errno = errno; rc2 = xc_domain_unpause(xch, domain_id); if ( rc1 != 0 || rc2 != 0 ) { if ( rc2 != 0 ) { if ( rc1 == 0 ) saved_errno = errno; PERROR("Unable to unpause domain"); } if ( ring_page ) xenforeignmemory_unmap(xch->fmem, ring_page, 1); ring_page = NULL; errno = saved_errno; } return ring_page; }
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; }