char *get_vm_name(int dom, int *target_dom)
{
	struct xs_handle *xs;
	char buf[64];
	char *name;
	char *target_dom_str;
	unsigned int len = 0;

	xs = xs_open(0);
	if (!xs) {
		perror("xs_daemon_open");
		exit(1);
	}
	snprintf(buf, sizeof(buf), "/local/domain/%d/target", dom);
	target_dom_str = xs_read(xs, 0, buf, &len);
	if (target_dom_str) {
		errno = 0;
		*target_dom = strtol(target_dom_str, (char **) NULL, 10);
		if (errno != 0) {
			perror("strtol");
			exit(1);
		}
	} else
		*target_dom = dom;
	snprintf(buf, sizeof(buf), "/local/domain/%d/name", *target_dom);
	name = xs_read(xs, 0, buf, &len);
	if (!name) {
		perror("xs_read domainname");
		exit(1);
	}
	xs_close(xs);
	return name;
}
XenDomainWatcher::XenDomainWatcher( LogHelper *logHelper )
    : xsh_( NULL ), xci_( NULL ), introduceToken_( "introduce" ), releaseToken_( "release" ), logHelper_( logHelper )
{
	xsh_ = xs_open( 0 );

	if ( !xsh_ )
		throw Exception( "xs_open() failed" );

	if ( !xs_watch( xsh_, "@introduceDomain", introduceToken_.c_str() ) ) {
		xs_close( xsh_ );
		throw Exception( "xs_watch() failed" );
	}

	if ( !xs_watch( xsh_, "@releaseDomain", releaseToken_.c_str() ) ) {
		xs_unwatch( xsh_, "@introduceDomain", introduceToken_.c_str() );
		xs_close( xsh_ );
		throw Exception( "xs_watch() failed" );
	}

	xci_ = xc_interface_open( NULL, NULL, 0 );

	if ( !xci_ ) {
		xs_unwatch( xsh_, "@introduceDomain", introduceToken_.c_str() );
		xs_unwatch( xsh_, "@releaseDomain", releaseToken_.c_str() );
		xs_close( xsh_ );
		throw Exception( "xc_interface_init() failed" );
	}
}
示例#3
0
int setFullPerm(char *path){
  struct xs_permissions perms = {.id = 0, .perms = XS_PERM_READ|XS_PERM_WRITE}; // Full Permissions
  if(!xs_set_permissions(xsd, 0, path, &perms, 1)){
    printf("Could not set directory permissions.\n");
    return 3;
  }
  return 0;
}

