Exemple #1
0
/**
 * "Unplug" a device from a VM.
 * vusb_unassign() will "unassign" it, then
 * xenstore_create_usb() will be called to "detach" the device.
 *
 * @param domid The domid of the VM to unplug the device from
 * @param bus The bus ID of the device
 * @param device The ID of the device on the bus
 *
 * @return 0 for success, 1 for failure
 */
int
usbowls_unplug_device(int domid, int bus, int device)
{
  dominfo_t di;
  usbinfo_t ui;
  int ret;

  ret = xenstore_get_dominfo(domid, &di);
  if (ret != 0) {
    xd_log(LOG_ERR, "Invalid domid %d", domid);
    return 1;
  }
  ret = get_usbinfo(bus, device, &ui);
  if (ret != 0) {
    xd_log(LOG_ERR, "Invalid device %d-%d", bus, device);
    return 1;
  }

  ret = vusb_assign(ui.usb_vendor, ui.usb_product, 0);
  if (ret != 0) {
    xd_log(LOG_ERR, "Failed to unassign device");
    return 1;
  }

  ret = xenstore_destroy_usb(&di, &ui);
  if (ret != 0) {
    xd_log(LOG_ERR, "Failed to detach device");
    return 1;
  }

  return 0;
}
Exemple #2
0
/**
 * "Plug" a device to a VM.
 * xenstore_create_usb() will be called to "attach" the device, then
 * vusb_assign() will "assign" it.
 *
 * @param domid The domid of the VM to plug the device to
 * @param bus The bus ID of the device
 * @param device The ID of the device on the bus
 *
 * @return 0 for success, 1 for failure
 */
int
usbowls_plug_device(int domid, int bus, int device)
{
  dominfo_t di;
  usbinfo_t ui;
  int ret;

  ret = xenstore_get_dominfo(domid, &di);
  if (ret != 0) {
    xd_log(LOG_ERR, "Invalid domid %d", domid);
    return 1;
  }
  ret = get_usbinfo(bus, device, &ui);
  if (ret != 0) {
    xd_log(LOG_ERR, "Invalid device %d-%d", bus, device);
    return 1;
  }

  /* FIXME: nicely unbind dom0 drivers on interfaces?
   * Or not, USB supports hot unplug doesn't it? :)
   */

  ret = xenstore_create_usb(&di, &ui);
  if (ret != 0) {
    xd_log(LOG_ERR, "Failed to attach device");
    return 1;
  }

  if (xenstore_wait_for_online(&di, &ui) < 0)
    xd_log(LOG_ERR, "The frontend or the backend didn't go online, continue anyway");

  ret = vusb_assign(ui.usb_vendor, ui.usb_product, 1);
  if (ret != 0) {
    xd_log(LOG_ERR, "Failed to assign device");
    xenstore_destroy_usb(&di, &ui);
    return 1;
  }

  return 0;
}
int main(int argc, char **argv)
{
  int option = 0;
  int domid = -1, bus = -1, device = -1;
  int vassign = 0, vunassign = 0, attach = 0, detach = 0, list = 0, dump = 0;
  char *action = NULL;
  dominfo_t di;
  usbinfo_t ui;
  int ret = 0;

  xs_handle = xs_daemon_open();
  if (xs_handle == NULL) {
    xd_log(LOG_ERR, "Failed to connect to xenstore");
    exit(1);
  }

  if ((xs_dom0path = xs_get_domain_path(xs_handle, 0)) == NULL) {
    xd_log(LOG_ERR, "Could not get domain 0 path from XenStore");
    exit(1);
  }

  while ((option = getopt(argc, argv, "D:b:d:")) != -1) {
    switch (option) {
    case 'D':
      domid = atoi(optarg);
      if (get_dominfo(domid, &di))
        exit(1);
      break;
    case 'b':
      bus = atoi(optarg);
      break;
    case 'd':
      device = atoi(optarg);
      break;
    }
  }

  if (optind != argc-1) {
    usage();
  }

  action = argv[optind];
  vassign = !strcmp(action, "assign");
  vunassign = !strcmp(action, "unassign");
  attach = !strcmp(action, "attach");
  detach = !strcmp(action, "detach");
  list = !strcmp(action, "list");
  dump = !strcmp(action, "dump");

  if (vassign || vunassign || attach || detach || dump) {
    if (bus < 0 || device < 0)
      usage();

    if (get_usbinfo(bus, device, &ui)) {
      if (detach) {
        /* can proceed detaching without detailed device info, we only need bus & dev num */
      } else if (vunassign) {
        /* no device so nothing to unassign */
        exit(0);
      } else {
        xd_log(LOG_ERR, "Failed to find device %d:%d", bus, device);
        exit(1);
      }
    }
  }

  if (optind == argc) {
    dump_dev(&ui);
    return 0;
  }

  if (dump)
    dump_dev(&ui);
  else if (vassign)
    ret = vusb_assign(ui.usb_vendor, ui.usb_product, 1);
  else if (vunassign)
    ret = vusb_assign(ui.usb_vendor, ui.usb_product, 0);
  else if (attach) {
    if (domid < 0)
      usage();
    ret = xenstore_create_usb(&di, &ui);
  }
  else if (detach) {
    if (domid < 0)
      usage();
    ret = xenstore_destroy_usb(&di, &ui);
  }
  else if (list) {
    if (domid < 0)
      usage();
    list_domain_devs(&di);
  }

  if (ret)
    xd_log(LOG_ERR, "Operation failed");
  return ret == 0 ? 0 : 1;
}