From: Daniel P. Berrange Date: Fri, 24 Apr 2009 13:11:23 +0000 (+0000) Subject: Add virNodeDeviceCreateXML / virNodeDeviceDestroy boilerplate public API and remote... X-Git-Tag: LIBVIRT_0_6_3~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=62aa1b56d6bb2909877dcc3678f5ff0de2a19455;p=thirdparty%2Flibvirt.git Add virNodeDeviceCreateXML / virNodeDeviceDestroy boilerplate public API and remote protocol impl --- diff --git a/ChangeLog b/ChangeLog index 7c90f6e2e0..ef83ce782b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +Fri Apr 24 14:07:22 BST 2009 Daniel P. Berrange + + Add virNodeDeviceCreateXML / virNodeDeviceDestroy boilerplate + public API and remote protocol impl + * include/libvirt/libvirt.h, include/libvirt/libvirt.h.in, + src/libvirt_public.syms: Public API definition of new + virNodeDeviceCreateXML and virNodeDeviceDestroy methods + * qemud/remote.c: Dispatch code for new APIs + * qemud/remote_dispatch_args.h, qemud/remote_dispatch_prototypes.h, + qemud/remote_dispatch_ret.h, qemud/remote_dispatch_table.h: + Re-generate stubs for dispatcher + * qemud/remote_protocol.x: Define wire protocol for node + device create / destroy APIs + * qemud/remote_protocol.c, qemud/remote_protocol.h: + Re-generate based off protocol additions + * src/driver.h: Define internal driver API contract for + new public APIs + * src/libvirt.c: Wire up public API to driver API for + virNodeDeviceCreateXML/virNodeDeviceDestroy + * src/remote_internal.c: Client for new node device methods + Fri Apr 24 13:19:47 BST 2009 Daniel P. Berrange * src/libvirt_private.syms: Add virDomainHostdevDefFree needed diff --git a/include/libvirt/libvirt.h b/include/libvirt/libvirt.h index bd94a187e4..d640336ad6 100644 --- a/include/libvirt/libvirt.h +++ b/include/libvirt/libvirt.h @@ -1124,6 +1124,12 @@ int virNodeDeviceDettach (virNodeDevicePtr dev); int virNodeDeviceReAttach (virNodeDevicePtr dev); int virNodeDeviceReset (virNodeDevicePtr dev); +virNodeDevicePtr virNodeDeviceCreateXML (virConnectPtr conn, + const char *xmlDesc, + unsigned int flags); + +int virNodeDeviceDestroy (virNodeDevicePtr dev); + /* * Domain Event Notification */ diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index a028b21e88..2f7076fed4 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1124,6 +1124,12 @@ int virNodeDeviceDettach (virNodeDevicePtr dev); int virNodeDeviceReAttach (virNodeDevicePtr dev); int virNodeDeviceReset (virNodeDevicePtr dev); +virNodeDevicePtr virNodeDeviceCreateXML (virConnectPtr conn, + const char *xmlDesc, + unsigned int flags); + +int virNodeDeviceDestroy (virNodeDevicePtr dev); + /* * Domain Event Notification */ diff --git a/qemud/remote.c b/qemud/remote.c index e27820f607..8d24a3a199 100644 --- a/qemud/remote.c +++ b/qemud/remote.c @@ -4323,6 +4323,54 @@ remoteDispatchNodeDeviceReset (struct qemud_server *server ATTRIBUTE_UNUSED, } +static int +remoteDispatchNodeDeviceCreateXml(struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, + remote_error *rerr, + remote_node_device_create_xml_args *args, + remote_node_device_create_xml_ret *ret) +{ + virNodeDevicePtr dev; + + dev = virNodeDeviceCreateXML (conn, args->xml_desc, args->flags); + if (dev == NULL) { + remoteDispatchConnError(rerr, conn); + return -1; + } + + make_nonnull_node_device (&ret->dev, dev); + virNodeDeviceFree(dev); + + return 0; +} + + +static int +remoteDispatchNodeDeviceDestroy(struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, + remote_error *rerr, + remote_node_device_destroy_args *args, + void *ret ATTRIBUTE_UNUSED) +{ + virNodeDevicePtr dev; + + dev = virNodeDeviceLookupByName(conn, args->name); + if (dev == NULL) { + remoteDispatchFormatError(rerr, "%s", _("node_device not found")); + return -1; + } + + if (virNodeDeviceDestroy(dev) == -1) { + remoteDispatchConnError(rerr, conn); + return -1; + } + + return 0; +} + + /************************** * Async Events **************************/ diff --git a/qemud/remote_dispatch_args.h b/qemud/remote_dispatch_args.h index 657372989f..58eccf557d 100644 --- a/qemud/remote_dispatch_args.h +++ b/qemud/remote_dispatch_args.h @@ -103,3 +103,5 @@ remote_node_device_re_attach_args val_remote_node_device_re_attach_args; remote_node_device_reset_args val_remote_node_device_reset_args; remote_domain_get_security_label_args val_remote_domain_get_security_label_args; + remote_node_device_create_xml_args val_remote_node_device_create_xml_args; + remote_node_device_destroy_args val_remote_node_device_destroy_args; diff --git a/qemud/remote_dispatch_prototypes.h b/qemud/remote_dispatch_prototypes.h index c44e5cecab..96dcb2a6b1 100644 --- a/qemud/remote_dispatch_prototypes.h +++ b/qemud/remote_dispatch_prototypes.h @@ -527,6 +527,20 @@ static int remoteDispatchNetworkUndefine( remote_error *err, remote_network_undefine_args *args, void *ret); +static int remoteDispatchNodeDeviceCreateXml( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_error *err, + remote_node_device_create_xml_args *args, + remote_node_device_create_xml_ret *ret); +static int remoteDispatchNodeDeviceDestroy( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_error *err, + remote_node_device_destroy_args *args, + void *ret); static int remoteDispatchNodeDeviceDettach( struct qemud_server *server, struct qemud_client *client, diff --git a/qemud/remote_dispatch_ret.h b/qemud/remote_dispatch_ret.h index 136b1ccac4..3325c8b75e 100644 --- a/qemud/remote_dispatch_ret.h +++ b/qemud/remote_dispatch_ret.h @@ -88,3 +88,4 @@ remote_node_device_list_caps_ret val_remote_node_device_list_caps_ret; remote_domain_get_security_label_ret val_remote_domain_get_security_label_ret; remote_node_get_security_model_ret val_remote_node_get_security_model_ret; + remote_node_device_create_xml_ret val_remote_node_device_create_xml_ret; diff --git a/qemud/remote_dispatch_table.h b/qemud/remote_dispatch_table.h index 75f184b132..ac7f9b996b 100644 --- a/qemud/remote_dispatch_table.h +++ b/qemud/remote_dispatch_table.h @@ -607,13 +607,23 @@ .args_filter = (xdrproc_t) xdr_remote_node_device_reset_args, .ret_filter = (xdrproc_t) xdr_void, }, -{ /* DomainGetSecurityLabel => 118 */ +{ /* DomainGetSecurityLabel => 121 */ .fn = (dispatch_fn) remoteDispatchDomainGetSecurityLabel, .args_filter = (xdrproc_t) xdr_remote_domain_get_security_label_args, .ret_filter = (xdrproc_t) xdr_remote_domain_get_security_label_ret, }, -{ /* NodeGetSecurityModel => 119 */ +{ /* NodeGetSecurityModel => 122 */ .fn = (dispatch_fn) remoteDispatchNodeGetSecurityModel, .args_filter = (xdrproc_t) xdr_void, .ret_filter = (xdrproc_t) xdr_remote_node_get_security_model_ret, }, +{ /* NodeDeviceCreateXml => 123 */ + .fn = (dispatch_fn) remoteDispatchNodeDeviceCreateXml, + .args_filter = (xdrproc_t) xdr_remote_node_device_create_xml_args, + .ret_filter = (xdrproc_t) xdr_remote_node_device_create_xml_ret, +}, +{ /* NodeDeviceDestroy => 124 */ + .fn = (dispatch_fn) remoteDispatchNodeDeviceDestroy, + .args_filter = (xdrproc_t) xdr_remote_node_device_destroy_args, + .ret_filter = (xdrproc_t) xdr_void, +}, diff --git a/qemud/remote_protocol.c b/qemud/remote_protocol.c index 7f7c628506..af3c792dcc 100644 --- a/qemud/remote_protocol.c +++ b/qemud/remote_protocol.c @@ -2229,6 +2229,35 @@ xdr_remote_node_device_reset_args (XDR *xdrs, remote_node_device_reset_args *obj return TRUE; } +bool_t +xdr_remote_node_device_create_xml_args (XDR *xdrs, remote_node_device_create_xml_args *objp) +{ + + if (!xdr_remote_nonnull_string (xdrs, &objp->xml_desc)) + return FALSE; + if (!xdr_int (xdrs, &objp->flags)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_node_device_create_xml_ret (XDR *xdrs, remote_node_device_create_xml_ret *objp) +{ + + if (!xdr_remote_nonnull_node_device (xdrs, &objp->dev)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_node_device_destroy_args (XDR *xdrs, remote_node_device_destroy_args *objp) +{ + + if (!xdr_remote_nonnull_string (xdrs, &objp->name)) + return FALSE; + return TRUE; +} + bool_t xdr_remote_domain_events_register_ret (XDR *xdrs, remote_domain_events_register_ret *objp) { diff --git a/qemud/remote_protocol.h b/qemud/remote_protocol.h index 75def5e872..9d67e58845 100644 --- a/qemud/remote_protocol.h +++ b/qemud/remote_protocol.h @@ -1255,6 +1255,22 @@ struct remote_node_device_reset_args { }; typedef struct remote_node_device_reset_args remote_node_device_reset_args; +struct remote_node_device_create_xml_args { + remote_nonnull_string xml_desc; + int flags; +}; +typedef struct remote_node_device_create_xml_args remote_node_device_create_xml_args; + +struct remote_node_device_create_xml_ret { + remote_nonnull_node_device dev; +}; +typedef struct remote_node_device_create_xml_ret remote_node_device_create_xml_ret; + +struct remote_node_device_destroy_args { + remote_nonnull_string name; +}; +typedef struct remote_node_device_destroy_args remote_node_device_destroy_args; + struct remote_domain_events_register_ret { int cb_registered; }; @@ -1397,6 +1413,8 @@ enum remote_procedure { REMOTE_PROC_NODE_DEVICE_RESET = 120, REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL = 121, REMOTE_PROC_NODE_GET_SECURITY_MODEL = 122, + REMOTE_PROC_NODE_DEVICE_CREATE_XML = 123, + REMOTE_PROC_NODE_DEVICE_DESTROY = 124, }; typedef enum remote_procedure remote_procedure; @@ -1629,6 +1647,9 @@ extern bool_t xdr_remote_node_device_list_caps_ret (XDR *, remote_node_device_l extern bool_t xdr_remote_node_device_dettach_args (XDR *, remote_node_device_dettach_args*); extern bool_t xdr_remote_node_device_re_attach_args (XDR *, remote_node_device_re_attach_args*); extern bool_t xdr_remote_node_device_reset_args (XDR *, remote_node_device_reset_args*); +extern bool_t xdr_remote_node_device_create_xml_args (XDR *, remote_node_device_create_xml_args*); +extern bool_t xdr_remote_node_device_create_xml_ret (XDR *, remote_node_device_create_xml_ret*); +extern bool_t xdr_remote_node_device_destroy_args (XDR *, remote_node_device_destroy_args*); extern bool_t xdr_remote_domain_events_register_ret (XDR *, remote_domain_events_register_ret*); extern bool_t xdr_remote_domain_events_deregister_ret (XDR *, remote_domain_events_deregister_ret*); extern bool_t xdr_remote_domain_event_ret (XDR *, remote_domain_event_ret*); @@ -1840,6 +1861,9 @@ extern bool_t xdr_remote_node_device_list_caps_ret (); extern bool_t xdr_remote_node_device_dettach_args (); extern bool_t xdr_remote_node_device_re_attach_args (); extern bool_t xdr_remote_node_device_reset_args (); +extern bool_t xdr_remote_node_device_create_xml_args (); +extern bool_t xdr_remote_node_device_create_xml_ret (); +extern bool_t xdr_remote_node_device_destroy_args (); extern bool_t xdr_remote_domain_events_register_ret (); extern bool_t xdr_remote_domain_events_deregister_ret (); extern bool_t xdr_remote_domain_event_ret (); diff --git a/qemud/remote_protocol.x b/qemud/remote_protocol.x index 2d8e6a2025..2c79949f96 100644 --- a/qemud/remote_protocol.x +++ b/qemud/remote_protocol.x @@ -1109,6 +1109,19 @@ struct remote_node_device_reset_args { remote_nonnull_string name; }; +struct remote_node_device_create_xml_args { + remote_nonnull_string xml_desc; + int flags; +}; + +struct remote_node_device_create_xml_ret { + remote_nonnull_node_device dev; +}; + +struct remote_node_device_destroy_args { + remote_nonnull_string name; +}; + /** * Events Register/Deregister: @@ -1270,7 +1283,10 @@ enum remote_procedure { REMOTE_PROC_NODE_DEVICE_RESET = 120, REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL = 121, - REMOTE_PROC_NODE_GET_SECURITY_MODEL = 122 + REMOTE_PROC_NODE_GET_SECURITY_MODEL = 122, + + REMOTE_PROC_NODE_DEVICE_CREATE_XML = 123, + REMOTE_PROC_NODE_DEVICE_DESTROY = 124 }; /* Custom RPC structure. */ diff --git a/src/driver.h b/src/driver.h index 39dc4136b6..c357b76321 100644 --- a/src/driver.h +++ b/src/driver.h @@ -684,6 +684,11 @@ typedef int (*virDevMonDeviceListCaps)(virNodeDevicePtr dev, char **const names, int maxnames); +typedef virNodeDevicePtr (*virDrvNodeDeviceCreateXML)(virConnectPtr conn, + const char *xmlDesc, + unsigned int flags); +typedef int (*virDrvNodeDeviceDestroy)(virNodeDevicePtr dev); + /** * _virDeviceMonitor: * @@ -702,6 +707,8 @@ struct _virDeviceMonitor { virDevMonDeviceGetParent deviceGetParent; virDevMonDeviceNumOfCaps deviceNumOfCaps; virDevMonDeviceListCaps deviceListCaps; + virDrvNodeDeviceCreateXML deviceCreateXML; + virDrvNodeDeviceDestroy deviceDestroy; }; /* diff --git a/src/libvirt.c b/src/libvirt.c index 95a861ea41..9bf2dd9511 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -7491,6 +7491,103 @@ error: } +/** + * virNodeDeviceCreateXML: + * @conn: pointer to the hypervisor connection + * @xmlDesc: string containing an XML description of the device to be created + * @flags: callers should always pass 0 + * + * Create a new device on the VM host machine, for example, virtual + * HBAs created using vport_create. + * + * Returns a node device object if successful, NULL in case of failure + */ +virNodeDevicePtr +virNodeDeviceCreateXML(virConnectPtr conn, + const char *xmlDesc, + unsigned int flags) +{ + VIR_DEBUG("conn=%p, xmlDesc=%s, flags=%d", conn, xmlDesc, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__); + return NULL; + } + + if (conn->flags & VIR_CONNECT_RO) { + virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__); + goto error; + } + + if (xmlDesc == NULL) { + virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + + if (conn->deviceMonitor && + conn->deviceMonitor->deviceCreateXML) { + virNodeDevicePtr dev = conn->deviceMonitor->deviceCreateXML(conn, xmlDesc, flags); + if (dev == NULL) + goto error; + return dev; + } + + virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + /* Copy to connection error object for back compatability */ + virSetConnError(conn); + return NULL; +} + + +/** + * virNodeDeviceDestroy: + * @dev: a device object + * + * Destroy the device object. The virtual device is removed from the host operating system. + * This function may require privileged access + * + * Returns 0 in case of success and -1 in case of failure. + */ +int +virNodeDeviceDestroy(virNodeDevicePtr dev) +{ + DEBUG("dev=%p", dev); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) { + virLibNodeDeviceError(NULL, VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__); + return (-1); + } + + if (dev->conn->flags & VIR_CONNECT_RO) { + virLibConnError(dev->conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__); + goto error; + } + + if (dev->conn->deviceMonitor && + dev->conn->deviceMonitor->deviceDestroy) { + int retval = dev->conn->deviceMonitor->deviceDestroy(dev); + if (retval < 0) { + goto error; + } + + return 0; + } + + virLibConnError (dev->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + /* Copy to connection error object for back compatability */ + virSetConnError(dev->conn); + return -1; +} + + /* * Domain Event Notification */ diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index f7ebbc39ab..b8f9128a93 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -258,4 +258,10 @@ LIBVIRT_0.6.1 { virNodeGetSecurityModel; } LIBVIRT_0.6.0; +LIBVIRT_0.6.3 { + global: + virNodeDeviceCreateXML; + virNodeDeviceDestroy; +} LIBVIRT_0.6.1; + # .... define new API here using predicted next version number .... diff --git a/src/remote_internal.c b/src/remote_internal.c index 575bf5d3b9..24226e5023 100644 --- a/src/remote_internal.c +++ b/src/remote_internal.c @@ -4987,6 +4987,59 @@ done: } +static virNodeDevicePtr +remoteNodeDeviceCreateXML(virConnectPtr conn, + const char *xmlDesc, + unsigned int flags) +{ + remote_node_device_create_xml_args args; + remote_node_device_create_xml_ret ret; + virNodeDevicePtr dev = NULL; + struct private_data *priv = conn->privateData; + + remoteDriverLock(priv); + + memset(&ret, 0, sizeof ret); + args.xml_desc = (char *)xmlDesc; + args.flags = flags; + + if (call(conn, priv, 0, REMOTE_PROC_NODE_DEVICE_CREATE_XML, + (xdrproc_t) xdr_remote_node_device_create_xml_args, (char *) &args, + (xdrproc_t) xdr_remote_node_device_create_xml_ret, (char *) &ret) == -1) + goto done; + + dev = get_nonnull_node_device(conn, ret.dev); + xdr_free ((xdrproc_t) xdr_remote_node_device_create_xml_ret, (char *) &ret); + +done: + remoteDriverUnlock(priv); + return dev; +} + +static int +remoteNodeDeviceDestroy(virNodeDevicePtr dev) +{ + int rv = -1; + remote_node_device_destroy_args args; + struct private_data *priv = dev->conn->privateData; + + remoteDriverLock(priv); + + args.name = dev->name; + + if (call(dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_RESET, + (xdrproc_t) xdr_remote_node_device_destroy_args, (char *) &args, + (xdrproc_t) xdr_void, (char *) NULL) == -1) + goto done; + + rv = 0; + +done: + remoteDriverUnlock(priv); + return rv; +} + + /*----------------------------------------------------------------------*/ static int @@ -6991,6 +7044,8 @@ static virDeviceMonitor dev_monitor = { .deviceGetParent = remoteNodeDeviceGetParent, .deviceNumOfCaps = remoteNodeDeviceNumOfCaps, .deviceListCaps = remoteNodeDeviceListCaps, + .deviceCreateXML = remoteNodeDeviceCreateXML, + .deviceDestroy = remoteNodeDeviceDestroy };