On 07/03/2014 01:56 PM, Simon Cao
wrote:
OK -- well I think that's a bit incidental to the core
functionality. I would put off working on this until the core
functionality is working; and then I'd put it in its own patch, so
we can consider whether to include it separately.
Yeah, I understand the logic. But that's how we name network
devices, for instance, which are created from nothing before being
attached. In any case, you're still combining the "create" and the
"attach" operation into one. Having "attach" mean "create and
attach" isn't really that different from having "create" mean
"create and attach".Â
Anyway, I'm pretty sure the maintainers will insist on attach /
detach before accepting it (they asked me to change it when I posted
it a year ago), so you might as well just do it now. :-)
OK -- well I'm sure there will be comments on the exact syntax
before the patches are finally accepted. :-)
So this idl code:
libxl_device_usb = Struct("device_usb", [
ÂÂÂÂÂÂÂ ("protocol", libxl_device_usb_protocol,
ÂÂÂÂÂÂÂÂ {'init_val': 'LIBXL_USB_PROTOCOL_AUTO'}),
ÂÂÂÂÂÂÂ ("backend_domid",ÂÂÂ libxl_domid),
 ("backend_domname", string),
ÂÂÂÂÂÂÂ ("u", KeyedUnion(None, libxl_device_usb_type, "type",
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ [("hostdev", Struct(None, [
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ ("hostbus",ÂÂ integer),
 ("hostaddr", integer) ]))
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ ]))
ÂÂÂ ])
Generated this header code:
typedef struct libxl_device_usb {
ÂÂÂ libxl_usb_protocol protocol;
ÂÂÂ libxl_domid backend_domid;
ÂÂÂ char * backend_domname;
ÂÂÂ libxl_device_usb_type type;
ÂÂÂ union {
ÂÂÂÂÂÂÂ struct {
ÂÂÂÂÂÂÂÂÂÂÂ int hostbus;
ÂÂÂÂÂÂÂÂÂÂÂ int hostaddr;
ÂÂÂÂÂÂÂ } hostdev;
ÂÂÂ } u;
} libxl_device_usb;
void libxl_device_usb_dispose(libxl_device_usb *p);
void libxl_device_usb_init(libxl_device_usb *p);
void libxl_device_usb_init_type(libxl_device_usb *p,
libxl_device_usb_type type);
char *libxl_device_usb_to_json(libxl_ctx *ctx, libxl_device_usb *p);
So first of all it makes a union; so that if we eventually have,
say, a mass storage type, you won't just have to toss all the
possible different parameters into the struct together; it will only
be as long as the longest type. Secondly, it tells the idl compiler
that the value in "type" tells you what kind of union you're dealing
with, so that the "usb_to_json" functions get build properly. For
example, the above idl code generates the following code snippet in
_libxl_types.c:libxl_device_usb_gen_json():
ÂÂÂ switch (p->type) {
ÂÂÂ case LIBXL_DEVICE_USB_TYPE_HOSTDEV:
ÂÂÂÂÂÂÂ s = yajl_gen_map_open(hand);
ÂÂÂÂÂÂÂ if (s != yajl_gen_status_ok)
ÂÂÂÂÂÂÂÂÂÂÂ goto out;
ÂÂÂÂÂÂÂ s = yajl_gen_string(hand, (const unsigned char *)"hostbus",
sizeof("hostbus")-1);
ÂÂÂÂÂÂÂ if (s != yajl_gen_status_ok)
ÂÂÂÂÂÂÂÂÂÂÂ goto out;
ÂÂÂÂÂÂÂ s = yajl_gen_integer(hand, p->u.hostdev.hostbus);
ÂÂÂÂÂÂÂ if (s != yajl_gen_status_ok)
ÂÂÂÂÂÂÂÂÂÂÂ goto out;
ÂÂÂÂÂÂÂ s = yajl_gen_string(hand, (const unsigned char *)"hostaddr",
sizeof("hostaddr")-1);
ÂÂÂÂÂÂÂ if (s != yajl_gen_status_ok)
ÂÂÂÂÂÂÂÂÂÂÂ goto out;
ÂÂÂÂÂÂÂ s = yajl_gen_integer(hand, p->u.hostdev.hostaddr);
ÂÂÂÂÂÂÂ if (s != yajl_gen_status_ok)
ÂÂÂÂÂÂÂÂÂÂÂ goto out;
ÂÂÂÂÂÂÂ s = yajl_gen_map_close(hand);
ÂÂÂÂÂÂÂ if (s != yajl_gen_status_ok)
ÂÂÂÂÂÂÂÂÂÂÂ goto out;
ÂÂÂÂÂÂÂ break;
ÂÂÂ }
So it does specific things based on what "type" is set to: if it's
set to "hostdev" it outputs hostbus and hostaddr; if we added a mass
storage type, and type was set to "storage", it would only output
the information relevant to the mass storage device.
Cool, look forward to the code. :-)
Â-George
|