|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v6 1/2] libxl: Introduce functions to add and remove USB devices to an HVM guest
On Wed, 2013-04-24 at 14:32 +0100, George Dunlap wrote:
> On 24/04/13 13:38, Ian Campbell wrote:
> > I didn't see an implementation of libxl__device_usb_setdefault?
>
> You mean, for the internal structure?
No, for the external structure, but called only internally in libxl.
>From libxl_internal.h:
/*
* For each aggregate type which can be used as an input we provide:
*
* int libxl__<type>_setdefault(gc, <type> *p):
*
* Idempotently sets any members of "p" which is currently set to
* a special value indicating that the defaults should be used
* (per libxl_<type>_init) to a specific value.
*
* All libxl API functions are expected to have arranged for this
* to be called before using any values within these structures.
*/
>
> >
> > On Fri, 2013-04-19 at 16:59 +0100, George Dunlap wrote:
> >> xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/vm", dom_path),
> >> vm_path, strlen(vm_path));
> >> rc = libxl__domain_rename(gc, *domid, 0, info->name, t);
> >> if (rc)
> >> diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
> >> index 3ba3a21..d2e00fa 100644
> >> --- a/tools/libxl/libxl_internal.h
> >> +++ b/tools/libxl/libxl_internal.h
> >> @@ -1412,6 +1412,24 @@ _hidden int libxl__qmp_save(libxl__gc *gc, int
> >> domid, const char *filename);
> >> /* Set dirty bitmap logging status */
> >> _hidden int libxl__qmp_set_global_dirty_log(libxl__gc *gc, int domid,
> >> bool enable);
> >> _hidden int libxl__qmp_insert_cdrom(libxl__gc *gc, int domid, const
> >> libxl_device_disk *disk);
> >> +/* Same as normal, but "translated" */
> > You can use the IDL to do internal stuff too -- see
> > tools/libxl/libxl_types_internal.idl
> >
> > What does "translated" mean? Which fields and how? Might it be better to
> > include a pointer to the original libxl_device_usb instead of
> > duplicating some/all of these fields?
>
> I think one of the biggest thing was avoiding having to look up the
> stubdomain in a bunch of different functions -- that's the dm_domid.
Yet you look it up in the two exact places that you use it...
> There's also the translation of "AUTO" protocol into PV or HVM, and
> (originally) the translation of BACKEND_DEFAULT into the actual backend
> domain.
>
> If we were willing to have the library change the protocol in the
> structure passed to it, then a pointer might work as well.
This is normal libxl behaviour, implemented via the setdefault function.
> > If you remove this and pass target_domid as a parameter to various
> > functions (which is the convention in libxl) then the need for this
> > weird internal/external representation goes away.
>
> There's also the resolution of protocol from ANY into PV or HVM; but if
> we're willing to change the structure passed in by the caller, then yes,
> we can get rid of this struct for now and consider re-introducing it
> if/when we actually need it.
Yes, please just nuke it.
> >> +static int libxl__qmp_usb_hostdev_add(libxl__gc *gc, int domid,
> >> + libxl__device_usb *dev)
> >> +{
> >> + libxl__json_object *args = NULL;
> >> + char *id;
> >> +
> >> + id = GCSPRINTF(HOST_USB_QDEV_ID,
> >> + (uint16_t)dev->u.hostdev.hostbus,
> >> + (uint16_t)dev->u.hostdev.hostaddr);
> > You could make these uint16 in the IDL if you wanted to restrict it like
> > that. Even without that is the cast really necessary though, given the
> > %x format string?
> >
> > If you do use uint16_t then you probably want to use PRIx16 too.
>
> This actually a vestigial artifact from the fact that you could
> originally specify ANY in the field, which was encoded as -1. I'll just
> take out now.
OK. BTW I saw some others that I didn't comment on, so you may want to
grep around a bit.
>
> >> +
> >> + qmp_parameters_add_string(gc, &args, "driver", "usb-host");
> >> + QMP_PARAMETERS_SPRINTF(&args, "hostbus", "0x%x",
> >> dev->u.hostdev.hostbus);
> >> + QMP_PARAMETERS_SPRINTF(&args, "hostaddr", "0x%x",
> >> dev->u.hostdev.hostaddr);
> >> +
> >> + qmp_parameters_add_string(gc, &args, "id", id);
> >> +
> >> + return qmp_run_command(gc, domid, "device_add", args, NULL, NULL);
> >> +}
> >> +
> >> +int libxl__qmp_usb_add(libxl__gc *gc, int domid, libxl__device_usb
> >> *usbdev)
> >> +{
> >> + int rc;
> >> + switch (usbdev->type) {
> >> + case LIBXL_DEVICE_USB_TYPE_HOSTDEV:
> > Will this function ever handle anything other than HOSTDEV? AIUI the
> > only other potential type is PV which won't come anywhere near here?
>
> You're mixing up protocol and device type. PV will only ever handle
> HOSTDEV types, but qmp allows a wide range of virtual devices: tablets,
> mice, keyboards, thumb drives, &c. I'd like at some point for all USB
> devices specified in the config file to be able to be listed and
> hot-plugged / hot-unplugged.
Ah, right.
> > (same comments on the remove bits)
> >
> >> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> >> index fcb1ecd..3c6a709 100644
> >> --- a/tools/libxl/libxl_types.idl
> >> +++ b/tools/libxl/libxl_types.idl
> >> @@ -408,6 +408,28 @@ libxl_device_vtpm = Struct("device_vtpm", [
> >> ("uuid", libxl_uuid),
> >> ])
> >>
> >> +libxl_device_usb_protocol = Enumeration("usb_protocol", [
> >> + (0, "AUTO"),
> >> + (1, "PV"),
> >> + (2, "DEVICEMODEL"),
> >> + ])
> >> +
> >> +libxl_device_usb_type = Enumeration("device_usb_type", [
> >> + (1, "HOSTDEV"),
> >> + ])
> >> +
> >> +libxl_device_usb = Struct("device_usb", [
> >> + ("protocol", libxl_device_usb_protocol,
> >> + {'init_val': 'LIBXL_USB_PROTOCOL_AUTO'}),
> >> + ("backend_domid", libxl_domid,
> >> + {'init_val': 'LIBXL_DEVICE_USB_BACKEND_DEFAULT'}),
> >> + ("u", KeyedUnion(None, libxl_device_usb_type, "type",
> >> + [("hostdev", Struct(None, [
> >> + ("hostbus", integer),
> >> + ("hostaddr", integer) ]))
> >> + ]))
> >> + ])
> >> +
> >> libxl_domain_config = Struct("domain_config", [
> >> ("c_info", libxl_domain_create_info),
> >> ("b_info", libxl_domain_build_info),
> > Do you not want to add a list of USB devices to the domain_build_info?
>
> I don't think I can get that functionality working for 4.3. It's
> definitely on my plans for the future, though.
It should just be a case of
("usbdevs", Array(libxl_device_usb, "num_usbdevs")),
in the idl and
for (i = 0; i < d_config->num_usbdevs; i++)
libxl__device_usb_add(gc, domid, &d_config->usbdevs[i], 1);
in e.g. domcreate_attach_pci (which would then be better named
domcreate_attach_sync_devices or something).
> >
> >> +#define USB_HOSTDEV_ID "hostdev-%04x-%04x"
> >> +
> >> +/*
> >> + * Just use plain numbers for now. Replace these with strings at some
> >> point.
> >> + */
> >> +static char * hostdev_xs_path(libxl__gc *gc, uint32_t domid,
> >> + libxl__device_usb *usbdev)
> >> +{
> >> + return GCSPRINTF(USB_INFO_PATH "/%s",
> >> + libxl__xs_libxl_path(gc, domid),
> >> + GCSPRINTF(USB_HOSTDEV_ID,
> >> + (uint16_t)usbdev->u.hostdev.hostbus,
> >> + (uint16_t)usbdev->u.hostdev.hostaddr));
> >> +}
> >> +
> >> +static void hostdev_xs_append_params(libxl__gc *gc, libxl__device_usb
> >> *usbdev,
> >> + flexarray_t *a)
> >> +{
> >> + flexarray_append_pair(a, "hostbus",
> >> + GCSPRINTF("%d",
> >> + usbdev->u.hostdev.hostbus));
> >> + flexarray_append_pair(a, "hostaddr",
> >> + GCSPRINTF("%d",
> >> + usbdev->u.hostdev.hostaddr));
> > Are the second and third lines > 80 chars in total?
>
> You mean, "Why did you break the GSPRINTF into two lines?" Yes, because
> on one line it's > 80 chars.
OK.
> >> +int libxl_device_usb_add(libxl_ctx *ctx, uint32_t domid,
> >> + libxl_device_usb *usbdev,
> >> + const libxl_asyncop_how *ao_how)
> >> +{
> >> + AO_CREATE(ctx, domid, ao_how);
> >> + int rc;
> >> + rc = libxl__device_usb_add(gc, domid, usbdev);
> >> + libxl__ao_complete(egc, ao, rc);
> >> + return AO_INPROGRESS;
> >> +}
> > Please define this (and the remove) using the DEFINE_DEVICE_ADD/REMOVE
> > macros in libxl.c. Not least because I'm not convinced your handling of
> > the AO stuff is correct (or indeed present).
> >
> > This will probably require the libxl__device_usb_add/remove to change to
> > do the AIO stuff too -- i.e. at the end:
> > aodev->rc = rc;
> > if (rc) aodev->callback(egc, aodev);
> > return;
>
> These follow the template set by
> libxl_pci.c:libxl_device_pci_{add,remove,destroy}(), which were chosen
> specifically because they essentially do a null ASYNC, but
> interface-wise allow for real async to be added in the future.
Ah, OK then.
Ian.
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |