Exemplo n.º 1
0
struct libxenvchan * vchan_maybe_client_init(xentoollog_logger * logger, int srvId){
   int sourceId = getDomId();
   int destId = srvId;
   struct libxenvchan *txCtrl=0;
   char serverRxXS [256]; // xenStore path for the server's receive.
   char  p[256];
   char *path = "data/serverVchan";
   
   
   if (!path){
     sprintf (p,"%s",SERV_REL_RX_XS_PATH);
   }else{
     sprintf (p,"%s",path);
   }

   sprintf(p, "%s_%d",p,sourceId);
   sprintf(serverRxXS, "/local/domain/%d/%s", destId,
           p);

   // We act as a client so the servers Rx is our Tx.
   fprintf(stdout, "transmitChan: vchan init for xs=%s to domId=%d,\n",
           serverRxXS, sourceId );
   txCtrl = libxenvchan_client_init((xentoollog_logger *)logger,
                                    destId, serverRxXS);
 
   if(txCtrl == NULL) {
      return NULL;
   }
   return txCtrl;
}
Exemplo n.º 2
0
struct libxenvchan * createTransmitChanP(xentoollog_logger * xc_logger, int destId, int sourceId, char * path){
  struct libxenvchan *txCtrl=0;
  char serverRxXS [256]; // xenStore path for the server's receive.
  char  p[256];
  if (!path){
    sprintf (p,"%s",SERV_REL_RX_XS_PATH);
  }else{
    sprintf (p,"%s",path);
  }
  
  sprintf(p, "%s_%d",p,sourceId);
  sprintf(serverRxXS, "/local/domain/%d/%s", destId,
          p);

  // We act as a client so the servers Rx is our Tx.
  fprintf(stdout, "transmitChan: vchan init for xs=%s to domId=%d,\n",
          serverRxXS, sourceId );
  txCtrl = libxenvchan_client_init((xentoollog_logger *)xc_logger,
                                   destId, serverRxXS);

  if(txCtrl == NULL) {
    // We had an error trying to initialise the client vchan.
    char * lclErrStr = strerror(errno);
    fprintf(stderr, "Error: %s: libxenvchan_client_init: domId=%d, xsPath=%s.\n",
            lclErrStr, destId, serverRxXS);
    if(errno == ENOENT) {
      fprintf(stderr, "    kernel module xen_gntalloc (/dev/xen/gntalloc) or xen_evtchn (/dev/xen/evtchn) may not be running.\n");
    }
    exit(1);
  }
//  txCtrl->blocking = 1; // Block for each vchan IO ?

return txCtrl;

}
Exemplo n.º 3
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;
}
Exemplo n.º 4
0
libvchan_t *libvchan_client_init(int domain, int port) {
    char xs_path[255];
    char xs_path_watch[255];
    libvchan_t *ctrl = NULL;
    PXENCONTROL_CONTEXT xc_handle = NULL;
    char own_domid[16];
    DWORD status;
    HANDLE path_watch_event = NULL;
    PVOID path_watch_handle = NULL;

    if (ERROR_SUCCESS != XcOpen(g_logger, &xc_handle)) {
        Log(XLL_ERROR, "opening xen device failed");
        /*
        This error signifies that xeniface is not available.
        We need to return a well-defined code so the caller can potentially
        wait for xeniface to become active (this can happen after the first
        reboot after pvdrivers installation, it takes a while to load).
        */
        SetLastError(ERROR_NOT_SUPPORTED);
        goto fail;
    }

    /* wait for server to appear */
    status = XcStoreRead(xc_handle, "domid", sizeof(own_domid), own_domid);
    if (status != ERROR_SUCCESS) {
        Log(XLL_ERROR, "reading domid from xenstore failed: 0x%x", status);
        goto fail;
    }
    
    if (atoi(own_domid) == domain) {
        Log(XLL_ERROR, "Loopback vchan connection not supported");
        goto fail;
    }

    path_watch_event = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (!path_watch_event) {
        Log(XLL_ERROR, "CreateEvent(xs watch) failed: 0x%x", GetLastError());
        goto fail;
    }

    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);

    Log(XLL_DEBUG, "path: %S", xs_path);
    status = XcStoreAddWatch(xc_handle, xs_path_watch, path_watch_event, &path_watch_handle);
    if (status != ERROR_SUCCESS) {
        Log(XLL_ERROR, "adding xenstore watch (%S) failed: 0x%x", xs_path_watch, status);
        goto fail;
    }

    status = WaitForSingleObject(path_watch_event, 100);
    if (status != WAIT_OBJECT_0) {
        Log(XLL_ERROR, "Wait for xenstore (1) failed: 0x%x", GetLastError());
        // don't fail completely yet, if we can read the store values we're ok
    }

    // wait two times because Xen always signals the watch immediately after creation
    status = WaitForSingleObject(path_watch_event, 100);
    if (status != WAIT_OBJECT_0) {
        Log(XLL_ERROR, "Wait for xenstore (2) failed: 0x%x", GetLastError());
    }

    XcStoreRemoveWatch(xc_handle, path_watch_handle);
    path_watch_handle = 0;
    CloseHandle(path_watch_event);
    path_watch_event = NULL;

    ctrl = malloc(sizeof(*ctrl));
    if (!ctrl)
        goto fail;

    ctrl->xs_path = NULL;
    ctrl->xenvchan = libxenvchan_client_init(g_logger, domain, xs_path);
    if (!ctrl->xenvchan) {
        Log(XLL_ERROR, "libxenvchan_client_init(%u, %S) failed", domain, xs_path);
        goto fail;
    }
    
    ctrl->xenvchan->blocking = 1;
    // notify server - xc handle must be the one that xenvchan opened since we use event channel that was allocated using that handle
    XcEvtchnNotify(ctrl->xenvchan->xc, ctrl->xenvchan->event_port);
    ctrl->remote_domain = domain;
    XcClose(xc_handle);

    Log(XLL_DEBUG, "ctrl %p, xenvchan %p", ctrl, ctrl->xenvchan);
    return ctrl;

fail:
    if (path_watch_handle)
        XcStoreRemoveWatch(xc_handle, path_watch_handle);
    if (path_watch_event)
        CloseHandle(path_watch_event);
    if (xc_handle)
        XcClose(xc_handle);
    if (ctrl)
        free(ctrl);
    return NULL;
}