Пример #1
0
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);

}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}