int main(int argc, char **argv)
{
  unsigned int num, i;
  char **list;
  bool res;

  xsd = xs_open(0);
  
  mkdir("/rendezvous");
  mkdir("/transport");

  setFullPerm("/rendezvous");
  setFullPerm("/transport");
  setFullPerm("/local/domain");
    
  printf("Base directory added. New root directory:\n");
  list = xs_directory(xsd, 0, "/", &num);
  for(i = 0; i < num; i++)
    printf("  /%s\n", list[i]);

  return 0;
}
示例#4
0
int libvchan_wait(libvchan_t *ctrl) {
    int ret = -2; /* invalid, so can be distinguished from real
                     libxenvchan_wait return code */
    struct xs_handle *xs;

    if (ctrl->xenvchan->is_server && libxenvchan_is_open(ctrl->xenvchan) == 2) {
        /* In case of vchan server waiting for a client, we'll not receive any
         * notification if the remote domain dies before connecting. Because of
         * that, check periodically if remote domain is still alive while
         * waiting for a connection. Actually this doesn't cover all the cases
         * - if remote domain is still alive, but remote process dies before
         * connecting, we'll also not receive any notification. But this, in
         * most cases, can be solved by application using libvchan.
         *
         * During normal operation this shouldn't be long - in most cases vchan
         * client will connect almost instantly. So this sleep(10) loop will
         * not hurt. Alternativelly it could be implemented with
         * xs_watch("@releaseDomain"), but such approach will slow down most
         * common execution path (xs_open+xs_watch even if client connects
         * right away).
         */
        while (ret == -2 && libxenvchan_is_open(ctrl->xenvchan) == 2) {
            fd_set rd_set;
            struct timeval tv = { 10, 0 };
            int vchan_fd = libxenvchan_fd_for_select(ctrl->xenvchan);
            FD_ZERO(&rd_set);
            FD_SET(vchan_fd, &rd_set);
            switch (select(vchan_fd+1, &rd_set, NULL, NULL, &tv)) {
                case 0:
                    if (!libvchan__check_domain_alive(ctrl->xc_handle, ctrl->remote_domain))
                        return -1;
                    break;
                case 1:
                    /* break the loop */
                    ret = -1;
                    break;
                default:
                    if (errno == EINTR)
                        break;
                    perror("select");
                    return -1;
            }
        }
    }
    ret = libxenvchan_wait(ctrl->xenvchan);
    if (ctrl->xs_path) {
        /* remove xenstore entry at first client connection */
        xs = xs_open(0);
        if (xs) {
            /* if xenstore connection failed just do not remove entries, but do
             * not abort whole function, especially still free the memory
             */
            xs_rm(xs, 0, ctrl->xs_path);
            xs_close(xs);
        }
        free(ctrl->xs_path);
        ctrl->xs_path = NULL;
    }
    return ret;
}
示例#5
0
/*
 * Open connection to xenstore.
 *
 * @pollfds defines of signal-handling descriptors to be watched
 * if has to wait.
 *
 * Will not touch pollfds[NPFD_XS].
 */
