From a8cd24b3464b794e6240fc51f90a707d7d8f9ea4 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Tue, 3 Mar 2009 09:27:02 +0000 Subject: [PATCH] Remote protocol / RPC API for sVirt support (James Morris & Dan Walsh) --- ChangeLog | 11 +++++ qemud/remote.c | 70 ++++++++++++++++++++++++++++++ qemud/remote_dispatch_args.h | 1 + qemud/remote_dispatch_prototypes.h | 14 ++++++ qemud/remote_dispatch_ret.h | 2 + qemud/remote_dispatch_table.h | 10 +++++ qemud/remote_protocol.c | 37 ++++++++++++++++ qemud/remote_protocol.h | 37 ++++++++++++++++ qemud/remote_protocol.x | 34 ++++++++++++++- src/remote_internal.c | 63 +++++++++++++++++++++++++++ 10 files changed, 278 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c30a867d7c..74b8b4e893 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +Tue Mar 3 09:25:13 GMT 2009 Daniel P. Berrange + + Remote protocol / RPC API for sVirt support (James Morris & Dan Walsh) + * qemud/remote.c: Handle new RPC calls + * qemud/remote_protocol.x: Add definitions for new RPC calls + * src/remote_internal.c: Implement virDomainGetSecurityLabel() + and virNodeGetSecurityModel() driver methods + * qemud/remote_dispatch_args.h, qemud/remote_dispatch_prototypes.h, + qemud/remote_dispatch_ret.h, qemud/remote_dispatch_table.h, + qemud/remote_protocol.c, qemud/remote_protocol.h: Regenerate + Tue Mar 3 09:12:13 GMT 2009 Daniel P. Berrange Internal driver API for sVirt support (James Morris & Dan Walsh) diff --git a/qemud/remote.c b/qemud/remote.c index bb4cdb0941..8eaa7d66d8 100644 --- a/qemud/remote.c +++ b/qemud/remote.c @@ -1344,6 +1344,76 @@ remoteDispatchDomainGetMaxVcpus (struct qemud_server *server ATTRIBUTE_UNUSED, return 0; } +static int +remoteDispatchDomainGetSecurityLabel(struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, + remote_error *rerr, + remote_domain_get_security_label_args *args, + remote_domain_get_security_label_ret *ret) +{ + virDomainPtr dom; + virSecurityLabel seclabel; + + dom = get_nonnull_domain(conn, args->dom); + if (dom == NULL) { + remoteDispatchConnError(rerr, conn); + return -1; + } + + memset(&seclabel, 0, sizeof seclabel); + if (virDomainGetSecurityLabel(dom, &seclabel) == -1) { + virDomainFree(dom); + remoteDispatchFormatError(rerr, "%s", _("unable to get security label")); + return -1; + } + + ret->label.label_len = strlen(seclabel.label) + 1; + if (VIR_ALLOC_N(ret->label.label_val, ret->label.label_len) < 0) { + virDomainFree(dom); + remoteDispatchOOMError(rerr); + return -1; + } + strcpy(ret->label.label_val, seclabel.label); + ret->enforcing = seclabel.enforcing; + virDomainFree(dom); + + return 0; +} + +static int +remoteDispatchNodeGetSecurityModel(struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, + remote_error *rerr, + void *args ATTRIBUTE_UNUSED, + remote_node_get_security_model_ret *ret) +{ + virSecurityModel secmodel; + + memset(&secmodel, 0, sizeof secmodel); + if (virNodeGetSecurityModel(conn, &secmodel) == -1) { + remoteDispatchFormatError(rerr, "%s", _("unable to get security model")); + return -1; + } + + ret->model.model_len = strlen(secmodel.model) + 1; + if (VIR_ALLOC_N(ret->model.model_val, ret->model.model_len) < 0) { + remoteDispatchOOMError(rerr); + return -1; + } + strcpy(ret->model.model_val, secmodel.model); + + ret->doi.doi_len = strlen(secmodel.doi) + 1; + if (VIR_ALLOC_N(ret->doi.doi_val, ret->doi.doi_len) < 0) { + remoteDispatchOOMError(rerr); + return -1; + } + strcpy(ret->doi.doi_val, secmodel.doi); + + return 0; +} + static int remoteDispatchDomainGetOsType (struct qemud_server *server ATTRIBUTE_UNUSED, struct qemud_client *client ATTRIBUTE_UNUSED, diff --git a/qemud/remote_dispatch_args.h b/qemud/remote_dispatch_args.h index 03a79374a4..657372989f 100644 --- a/qemud/remote_dispatch_args.h +++ b/qemud/remote_dispatch_args.h @@ -102,3 +102,4 @@ remote_node_device_dettach_args val_remote_node_device_dettach_args; 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; diff --git a/qemud/remote_dispatch_prototypes.h b/qemud/remote_dispatch_prototypes.h index 4188c6a626..c44e5cecab 100644 --- a/qemud/remote_dispatch_prototypes.h +++ b/qemud/remote_dispatch_prototypes.h @@ -184,6 +184,13 @@ static int remoteDispatchDomainGetSchedulerType( remote_error *err, remote_domain_get_scheduler_type_args *args, remote_domain_get_scheduler_type_ret *ret); +static int remoteDispatchDomainGetSecurityLabel( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_error *err, + remote_domain_get_security_label_args *args, + remote_domain_get_security_label_ret *ret); static int remoteDispatchDomainGetVcpus( struct qemud_server *server, struct qemud_client *client, @@ -597,6 +604,13 @@ static int remoteDispatchNodeGetInfo( remote_error *err, void *args, remote_node_get_info_ret *ret); +static int remoteDispatchNodeGetSecurityModel( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_error *err, + void *args, + remote_node_get_security_model_ret *ret); static int remoteDispatchNodeListDevices( struct qemud_server *server, struct qemud_client *client, diff --git a/qemud/remote_dispatch_ret.h b/qemud/remote_dispatch_ret.h index 563167faf7..136b1ccac4 100644 --- a/qemud/remote_dispatch_ret.h +++ b/qemud/remote_dispatch_ret.h @@ -86,3 +86,5 @@ remote_node_device_get_parent_ret val_remote_node_device_get_parent_ret; remote_node_device_num_of_caps_ret val_remote_node_device_num_of_caps_ret; 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; diff --git a/qemud/remote_dispatch_table.h b/qemud/remote_dispatch_table.h index 98be9f366e..75f184b132 100644 --- a/qemud/remote_dispatch_table.h +++ b/qemud/remote_dispatch_table.h @@ -607,3 +607,13 @@ .args_filter = (xdrproc_t) xdr_remote_node_device_reset_args, .ret_filter = (xdrproc_t) xdr_void, }, +{ /* DomainGetSecurityLabel => 118 */ + .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 */ + .fn = (dispatch_fn) remoteDispatchNodeGetSecurityModel, + .args_filter = (xdrproc_t) xdr_void, + .ret_filter = (xdrproc_t) xdr_remote_node_get_security_model_ret, +}, diff --git a/qemud/remote_protocol.c b/qemud/remote_protocol.c index b872469457..7f7c628506 100644 --- a/qemud/remote_protocol.c +++ b/qemud/remote_protocol.c @@ -1165,6 +1165,43 @@ xdr_remote_domain_get_max_vcpus_ret (XDR *xdrs, remote_domain_get_max_vcpus_ret return TRUE; } +bool_t +xdr_remote_domain_get_security_label_args (XDR *xdrs, remote_domain_get_security_label_args *objp) +{ + + if (!xdr_remote_nonnull_domain (xdrs, &objp->dom)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_domain_get_security_label_ret (XDR *xdrs, remote_domain_get_security_label_ret *objp) +{ + char **objp_cpp0 = (char **) (void *) &objp->label.label_val; + + if (!xdr_array (xdrs, objp_cpp0, (u_int *) &objp->label.label_len, REMOTE_SECURITY_LABEL_MAX, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + if (!xdr_int (xdrs, &objp->enforcing)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_node_get_security_model_ret (XDR *xdrs, remote_node_get_security_model_ret *objp) +{ + char **objp_cpp1 = (char **) (void *) &objp->doi.doi_val; + char **objp_cpp0 = (char **) (void *) &objp->model.model_val; + + if (!xdr_array (xdrs, objp_cpp0, (u_int *) &objp->model.model_len, REMOTE_SECURITY_MODEL_MAX, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + if (!xdr_array (xdrs, objp_cpp1, (u_int *) &objp->doi.doi_len, REMOTE_SECURITY_DOI_MAX, + sizeof (char), (xdrproc_t) xdr_char)) + return FALSE; + return TRUE; +} + bool_t xdr_remote_domain_attach_device_args (XDR *xdrs, remote_domain_attach_device_args *objp) { diff --git a/qemud/remote_protocol.h b/qemud/remote_protocol.h index e73e5daaa3..75def5e872 100644 --- a/qemud/remote_protocol.h +++ b/qemud/remote_protocol.h @@ -38,6 +38,9 @@ typedef remote_nonnull_string *remote_string; #define REMOTE_AUTH_TYPE_LIST_MAX 20 #define REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX 65536 #define REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX 65536 +#define REMOTE_SECURITY_MODEL_MAX VIR_SECURITY_MODEL_BUFLEN +#define REMOTE_SECURITY_LABEL_MAX VIR_SECURITY_LABEL_BUFLEN +#define REMOTE_SECURITY_DOI_MAX VIR_SECURITY_DOI_BUFLEN typedef char remote_uuid[VIR_UUID_BUFLEN]; @@ -637,6 +640,32 @@ struct remote_domain_get_max_vcpus_ret { }; typedef struct remote_domain_get_max_vcpus_ret remote_domain_get_max_vcpus_ret; +struct remote_domain_get_security_label_args { + remote_nonnull_domain dom; +}; +typedef struct remote_domain_get_security_label_args remote_domain_get_security_label_args; + +struct remote_domain_get_security_label_ret { + struct { + u_int label_len; + char *label_val; + } label; + int enforcing; +}; +typedef struct remote_domain_get_security_label_ret remote_domain_get_security_label_ret; + +struct remote_node_get_security_model_ret { + struct { + u_int model_len; + char *model_val; + } model; + struct { + u_int doi_len; + char *doi_val; + } doi; +}; +typedef struct remote_node_get_security_model_ret remote_node_get_security_model_ret; + struct remote_domain_attach_device_args { remote_nonnull_domain dom; remote_nonnull_string xml; @@ -1366,6 +1395,8 @@ enum remote_procedure { REMOTE_PROC_NODE_DEVICE_DETTACH = 118, REMOTE_PROC_NODE_DEVICE_RE_ATTACH = 119, REMOTE_PROC_NODE_DEVICE_RESET = 120, + REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL = 121, + REMOTE_PROC_NODE_GET_SECURITY_MODEL = 122, }; typedef enum remote_procedure remote_procedure; @@ -1492,6 +1523,9 @@ extern bool_t xdr_remote_domain_get_vcpus_args (XDR *, remote_domain_get_vcpus_ extern bool_t xdr_remote_domain_get_vcpus_ret (XDR *, remote_domain_get_vcpus_ret*); extern bool_t xdr_remote_domain_get_max_vcpus_args (XDR *, remote_domain_get_max_vcpus_args*); extern bool_t xdr_remote_domain_get_max_vcpus_ret (XDR *, remote_domain_get_max_vcpus_ret*); +extern bool_t xdr_remote_domain_get_security_label_args (XDR *, remote_domain_get_security_label_args*); +extern bool_t xdr_remote_domain_get_security_label_ret (XDR *, remote_domain_get_security_label_ret*); +extern bool_t xdr_remote_node_get_security_model_ret (XDR *, remote_node_get_security_model_ret*); extern bool_t xdr_remote_domain_attach_device_args (XDR *, remote_domain_attach_device_args*); extern bool_t xdr_remote_domain_detach_device_args (XDR *, remote_domain_detach_device_args*); extern bool_t xdr_remote_domain_get_autostart_args (XDR *, remote_domain_get_autostart_args*); @@ -1700,6 +1734,9 @@ extern bool_t xdr_remote_domain_get_vcpus_args (); extern bool_t xdr_remote_domain_get_vcpus_ret (); extern bool_t xdr_remote_domain_get_max_vcpus_args (); extern bool_t xdr_remote_domain_get_max_vcpus_ret (); +extern bool_t xdr_remote_domain_get_security_label_args (); +extern bool_t xdr_remote_domain_get_security_label_ret (); +extern bool_t xdr_remote_node_get_security_model_ret (); extern bool_t xdr_remote_domain_attach_device_args (); extern bool_t xdr_remote_domain_detach_device_args (); extern bool_t xdr_remote_domain_get_autostart_args (); diff --git a/qemud/remote_protocol.x b/qemud/remote_protocol.x index 8f760644a5..2d8e6a2025 100644 --- a/qemud/remote_protocol.x +++ b/qemud/remote_protocol.x @@ -115,6 +115,21 @@ const REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX = 65536; */ const REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX = 65536; +/* + * Maximum length of a security model field. + */ +const REMOTE_SECURITY_MODEL_MAX = VIR_SECURITY_MODEL_BUFLEN; + +/* + * Maximum length of a security label field. + */ +const REMOTE_SECURITY_LABEL_MAX = VIR_SECURITY_LABEL_BUFLEN; + +/* + * Maximum length of a security DOI field. + */ +const REMOTE_SECURITY_DOI_MAX = VIR_SECURITY_DOI_BUFLEN; + /* UUID. VIR_UUID_BUFLEN definition comes from libvirt.h */ typedef opaque remote_uuid[VIR_UUID_BUFLEN]; @@ -617,6 +632,20 @@ struct remote_domain_get_max_vcpus_ret { int num; }; +struct remote_domain_get_security_label_args { + remote_nonnull_domain dom; +}; + +struct remote_domain_get_security_label_ret { + char label; + int enforcing; +}; + +struct remote_node_get_security_model_ret { + char model; + char doi; +}; + struct remote_domain_attach_device_args { remote_nonnull_domain dom; remote_nonnull_string xml; @@ -1238,7 +1267,10 @@ enum remote_procedure { REMOTE_PROC_NODE_DEVICE_LIST_CAPS = 117, REMOTE_PROC_NODE_DEVICE_DETTACH = 118, REMOTE_PROC_NODE_DEVICE_RE_ATTACH = 119, - REMOTE_PROC_NODE_DEVICE_RESET = 120 + REMOTE_PROC_NODE_DEVICE_RESET = 120, + + REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL = 121, + REMOTE_PROC_NODE_GET_SECURITY_MODEL = 122 }; /* Custom RPC structure. */ diff --git a/src/remote_internal.c b/src/remote_internal.c index 90c5a5d45f..a45e13f796 100644 --- a/src/remote_internal.c +++ b/src/remote_internal.c @@ -2296,6 +2296,67 @@ done: return rv; } +static int +remoteDomainGetSecurityLabel (virDomainPtr domain, virSecurityLabelPtr seclabel) +{ + remote_domain_get_security_label_args args; + remote_domain_get_security_label_ret ret; + struct private_data *priv = domain->conn->privateData; + + make_nonnull_domain (&args.dom, domain); + memset (&ret, 0, sizeof ret); + if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL, + (xdrproc_t) xdr_remote_domain_get_security_label_args, (char *)&args, + (xdrproc_t) xdr_remote_domain_get_security_label_ret, (char *)&ret) == -1) { + return -1; + } + + if (ret.label.label_val != NULL) { + if (strlen (ret.label.label_val) >= sizeof seclabel->label) { + errorf (domain->conn, VIR_ERR_RPC, _("security label exceeds maximum: %zd"), + sizeof seclabel->label - 1); + return -1; + } + strcpy (seclabel->label, ret.label.label_val); + seclabel->enforcing = ret.enforcing; + } + + return 0; +} + +static int +remoteNodeGetSecurityModel (virConnectPtr conn, virSecurityModelPtr secmodel) +{ + remote_node_get_security_model_ret ret; + struct private_data *priv = conn->privateData; + + memset (&ret, 0, sizeof ret); + if (call (conn, priv, 0, REMOTE_PROC_NODE_GET_SECURITY_MODEL, + (xdrproc_t) xdr_void, NULL, + (xdrproc_t) xdr_remote_node_get_security_model_ret, (char *)&ret) == -1) { + return -1; + } + + if (ret.model.model_val != NULL) { + if (strlen (ret.model.model_val) >= sizeof secmodel->model) { + errorf (conn, VIR_ERR_RPC, _("security model exceeds maximum: %zd"), + sizeof secmodel->model - 1); + return -1; + } + strcpy (secmodel->model, ret.model.model_val); + } + + if (ret.doi.doi_val != NULL) { + if (strlen (ret.doi.doi_val) >= sizeof secmodel->doi) { + errorf (conn, VIR_ERR_RPC, _("security doi exceeds maximum: %zd"), + sizeof secmodel->doi - 1); + return -1; + } + strcpy (secmodel->doi, ret.doi.doi_val); + } + return 0; +} + static char * remoteDomainDumpXML (virDomainPtr domain, int flags) { @@ -6785,6 +6846,8 @@ static virDriver driver = { .domainPinVcpu = remoteDomainPinVcpu, .domainGetVcpus = remoteDomainGetVcpus, .domainGetMaxVcpus = remoteDomainGetMaxVcpus, + .domainGetSecurityLabel = remoteDomainGetSecurityLabel, + .nodeGetSecurityModel = remoteNodeGetSecurityModel, .domainDumpXML = remoteDomainDumpXML, .listDefinedDomains = remoteListDefinedDomains, .numOfDefinedDomains = remoteNumOfDefinedDomains,