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" ); } }
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; }
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; }
/* * 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"); } } }
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; }
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; }
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; }
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; }
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); }
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; }
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; }
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; }
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; }