static void open_xs_connection(struct pollfd *pollfds)
{
	struct timespec ts0;
	int64_t wsec;
	bool displayed_msg = false;
	int k;

	/*
	 * If we are running as a daemon during system startup, there
	 * can be a race condition with continuing Xen initialization
	 * (/proc/xen including /proc/xen/privcmd may be unavailable yet,
	 * still to be created even though Xen service startup completion
	 * has already been signalled), so wait for a while if necessary.
	 */
	for (ts0 = getnow();;)
	{
		if (!xs)
			xs = xs_open(0);
		if (xs)
			break;

		/* time since the start */
		wsec = timespec_diff_ms(getnow(), ts0) / MSEC_PER_SEC;

		if (run_as_daemon && wsec < max_xen_init_retries)
		{
			if (wsec >= xen_init_retry_msg && !displayed_msg)
			{
				notice_msg("waiting for Xen to initialize");
				displayed_msg = true;
			}

			if (pollfds != NULL)
			{
				int npollfds = NPFD_COUNT - 1;
				for (k = 0;  k < npollfds;  k++)
					pollfds[k].revents = 0;
				if (poll(pollfds, npollfds, 1 * MSEC_PER_SEC) < 0)
					fatal_perror("poll");
				handle_signals(pollfds, NULL);
			}
			else
			{
				sleep(1);
			}
		}
		else
		{
			fatal_perror("unable to open connection to xenstore");
		}
	}
}
示例#6
0
libIVC_t *openIVCLibrary()
{
  libIVC_t *retval;

  assert( retval = calloc(1, sizeof(struct libIVC_interface)) );
  assert( retval->xc = xc_interface_open(NULL, NULL, 0) );
  assert( retval->xs = xs_open(0) );
  assert( retval->ec = xc_evtchn_open(NULL, 0) );
  assert( retval->gt = xc_gnttab_open(NULL, 0) );
#ifdef HAVE_XENSTORE_H
  retval->gs = xc_gntshr_open(NULL, 0); /* may not be available on all plats */
#endif

  return retval;
}
示例#7
0
static int store_dev_info(int domid, CharDriverState *cs, const char *string)
{
    struct xs_handle *xs = NULL;
    char *path = NULL;
    char *newpath = NULL;
    char *pts = NULL;
    int ret = -1;

    /* Only continue if we're talking to a pty. */
    if (strncmp(cs->filename, "pty:", 4)) {
        return 0;
    }
    pts = cs->filename + 4;

    /* We now have everything we need to set the xenstore entry. */
    xs = xs_open(0);
    if (xs == NULL) {
        fprintf(stderr, "Could not contact XenStore\n");
        goto out;
    }

    path = xs_get_domain_path(xs, domid);
    if (path == NULL) {
        fprintf(stderr, "xs_get_domain_path() error\n");
        goto out;
    }
    newpath = realloc(path, (strlen(path) + strlen(string) +
                strlen("/tty") + 1));
    if (newpath == NULL) {
        fprintf(stderr, "realloc error\n");
        goto out;
    }
    path = newpath;

    strcat(path, string);
    strcat(path, "/tty");
    if (!xs_write(xs, XBT_NULL, path, pts, strlen(pts))) {
        fprintf(stderr, "xs_write for '%s' fail", string);
        goto out;
    }
    ret = 0;

out:
    free(path);
    xs_close(xs);

    return ret;
}
示例#8
0
int __cdecl
main()
{
    HMODULE module;
    HANDLE h;
    HANDLE (__stdcall *xs_open)(void);
    void *(__stdcall *xs_read_f)(HANDLE, const char *, size_t *);
    char *r;
    char *path;
    char *dll;

#ifdef AMD64
    path = read_reg_string(HKEY_LOCAL_MACHINE,
                           "SOFTWARE\\Wow6432node\\Citrix\\XenTools",
                           "Install_Dir");
#else
    path = read_reg_string(HKEY_LOCAL_MACHINE,
                           "SOFTWARE\\Citrix\\XenTools",
                           "Install_Dir");
#endif
    if (!path) 
        xs_win_err(1, &xs_render_error_stderr, "getting install dir");

    dll = xs_assemble_strings("\\", path, "xs.dll", NULL);
    if (!dll)
        xs_win_err(1, &xs_render_error_stderr, "assembling path");

    module = LoadLibrary(dll);
    if (!module)
        xs_win_err(1, &xs_render_error_stderr, "loading xs.dll");
    printf("Loaded module.\n");
    xs_open = (HANDLE (__stdcall *)(void))GetProcAddress(module, "xs_domain_open");
    if (!xs_open)
        xs_win_err(1, &xs_render_error_stderr, "getting xs_domain_open");
    h = xs_open();
    if (!h)
        xs_win_err(1, &xs_render_error_stderr, "opening interface");
    printf("interface %p\n", h);

    xs_read_f = (void *(__stdcall *)(HANDLE, const char *, size_t *))GetProcAddress(module, "xs_read");
    if (!xs_read_f)
        xs_win_err(1, &xs_render_error_stderr, "getting xs_read");
    r = xs_read_f(h, "vm", NULL);
    printf("r %p\n", r);
    printf("vm -> %s\n", r);

    return 0;
}
示例#9
0
static uint32_t
vbd_read_tapdisk_pid(uint32_t domid, uint32_t vbdid)
{
    // XenStore tapdisk pid path
    static const char* PATH_FMT = "/local/domain/0/backend/vbd3/%u/%u/kthread-pid";

    // Local variables
    char *path;                 // Path storage
    unsigned int len;           // Temp variable
    void *value;                // Value returned by xs_read
    uint32_t retvalue = 0;      // Value converted to integer

    // Open Xenstore connection
    struct xs_handle *handle = xs_open(XS_OPEN_READONLY);

    if (!handle) {
        perror("xs_open");
        goto err;
    }

    // Format tapdisk pid path
    if (asprintf(&path, PATH_FMT, domid, vbdid) < 0) {
        perror("asprintf");
        goto asperr;
    }

    // Read value
    value = xs_read(handle, XBT_NULL, path, &len);

    // We don't print error here, as we would always report invalid cdrom entry,
    // for which there is no tapdisk pid
    if (!value) {
        goto readerr;
    }

    // Convert to int
    retvalue = atoi((const char *)value);

    free(value);
readerr:
    free(path);
asperr:
    xs_close(handle);
err:
    return retvalue;
}
示例#10
0
void libvchan_close(libvchan_t *ctrl) {
    struct xs_handle *xs;

    libxenvchan_close(ctrl->xenvchan);
    if (ctrl->xs_path) {
        /* remove xenstore entry in case of no client connected */
        xs = xs_open(0);
        if (xs) {
            /* if xenstore connection failed just do not remove entries, but do
             * not abort whole function, especially still free the memory
             */
            xs_rm(xs, 0, ctrl->xs_path);
            xs_close(xs);
        }
        free(ctrl->xs_path);
    }
    free(ctrl);
}
示例#11
0
int getDomId(void){
  struct xs_handle   *handle= 0;
  int selfId = -1;
  handle = xs_open(XS_OPEN_READONLY);
  if ( handle == NULL || handle < 0){
    fprintf(stderr, "Unabled to open an interface\n");
    perror("getDomId: xs_open Failed to obtain a handle.");
    return -1;
  }
  char * s = (char *)xs_read(handle, XBT_NULL,"domid",NULL);

  if (s == NULL){
    fprintf(stderr, "Unabled to open an interface\n");
    perror("getDomId: xs_open Failed to obtain a handle.");
    return -1;
  }

  selfId =(int) strtol(s,(char **)NULL,10);
  return selfId;

}
示例#12
0
int
main(int argc, char **argv)
{
    struct xs_handle *xsh;
    xs_transaction_t xth = XBT_NULL;
    int ret = 0, socket = 0;
    int prefix = 0;
    int tidy = 0;
    int upto = 0;
    int recurse = 0;
    int nr_watches = -1;
    int transaction;
    struct winsize ws;
    enum mode mode;

    const char *_command = strrchr(argv[0], '/');
    const char *command = _command ? &_command[1] : argv[0];
    int switch_argv = -1; /* which element of argv did we switch on */

    if (strncmp(command, "xenstore-", strlen("xenstore-")) == 0)
    {
	switch_argv = 0;
	command = command + strlen("xenstore-");
    }
    else if (argc < 2)
	usage(MODE_unknown, 0, argv[0]);
    else
    {
	command = argv[1];
	switch_argv = 1;
    }

    mode = lookup_mode(command);

    while (1) {
	int c, index = 0;
	static struct option long_options[] = {
	    {"help",    0, 0, 'h'},
	    {"flat",    0, 0, 'f'}, /* MODE_ls */
	    {"socket",  0, 0, 's'},
	    {"prefix",  0, 0, 'p'}, /* MODE_read || MODE_list || MODE_ls */
	    {"tidy",    0, 0, 't'}, /* MODE_rm */
	    {"upto",    0, 0, 'u'}, /* MODE_chmod */
	    {"recurse", 0, 0, 'r'}, /* MODE_chmod */
	    {"number",  1, 0, 'n'}, /* MODE_watch */
	    {0, 0, 0, 0}
	};

	c = getopt_long(argc - switch_argv, argv + switch_argv, "hfspturn:",
			long_options, &index);
	if (c == -1)
	    break;

	switch (c) {
	case 'h':
	    usage(mode, switch_argv, argv[0]);
	    /* NOTREACHED */
        case 'f':
	    if ( mode == MODE_ls ) {
		max_width = INT_MAX/2;
		desired_width = 0;
		show_whole_path = 1;
	    } else {
		usage(mode, switch_argv, argv[0]);
	    }
            break;
        case 's':
            socket = 1;
            break;
	case 'p':
	    if ( mode == MODE_read || mode == MODE_list || mode == MODE_ls )
		prefix = 1;
	    else
		usage(mode, switch_argv, argv[0]);
	    break;
	case 't':
	    if ( mode == MODE_rm )
		tidy = 1;
	    else
		usage(mode, switch_argv, argv[0]);
	    break;
	case 'u':
	    if ( mode == MODE_chmod )
		upto = 1;
	    else
		usage(mode, switch_argv, argv[0]);
	    break;
	case 'r':
	    if ( mode == MODE_chmod )
		recurse = 1;
	    else
		usage(mode, switch_argv, argv[0]);
	    break;
	case 'n':
	    if ( mode == MODE_watch )
		nr_watches = atoi(optarg);
	    else
		usage(mode, switch_argv, argv[0]);
	    break;
	}
    }

    switch (mode) {
    case MODE_ls:
	break;
    case MODE_write:
	if ((argc - switch_argv - optind) % 2 == 1) {
	    usage(mode, switch_argv, argv[0]);
	    /* NOTREACHED */
	}
	/* DROP-THRU */
    default:
	if (optind == argc - switch_argv) {
	    usage(mode, switch_argv, argv[0]);
	    /* NOTREACHED */
	}
    }

    switch (mode) {
    case MODE_read:
	transaction = (argc - switch_argv - optind) > 1;
	break;
    case MODE_write:
	transaction = (argc - switch_argv - optind) > 2;
	break;
    case MODE_ls:
    case MODE_watch:
	transaction = 0;
	break;
    default:
	transaction = 1;
	break;
    }

    if ( mode == MODE_ls )
    {
	memset(&ws, 0, sizeof(ws));
	ret = ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
	if (!ret)
	    max_width = ws.ws_col - 2;
    }

    xsh = xs_open(socket ? XS_OPEN_SOCKETONLY : 0);
    if (xsh == NULL) err(1, "xs_open");

again:
    if (transaction) {
	xth = xs_transaction_start(xsh);
	if (xth == XBT_NULL)
	    errx(1, "couldn't start transaction");
    }

    ret = perform(mode, optind, argc - switch_argv, argv + switch_argv, xsh, xth, prefix, tidy, upto, recurse, nr_watches);

    if (transaction && !xs_transaction_end(xsh, xth, ret)) {
	if (ret == 0 && errno == EAGAIN) {
	    output_pos = 0;
	    goto again;
	}
	errx(1, "couldn't end transaction");
    }

    if (output_pos)
	printf("%s", output_buf);

    return ret;
}
示例#13
0
int main(int argc, char** argv)
{
    int opt;
    xc_interface *xch;
    struct xs_handle *xsh;
    char buf[16];
    int rv, fd;

    while ( (opt = getopt_long(argc, argv, "", options, NULL)) != -1 )
    {
        switch ( opt )
        {
        case 'k':
            kernel = optarg;
            break;
        case 'm':
            memory = strtol(optarg, NULL, 10);
            break;
        case 'f':
            flask = optarg;
            break;
        case 'r':
            ramdisk = optarg;
            break;
        case 'p':
            param = optarg;
            break;
        case 'n':
            name = optarg;
            break;
        default:
            usage();
            return 2;
        }
    }

    if ( optind != argc || !kernel || !memory )
    {
        usage();
        return 2;
    }

    xch = xc_interface_open(NULL, NULL, 0);
    if ( !xch )
    {
        fprintf(stderr, "xc_interface_open() failed\n");
        return 1;
    }

    rv = check_domain(xch);

    if ( !rv )
        rv = build(xch);
    else if ( rv > 0 )
        fprintf(stderr, "xenstore domain already present.\n");

    xc_interface_close(xch);

    if ( rv )
        return 1;

    rv = gen_stub_json_config(domid);
    if ( rv )
        return 3;

    xsh = xs_open(0);
    if ( !xsh )
    {
        fprintf(stderr, "xs_open() failed.\n");
        return 3;
    }
    snprintf(buf, 16, "%d", domid);
    do_xs_write(xsh, "/tool/xenstored/domid", buf);
    do_xs_write_dom(xsh, "domid", buf);
    do_xs_write_dom(xsh, "name", name);
    snprintf(buf, 16, "%d", memory * 1024);
    do_xs_write_dom(xsh, "memory/target", buf);
    do_xs_write_dom(xsh, "memory/static-max", buf);
    xs_close(xsh);

    fd = creat("/var/run/xenstored.pid", 0666);
    if ( fd < 0 )
    {
        fprintf(stderr, "Creating /var/run/xenstored.pid failed\n");
        return 3;
    }
    rv = snprintf(buf, 16, "domid:%d\n", domid);
    rv = write(fd, buf, rv);
    close(fd);
    if ( rv < 0 )
    {
        fprintf(stderr, "Writing domid to /var/run/xenstored.pid failed\n");
        return 3;
    }

    return 0;
}
示例#14
0
libvchan_t *libvchan_client_init(int domain, int port) {
    char xs_path[255];
    char xs_path_watch[255];
    libvchan_t *ctrl;
    xc_interface *xc_handle;
    struct xs_handle *xs;
    char **vec;
    unsigned int count, len;
    char *dummy = NULL;
    char *own_domid = NULL;

    xc_handle = xc_interface_open(NULL, NULL, 0);
    if (!xc_handle) {
        /* error already logged by xc_interface_open */
        goto err;
    }

    /* wait for server to appear */
    xs = xs_open(0);
    if (!xs) {
        perror("xs_open");
        goto err_xc;
    }

    len = 0;

    if (!xs_watch(xs, "domid", "domid")) {
        fprintf(stderr, "Cannot setup xenstore watch\n");
        goto err_xs;
    }
    if (!xs_watch(xs, "@releaseDomain", "release")) {
        fprintf(stderr, "Cannot setup xenstore watch\n");
        goto err_xs;
    }
    while (!dummy || !len) {
        vec = xs_read_watch(xs, &count);
        if (vec) {
            if (strcmp(vec[XS_WATCH_TOKEN], "domid") == 0) {
                /* domid have changed */
                if (own_domid) {
                    free(own_domid);
                    own_domid = NULL;
                    xs_unwatch(xs, xs_path_watch, xs_path_watch);
                }
            }
            free(vec);
        }
        if (!own_domid) {
            /* construct xenstore path on first iteration and on every domid
             * change detected (save+restore case) */
            own_domid = xs_read(xs, 0, "domid", &len);
            if (!own_domid) {
                fprintf(stderr, "Cannot get own domid\n");
                goto err_xs;
            }
            if (atoi(own_domid) == domain) {
                fprintf(stderr, "Loopback vchan connection not supported\n");
                free(own_domid);
                goto err_xs;
            }

            snprintf(xs_path, sizeof(xs_path), "/local/domain/%d/data/vchan/%s/%d",
                    domain, own_domid, port);
            /* watch on this key as we might not have access to the whole directory */
            snprintf(xs_path_watch, sizeof(xs_path_watch), "%s/event-channel", xs_path);

            if (!xs_watch(xs, xs_path_watch, xs_path_watch)) {
                fprintf(stderr, "Cannot setup watch on %s\n", xs_path_watch);
                free(own_domid);
                goto err_xs;
            }
        }

        dummy = xs_read(xs, 0, xs_path_watch, &len);
        if (dummy)
            free(dummy);
        else {
            if (!libvchan__check_domain_alive(xc_handle, domain)) {
                fprintf(stderr, "domain dead\n");
                goto err_xs;
            }
        }
    }

    if (own_domid)
        free(own_domid);
    xs_close(xs);

    ctrl = malloc(sizeof(*ctrl));
    if (!ctrl)
        return NULL;
    ctrl->xs_path = NULL;
    ctrl->xenvchan = libxenvchan_client_init(NULL, domain, xs_path);
    if (!ctrl->xenvchan) {
        free(ctrl);
        return NULL;
    }
    ctrl->xenvchan->blocking = 1;
    /* notify server */
    xc_evtchn_notify(ctrl->xenvchan->event, ctrl->xenvchan->event_port);
    ctrl->remote_domain = domain;
    ctrl->xc_handle = xc_handle;
    return ctrl;

err_xs:
    xs_close(xs);
err_xc:
    xc_interface_close(xc_handle);
err:
    return NULL;
}