From 137847e55dff11cbbb96785105aa821b66de900c Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Fri, 22 Jun 2007 13:16:10 +0000 Subject: [PATCH] Fri Jun 22 14:15:00 BST 2007 Richard W.M. Jones * qemud/remote.c, qemud/remote_protocol.x, src/remote_internal.c: Add support for setting scheduler parameters over remote connections. --- ChangeLog | 6 + qemud/remote.c | 165 ++++++++++++++++++++++++++++ qemud/remote_dispatch_localvars.h | 5 + qemud/remote_dispatch_proc_switch.h | 24 ++++ qemud/remote_dispatch_prototypes.h | 3 + qemud/remote_protocol.c | 102 +++++++++++++++++ qemud/remote_protocol.h | 71 ++++++++++++ qemud/remote_protocol.x | 54 ++++++++- src/remote_internal.c | 141 ++++++++++++++++++++++++ 9 files changed, 570 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ca38f9763b..5fd45c52fb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Fri Jun 22 14:15:00 BST 2007 Richard W.M. Jones + + * qemud/remote.c, qemud/remote_protocol.x, src/remote_internal.c: + Add support for setting scheduler parameters over remote + connections. + Fri Jun 22 12:40:00 BST 2007 Richard W.M. Jones * src/internal.h: Added STREQ and STRCASEEQ macros for clearer diff --git a/qemud/remote.c b/qemud/remote.c index 94540794b4..acd72a2b50 100644 --- a/qemud/remote.c +++ b/qemud/remote.c @@ -515,6 +515,171 @@ remoteDispatchGetCapabilities (struct qemud_client *client, return 0; } +static int +remoteDispatchDomainGetSchedulerType (struct qemud_client *client, + remote_message_header *req, + remote_domain_get_scheduler_type_args *args, + remote_domain_get_scheduler_type_ret *ret) +{ + virDomainPtr dom; + char *type; + int nparams; + CHECK_CONN(client); + + dom = get_nonnull_domain (client->conn, args->dom); + if (dom == NULL) { + remoteDispatchError (client, req, "domain not found"); + return -2; + } + + type = virDomainGetSchedulerType (dom, &nparams); + if (type == NULL) return -1; + + ret->type = type; + ret->nparams = nparams; + return 0; +} + +static int +remoteDispatchDomainGetSchedulerParameters (struct qemud_client *client, + remote_message_header *req, + remote_domain_get_scheduler_parameters_args *args, + remote_domain_get_scheduler_parameters_ret *ret) +{ + virDomainPtr dom; + virSchedParameterPtr params; + int i, r, nparams; + CHECK_CONN(client); + + nparams = args->nparams; + + if (nparams > REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX) { + remoteDispatchError (client, req, "nparams too large"); + return -2; + } + params = malloc (sizeof (virSchedParameter) * nparams); + if (params == NULL) { + remoteDispatchError (client, req, "out of memory allocating array"); + return -2; + } + + dom = get_nonnull_domain (client->conn, args->dom); + if (dom == NULL) { + free (params); + remoteDispatchError (client, req, "domain not found"); + return -2; + } + + r = virDomainGetSchedulerParameters (dom, params, &nparams); + if (r == -1) { + free (params); + return -1; + } + + /* Serialise the scheduler parameters. */ + ret->params.params_len = nparams; + ret->params.params_val = malloc (sizeof (struct remote_sched_param) + * nparams); + if (ret->params.params_val == NULL) { + free (params); + remoteDispatchError (client, req, + "out of memory allocating return array"); + return -2; + } + + for (i = 0; i < nparams; ++i) { + // remoteDispatchClientRequest will free this: + ret->params.params_val[i].field = strdup (params[i].field); + if (ret->params.params_val[i].field == NULL) { + free (params); + remoteDispatchError (client, req, + "out of memory allocating return array"); + return -2; + } + ret->params.params_val[i].value.type = params[i].type; + switch (params[i].type) { + case VIR_DOMAIN_SCHED_FIELD_INT: + ret->params.params_val[i].value.remote_sched_param_value_u.i = params[i].value.i; break; + case VIR_DOMAIN_SCHED_FIELD_UINT: + ret->params.params_val[i].value.remote_sched_param_value_u.ui = params[i].value.ui; break; + case VIR_DOMAIN_SCHED_FIELD_LLONG: + ret->params.params_val[i].value.remote_sched_param_value_u.l = params[i].value.l; break; + case VIR_DOMAIN_SCHED_FIELD_ULLONG: + ret->params.params_val[i].value.remote_sched_param_value_u.ul = params[i].value.ul; break; + case VIR_DOMAIN_SCHED_FIELD_DOUBLE: + ret->params.params_val[i].value.remote_sched_param_value_u.d = params[i].value.d; break; + case VIR_DOMAIN_SCHED_FIELD_BOOLEAN: + ret->params.params_val[i].value.remote_sched_param_value_u.b = params[i].value.b; break; + default: + free (params); + remoteDispatchError (client, req, "unknown type"); + return -2; + } + } + free (params); + + return 0; +} + +static int +remoteDispatchDomainSetSchedulerParameters (struct qemud_client *client, + remote_message_header *req, + remote_domain_set_scheduler_parameters_args *args, + void *ret ATTRIBUTE_UNUSED) +{ + virDomainPtr dom; + int i, r, nparams; + virSchedParameterPtr params; + CHECK_CONN(client); + + nparams = args->params.params_len; + + if (nparams > REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX) { + remoteDispatchError (client, req, "nparams too large"); + return -2; + } + params = malloc (sizeof (virSchedParameter) * nparams); + if (params == NULL) { + remoteDispatchError (client, req, "out of memory allocating array"); + return -2; + } + + /* Deserialise parameters. */ + for (i = 0; i < nparams; ++i) { + strncpy (params[i].field, args->params.params_val[i].field, + VIR_DOMAIN_SCHED_FIELD_LENGTH); + params[i].field[VIR_DOMAIN_SCHED_FIELD_LENGTH-1] = '\0'; + params[i].type = args->params.params_val[i].value.type; + switch (params[i].type) { + case VIR_DOMAIN_SCHED_FIELD_INT: + params[i].value.i = args->params.params_val[i].value.remote_sched_param_value_u.i; break; + case VIR_DOMAIN_SCHED_FIELD_UINT: + params[i].value.ui = args->params.params_val[i].value.remote_sched_param_value_u.ui; break; + case VIR_DOMAIN_SCHED_FIELD_LLONG: + params[i].value.l = args->params.params_val[i].value.remote_sched_param_value_u.l; break; + case VIR_DOMAIN_SCHED_FIELD_ULLONG: + params[i].value.ul = args->params.params_val[i].value.remote_sched_param_value_u.ul; break; + case VIR_DOMAIN_SCHED_FIELD_DOUBLE: + params[i].value.d = args->params.params_val[i].value.remote_sched_param_value_u.d; break; + case VIR_DOMAIN_SCHED_FIELD_BOOLEAN: + params[i].value.b = args->params.params_val[i].value.remote_sched_param_value_u.b; break; + } + } + + dom = get_nonnull_domain (client->conn, args->dom); + if (dom == NULL) { + free (params); + remoteDispatchError (client, req, "domain not found"); + return -2; + } + + r = virDomainSetSchedulerParameters (dom, params, nparams); + free (params); + if (r == -1) return -1; + + return 0; +} + static int remoteDispatchDomainAttachDevice (struct qemud_client *client, remote_message_header *req, diff --git a/qemud/remote_dispatch_localvars.h b/qemud/remote_dispatch_localvars.h index 12543d5f59..a7a00e7275 100644 --- a/qemud/remote_dispatch_localvars.h +++ b/qemud/remote_dispatch_localvars.h @@ -20,6 +20,8 @@ remote_domain_get_os_type_ret lv_remote_domain_get_os_type_ret; remote_domain_get_autostart_args lv_remote_domain_get_autostart_args; remote_domain_get_autostart_ret lv_remote_domain_get_autostart_ret; remote_domain_set_vcpus_args lv_remote_domain_set_vcpus_args; +remote_domain_get_scheduler_type_args lv_remote_domain_get_scheduler_type_args; +remote_domain_get_scheduler_type_ret lv_remote_domain_get_scheduler_type_ret; remote_network_undefine_args lv_remote_network_undefine_args; remote_domain_create_args lv_remote_domain_create_args; remote_domain_suspend_args lv_remote_domain_suspend_args; @@ -52,6 +54,7 @@ remote_domain_reboot_args lv_remote_domain_reboot_args; remote_domain_set_memory_args lv_remote_domain_set_memory_args; remote_domain_create_linux_args lv_remote_domain_create_linux_args; remote_domain_create_linux_ret lv_remote_domain_create_linux_ret; +remote_domain_set_scheduler_parameters_args lv_remote_domain_set_scheduler_parameters_args; remote_domain_attach_device_args lv_remote_domain_attach_device_args; remote_domain_lookup_by_id_args lv_remote_domain_lookup_by_id_args; remote_domain_lookup_by_id_ret lv_remote_domain_lookup_by_id_ret; @@ -75,6 +78,8 @@ remote_domain_define_xml_args lv_remote_domain_define_xml_args; remote_domain_define_xml_ret lv_remote_domain_define_xml_ret; remote_domain_get_vcpus_args lv_remote_domain_get_vcpus_args; remote_domain_get_vcpus_ret lv_remote_domain_get_vcpus_ret; +remote_domain_get_scheduler_parameters_args lv_remote_domain_get_scheduler_parameters_args; +remote_domain_get_scheduler_parameters_ret lv_remote_domain_get_scheduler_parameters_ret; remote_domain_dump_xml_args lv_remote_domain_dump_xml_args; remote_domain_dump_xml_ret lv_remote_domain_dump_xml_ret; remote_get_max_vcpus_args lv_remote_get_max_vcpus_args; diff --git a/qemud/remote_dispatch_proc_switch.h b/qemud/remote_dispatch_proc_switch.h index 900af3ea85..e00c897357 100644 --- a/qemud/remote_dispatch_proc_switch.h +++ b/qemud/remote_dispatch_proc_switch.h @@ -107,6 +107,24 @@ case REMOTE_PROC_DOMAIN_GET_OS_TYPE: ret = (char *) &lv_remote_domain_get_os_type_ret; memset (&lv_remote_domain_get_os_type_ret, 0, sizeof lv_remote_domain_get_os_type_ret); break; +case REMOTE_PROC_DOMAIN_GET_SCHEDULER_PARAMETERS: + fn = (dispatch_fn) remoteDispatchDomainGetSchedulerParameters; + args_filter = (xdrproc_t) xdr_remote_domain_get_scheduler_parameters_args; + args = (char *) &lv_remote_domain_get_scheduler_parameters_args; + memset (&lv_remote_domain_get_scheduler_parameters_args, 0, sizeof lv_remote_domain_get_scheduler_parameters_args); + ret_filter = (xdrproc_t) xdr_remote_domain_get_scheduler_parameters_ret; + ret = (char *) &lv_remote_domain_get_scheduler_parameters_ret; + memset (&lv_remote_domain_get_scheduler_parameters_ret, 0, sizeof lv_remote_domain_get_scheduler_parameters_ret); + break; +case REMOTE_PROC_DOMAIN_GET_SCHEDULER_TYPE: + fn = (dispatch_fn) remoteDispatchDomainGetSchedulerType; + args_filter = (xdrproc_t) xdr_remote_domain_get_scheduler_type_args; + args = (char *) &lv_remote_domain_get_scheduler_type_args; + memset (&lv_remote_domain_get_scheduler_type_args, 0, sizeof lv_remote_domain_get_scheduler_type_args); + ret_filter = (xdrproc_t) xdr_remote_domain_get_scheduler_type_ret; + ret = (char *) &lv_remote_domain_get_scheduler_type_ret; + memset (&lv_remote_domain_get_scheduler_type_ret, 0, sizeof lv_remote_domain_get_scheduler_type_ret); + break; case REMOTE_PROC_DOMAIN_GET_VCPUS: fn = (dispatch_fn) remoteDispatchDomainGetVcpus; args_filter = (xdrproc_t) xdr_remote_domain_get_vcpus_args; @@ -191,6 +209,12 @@ case REMOTE_PROC_DOMAIN_SET_MEMORY: args = (char *) &lv_remote_domain_set_memory_args; memset (&lv_remote_domain_set_memory_args, 0, sizeof lv_remote_domain_set_memory_args); break; +case REMOTE_PROC_DOMAIN_SET_SCHEDULER_PARAMETERS: + fn = (dispatch_fn) remoteDispatchDomainSetSchedulerParameters; + args_filter = (xdrproc_t) xdr_remote_domain_set_scheduler_parameters_args; + args = (char *) &lv_remote_domain_set_scheduler_parameters_args; + memset (&lv_remote_domain_set_scheduler_parameters_args, 0, sizeof lv_remote_domain_set_scheduler_parameters_args); + break; case REMOTE_PROC_DOMAIN_SET_VCPUS: fn = (dispatch_fn) remoteDispatchDomainSetVcpus; args_filter = (xdrproc_t) xdr_remote_domain_set_vcpus_args; diff --git a/qemud/remote_dispatch_prototypes.h b/qemud/remote_dispatch_prototypes.h index 9bd23cd5e8..67e01d76ce 100644 --- a/qemud/remote_dispatch_prototypes.h +++ b/qemud/remote_dispatch_prototypes.h @@ -16,6 +16,8 @@ static int remoteDispatchDomainGetInfo (struct qemud_client *client, remote_mess static int remoteDispatchDomainGetMaxMemory (struct qemud_client *client, remote_message_header *req, remote_domain_get_max_memory_args *args, remote_domain_get_max_memory_ret *ret); static int remoteDispatchDomainGetMaxVcpus (struct qemud_client *client, remote_message_header *req, remote_domain_get_max_vcpus_args *args, remote_domain_get_max_vcpus_ret *ret); static int remoteDispatchDomainGetOsType (struct qemud_client *client, remote_message_header *req, remote_domain_get_os_type_args *args, remote_domain_get_os_type_ret *ret); +static int remoteDispatchDomainGetSchedulerParameters (struct qemud_client *client, remote_message_header *req, remote_domain_get_scheduler_parameters_args *args, remote_domain_get_scheduler_parameters_ret *ret); +static int remoteDispatchDomainGetSchedulerType (struct qemud_client *client, remote_message_header *req, remote_domain_get_scheduler_type_args *args, remote_domain_get_scheduler_type_ret *ret); static int remoteDispatchDomainGetVcpus (struct qemud_client *client, remote_message_header *req, remote_domain_get_vcpus_args *args, remote_domain_get_vcpus_ret *ret); static int remoteDispatchDomainLookupById (struct qemud_client *client, remote_message_header *req, remote_domain_lookup_by_id_args *args, remote_domain_lookup_by_id_ret *ret); static int remoteDispatchDomainLookupByName (struct qemud_client *client, remote_message_header *req, remote_domain_lookup_by_name_args *args, remote_domain_lookup_by_name_ret *ret); @@ -28,6 +30,7 @@ static int remoteDispatchDomainSave (struct qemud_client *client, remote_message static int remoteDispatchDomainSetAutostart (struct qemud_client *client, remote_message_header *req, remote_domain_set_autostart_args *args, void *ret); static int remoteDispatchDomainSetMaxMemory (struct qemud_client *client, remote_message_header *req, remote_domain_set_max_memory_args *args, void *ret); static int remoteDispatchDomainSetMemory (struct qemud_client *client, remote_message_header *req, remote_domain_set_memory_args *args, void *ret); +static int remoteDispatchDomainSetSchedulerParameters (struct qemud_client *client, remote_message_header *req, remote_domain_set_scheduler_parameters_args *args, void *ret); static int remoteDispatchDomainSetVcpus (struct qemud_client *client, remote_message_header *req, remote_domain_set_vcpus_args *args, void *ret); static int remoteDispatchDomainShutdown (struct qemud_client *client, remote_message_header *req, remote_domain_shutdown_args *args, void *ret); static int remoteDispatchDomainSuspend (struct qemud_client *client, remote_message_header *req, remote_domain_suspend_args *args, void *ret); diff --git a/qemud/remote_protocol.c b/qemud/remote_protocol.c index 1bf6157508..ddbf345139 100644 --- a/qemud/remote_protocol.c +++ b/qemud/remote_protocol.c @@ -119,6 +119,53 @@ xdr_remote_vcpu_info (XDR *xdrs, remote_vcpu_info *objp) return TRUE; } +bool_t +xdr_remote_sched_param_value (XDR *xdrs, remote_sched_param_value *objp) +{ + + if (!xdr_int (xdrs, &objp->type)) + return FALSE; + switch (objp->type) { + case VIR_DOMAIN_SCHED_FIELD_INT: + return FALSE; + break; + case VIR_DOMAIN_SCHED_FIELD_UINT: + if (!xdr_u_int (xdrs, &objp->remote_sched_param_value_u.ui)) + return FALSE; + break; + case VIR_DOMAIN_SCHED_FIELD_LLONG: + if (!xdr_quad_t (xdrs, &objp->remote_sched_param_value_u.l)) + return FALSE; + break; + case VIR_DOMAIN_SCHED_FIELD_ULLONG: + if (!xdr_u_quad_t (xdrs, &objp->remote_sched_param_value_u.ul)) + return FALSE; + break; + case VIR_DOMAIN_SCHED_FIELD_DOUBLE: + if (!xdr_double (xdrs, &objp->remote_sched_param_value_u.d)) + return FALSE; + break; + case VIR_DOMAIN_SCHED_FIELD_BOOLEAN: + if (!xdr_int (xdrs, &objp->remote_sched_param_value_u.b)) + return FALSE; + break; + default: + return FALSE; + } + return TRUE; +} + +bool_t +xdr_remote_sched_param (XDR *xdrs, remote_sched_param *objp) +{ + + if (!xdr_remote_nonnull_string (xdrs, &objp->field)) + return FALSE; + if (!xdr_remote_sched_param_value (xdrs, &objp->value)) + return FALSE; + return TRUE; +} + bool_t xdr_remote_open_args (XDR *xdrs, remote_open_args *objp) { @@ -261,6 +308,61 @@ xdr_remote_get_capabilities_ret (XDR *xdrs, remote_get_capabilities_ret *objp) return TRUE; } +bool_t +xdr_remote_domain_get_scheduler_type_args (XDR *xdrs, remote_domain_get_scheduler_type_args *objp) +{ + + if (!xdr_remote_nonnull_domain (xdrs, &objp->dom)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_domain_get_scheduler_type_ret (XDR *xdrs, remote_domain_get_scheduler_type_ret *objp) +{ + + if (!xdr_remote_nonnull_string (xdrs, &objp->type)) + return FALSE; + if (!xdr_int (xdrs, &objp->nparams)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_domain_get_scheduler_parameters_args (XDR *xdrs, remote_domain_get_scheduler_parameters_args *objp) +{ + + if (!xdr_remote_nonnull_domain (xdrs, &objp->dom)) + return FALSE; + if (!xdr_int (xdrs, &objp->nparams)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_domain_get_scheduler_parameters_ret (XDR *xdrs, remote_domain_get_scheduler_parameters_ret *objp) +{ + char **objp_cpp0 = (char **) (void *) &objp->params.params_val; + + if (!xdr_array (xdrs, objp_cpp0, (u_int *) &objp->params.params_len, REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX, + sizeof (remote_sched_param), (xdrproc_t) xdr_remote_sched_param)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_domain_set_scheduler_parameters_args (XDR *xdrs, remote_domain_set_scheduler_parameters_args *objp) +{ + char **objp_cpp0 = (char **) (void *) &objp->params.params_val; + + if (!xdr_remote_nonnull_domain (xdrs, &objp->dom)) + return FALSE; + if (!xdr_array (xdrs, objp_cpp0, (u_int *) &objp->params.params_len, REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX, + sizeof (remote_sched_param), (xdrproc_t) xdr_remote_sched_param)) + return FALSE; + return TRUE; +} + bool_t xdr_remote_list_domains_args (XDR *xdrs, remote_list_domains_args *objp) { diff --git a/qemud/remote_protocol.h b/qemud/remote_protocol.h index 1b009c26a8..ee3d1b0981 100644 --- a/qemud/remote_protocol.h +++ b/qemud/remote_protocol.h @@ -26,6 +26,7 @@ typedef remote_nonnull_string *remote_string; #define REMOTE_VCPUINFO_MAX 2048 #define REMOTE_CPUMAPS_MAX 16384 #define REMOTE_NETWORK_NAME_LIST_MAX 256 +#define REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX 16 typedef char remote_uuid[VIR_UUID_BUFLEN]; @@ -69,6 +70,25 @@ struct remote_vcpu_info { }; typedef struct remote_vcpu_info remote_vcpu_info; +struct remote_sched_param_value { + int type; + union { + int i; + u_int ui; + quad_t l; + u_quad_t ul; + double d; + int b; + } remote_sched_param_value_u; +}; +typedef struct remote_sched_param_value remote_sched_param_value; + +struct remote_sched_param { + remote_nonnull_string field; + remote_sched_param_value value; +}; +typedef struct remote_sched_param remote_sched_param; + struct remote_open_args { remote_string name; int flags; @@ -112,6 +132,40 @@ struct remote_get_capabilities_ret { }; typedef struct remote_get_capabilities_ret remote_get_capabilities_ret; +struct remote_domain_get_scheduler_type_args { + remote_nonnull_domain dom; +}; +typedef struct remote_domain_get_scheduler_type_args remote_domain_get_scheduler_type_args; + +struct remote_domain_get_scheduler_type_ret { + remote_nonnull_string type; + int nparams; +}; +typedef struct remote_domain_get_scheduler_type_ret remote_domain_get_scheduler_type_ret; + +struct remote_domain_get_scheduler_parameters_args { + remote_nonnull_domain dom; + int nparams; +}; +typedef struct remote_domain_get_scheduler_parameters_args remote_domain_get_scheduler_parameters_args; + +struct remote_domain_get_scheduler_parameters_ret { + struct { + u_int params_len; + remote_sched_param *params_val; + } params; +}; +typedef struct remote_domain_get_scheduler_parameters_ret remote_domain_get_scheduler_parameters_ret; + +struct remote_domain_set_scheduler_parameters_args { + remote_nonnull_domain dom; + struct { + u_int params_len; + remote_sched_param *params_val; + } params; +}; +typedef struct remote_domain_set_scheduler_parameters_args remote_domain_set_scheduler_parameters_args; + struct remote_list_domains_args { int maxids; }; @@ -569,6 +623,9 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_CORE_DUMP = 53, REMOTE_PROC_DOMAIN_RESTORE = 54, REMOTE_PROC_DOMAIN_SAVE = 55, + REMOTE_PROC_DOMAIN_GET_SCHEDULER_TYPE = 56, + REMOTE_PROC_DOMAIN_GET_SCHEDULER_PARAMETERS = 57, + REMOTE_PROC_DOMAIN_SET_SCHEDULER_PARAMETERS = 58, }; typedef enum remote_procedure remote_procedure; @@ -607,6 +664,8 @@ extern bool_t xdr_remote_domain (XDR *, remote_domain*); extern bool_t xdr_remote_network (XDR *, remote_network*); extern bool_t xdr_remote_error (XDR *, remote_error*); extern bool_t xdr_remote_vcpu_info (XDR *, remote_vcpu_info*); +extern bool_t xdr_remote_sched_param_value (XDR *, remote_sched_param_value*); +extern bool_t xdr_remote_sched_param (XDR *, remote_sched_param*); extern bool_t xdr_remote_open_args (XDR *, remote_open_args*); extern bool_t xdr_remote_get_type_ret (XDR *, remote_get_type_ret*); extern bool_t xdr_remote_get_version_ret (XDR *, remote_get_version_ret*); @@ -614,6 +673,11 @@ extern bool_t xdr_remote_get_max_vcpus_args (XDR *, remote_get_max_vcpus_args*) extern bool_t xdr_remote_get_max_vcpus_ret (XDR *, remote_get_max_vcpus_ret*); extern bool_t xdr_remote_node_get_info_ret (XDR *, remote_node_get_info_ret*); extern bool_t xdr_remote_get_capabilities_ret (XDR *, remote_get_capabilities_ret*); +extern bool_t xdr_remote_domain_get_scheduler_type_args (XDR *, remote_domain_get_scheduler_type_args*); +extern bool_t xdr_remote_domain_get_scheduler_type_ret (XDR *, remote_domain_get_scheduler_type_ret*); +extern bool_t xdr_remote_domain_get_scheduler_parameters_args (XDR *, remote_domain_get_scheduler_parameters_args*); +extern bool_t xdr_remote_domain_get_scheduler_parameters_ret (XDR *, remote_domain_get_scheduler_parameters_ret*); +extern bool_t xdr_remote_domain_set_scheduler_parameters_args (XDR *, remote_domain_set_scheduler_parameters_args*); extern bool_t xdr_remote_list_domains_args (XDR *, remote_list_domains_args*); extern bool_t xdr_remote_list_domains_ret (XDR *, remote_list_domains_ret*); extern bool_t xdr_remote_num_of_domains_ret (XDR *, remote_num_of_domains_ret*); @@ -700,6 +764,8 @@ extern bool_t xdr_remote_domain (); extern bool_t xdr_remote_network (); extern bool_t xdr_remote_error (); extern bool_t xdr_remote_vcpu_info (); +extern bool_t xdr_remote_sched_param_value (); +extern bool_t xdr_remote_sched_param (); extern bool_t xdr_remote_open_args (); extern bool_t xdr_remote_get_type_ret (); extern bool_t xdr_remote_get_version_ret (); @@ -707,6 +773,11 @@ extern bool_t xdr_remote_get_max_vcpus_args (); extern bool_t xdr_remote_get_max_vcpus_ret (); extern bool_t xdr_remote_node_get_info_ret (); extern bool_t xdr_remote_get_capabilities_ret (); +extern bool_t xdr_remote_domain_get_scheduler_type_args (); +extern bool_t xdr_remote_domain_get_scheduler_type_ret (); +extern bool_t xdr_remote_domain_get_scheduler_parameters_args (); +extern bool_t xdr_remote_domain_get_scheduler_parameters_ret (); +extern bool_t xdr_remote_domain_set_scheduler_parameters_args (); extern bool_t xdr_remote_list_domains_args (); extern bool_t xdr_remote_list_domains_ret (); extern bool_t xdr_remote_num_of_domains_ret (); diff --git a/qemud/remote_protocol.x b/qemud/remote_protocol.x index 1496ac8cb2..6343f7aebb 100644 --- a/qemud/remote_protocol.x +++ b/qemud/remote_protocol.x @@ -75,6 +75,9 @@ const REMOTE_CPUMAPS_MAX = 16384; /* Upper limit on lists of network names. */ const REMOTE_NETWORK_NAME_LIST_MAX = 256; +/* Upper limit on list of scheduler parameters. */ +const REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX = 16; + /* UUID. VIR_UUID_BUFLEN definition comes from libvirt.h */ typedef opaque remote_uuid[VIR_UUID_BUFLEN]; @@ -125,6 +128,29 @@ struct remote_vcpu_info { int cpu; }; +/* Wire encoding of virDomainSchedParameter. + * Note the enum (type) which must remain binary compatible. + */ +union remote_sched_param_value switch (int type) { + case VIR_DOMAIN_SCHED_FIELD_INT: + int i; + case VIR_DOMAIN_SCHED_FIELD_UINT: + unsigned int ui; + case VIR_DOMAIN_SCHED_FIELD_LLONG: + hyper l; + case VIR_DOMAIN_SCHED_FIELD_ULLONG: + unsigned hyper ul; + case VIR_DOMAIN_SCHED_FIELD_DOUBLE: + double d; + case VIR_DOMAIN_SCHED_FIELD_BOOLEAN: + int b; +}; + +struct remote_sched_param { + remote_nonnull_string field; + remote_sched_param_value value; +}; + /*----- Calls. -----*/ /* For each call we may have a 'remote_CALL_args' and 'remote_CALL_ret' @@ -178,6 +204,29 @@ struct remote_get_capabilities_ret { remote_nonnull_string capabilities; }; +struct remote_domain_get_scheduler_type_args { + remote_nonnull_domain dom; +}; + +struct remote_domain_get_scheduler_type_ret { + remote_nonnull_string type; + int nparams; +}; + +struct remote_domain_get_scheduler_parameters_args { + remote_nonnull_domain dom; + int nparams; +}; + +struct remote_domain_get_scheduler_parameters_ret { + remote_sched_param params; +}; + +struct remote_domain_set_scheduler_parameters_args { + remote_nonnull_domain dom; + remote_sched_param params; +}; + struct remote_list_domains_args { int maxids; }; @@ -553,7 +602,10 @@ enum remote_procedure { REMOTE_PROC_NUM_OF_NETWORKS = 52, REMOTE_PROC_DOMAIN_CORE_DUMP = 53, REMOTE_PROC_DOMAIN_RESTORE = 54, - REMOTE_PROC_DOMAIN_SAVE = 55 + REMOTE_PROC_DOMAIN_SAVE = 55, + REMOTE_PROC_DOMAIN_GET_SCHEDULER_TYPE = 56, + REMOTE_PROC_DOMAIN_GET_SCHEDULER_PARAMETERS = 57, + REMOTE_PROC_DOMAIN_SET_SCHEDULER_PARAMETERS = 58 }; /* Custom RPC structure. */ diff --git a/src/remote_internal.c b/src/remote_internal.c index 33107103f7..1ef81b4f41 100644 --- a/src/remote_internal.c +++ b/src/remote_internal.c @@ -1731,6 +1731,144 @@ remoteDomainSetAutostart (virDomainPtr domain, int autostart) return 0; } +static char * +remoteDomainGetSchedulerType (virDomainPtr domain, int *nparams) +{ + remote_domain_get_scheduler_type_args args; + remote_domain_get_scheduler_type_ret ret; + GET_PRIVATE (domain->conn, NULL); + + make_nonnull_domain (&args.dom, domain); + + memset (&ret, 0, sizeof ret); + if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_SCHEDULER_TYPE, + (xdrproc_t) xdr_remote_domain_get_scheduler_type_args, (char *) &args, + (xdrproc_t) xdr_remote_domain_get_scheduler_type_ret, (char *) &ret) == -1) + return NULL; + + if (nparams) *nparams = ret.nparams; + + /* Caller frees this. */ + return ret.type; +} + +static int +remoteDomainGetSchedulerParameters (virDomainPtr domain, + virSchedParameterPtr params, int *nparams) +{ + remote_domain_get_scheduler_parameters_args args; + remote_domain_get_scheduler_parameters_ret ret; + int i; + GET_PRIVATE (domain->conn, -1); + + make_nonnull_domain (&args.dom, domain); + args.nparams = *nparams; + + memset (&ret, 0, sizeof ret); + if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_SCHEDULER_PARAMETERS, + (xdrproc_t) xdr_remote_domain_get_scheduler_parameters_args, (char *) &args, + (xdrproc_t) xdr_remote_domain_get_scheduler_parameters_ret, (char *) &ret) == -1) + return -1; + + /* Check the length of the returned list carefully. */ + if (ret.params.params_len > REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX || + ret.params.params_len > *nparams) { + xdr_free ((xdrproc_t) xdr_remote_domain_get_scheduler_parameters_ret, (char *) &ret); + error (domain->conn, VIR_ERR_RPC, "remoteDomainGetSchedulerParameters: returned number of parameters exceeds limit"); + return -1; + } + *nparams = ret.params.params_len; + + /* Deserialise the result. */ + for (i = 0; i < *nparams; ++i) { + strncpy (params[i].field, ret.params.params_val[i].field, + VIR_DOMAIN_SCHED_FIELD_LENGTH); + params[i].field[VIR_DOMAIN_SCHED_FIELD_LENGTH-1] = '\0'; + params[i].type = ret.params.params_val[i].value.type; + switch (params[i].type) { + case VIR_DOMAIN_SCHED_FIELD_INT: + params[i].value.i = ret.params.params_val[i].value.remote_sched_param_value_u.i; break; + case VIR_DOMAIN_SCHED_FIELD_UINT: + params[i].value.ui = ret.params.params_val[i].value.remote_sched_param_value_u.ui; break; + case VIR_DOMAIN_SCHED_FIELD_LLONG: + params[i].value.l = ret.params.params_val[i].value.remote_sched_param_value_u.l; break; + case VIR_DOMAIN_SCHED_FIELD_ULLONG: + params[i].value.ul = ret.params.params_val[i].value.remote_sched_param_value_u.ul; break; + case VIR_DOMAIN_SCHED_FIELD_DOUBLE: + params[i].value.d = ret.params.params_val[i].value.remote_sched_param_value_u.d; break; + case VIR_DOMAIN_SCHED_FIELD_BOOLEAN: + params[i].value.b = ret.params.params_val[i].value.remote_sched_param_value_u.b; break; + default: + xdr_free ((xdrproc_t) xdr_remote_domain_get_scheduler_parameters_ret, (char *) &ret); + error (domain->conn, VIR_ERR_RPC, "remoteDomainGetSchedulerParameters: unknown parameter type"); + return -1; + } + } + + xdr_free ((xdrproc_t) xdr_remote_domain_get_scheduler_parameters_ret, (char *) &ret); + return 0; +} + +static int +remoteDomainSetSchedulerParameters (virDomainPtr domain, + virSchedParameterPtr params, int nparams) +{ + remote_domain_set_scheduler_parameters_args args; + int i, do_error; + GET_PRIVATE (domain->conn, -1); + + make_nonnull_domain (&args.dom, domain); + + /* Serialise the scheduler parameters. */ + args.params.params_len = nparams; + args.params.params_val = malloc (sizeof (struct remote_sched_param) + * nparams); + if (args.params.params_val == NULL) { + error (domain->conn, VIR_ERR_RPC, "out of memory allocating array"); + return -1; + } + + do_error = 0; + for (i = 0; i < nparams; ++i) { + // call() will free this: + args.params.params_val[i].field = strdup (params[i].field); + if (args.params.params_val[i].field == NULL) { + error (domain->conn, VIR_ERR_NO_MEMORY, "out of memory"); + do_error = 1; + } + args.params.params_val[i].value.type = params[i].type; + switch (params[i].type) { + case VIR_DOMAIN_SCHED_FIELD_INT: + args.params.params_val[i].value.remote_sched_param_value_u.i = params[i].value.i; break; + case VIR_DOMAIN_SCHED_FIELD_UINT: + args.params.params_val[i].value.remote_sched_param_value_u.ui = params[i].value.ui; break; + case VIR_DOMAIN_SCHED_FIELD_LLONG: + args.params.params_val[i].value.remote_sched_param_value_u.l = params[i].value.l; break; + case VIR_DOMAIN_SCHED_FIELD_ULLONG: + args.params.params_val[i].value.remote_sched_param_value_u.ul = params[i].value.ul; break; + case VIR_DOMAIN_SCHED_FIELD_DOUBLE: + args.params.params_val[i].value.remote_sched_param_value_u.d = params[i].value.d; break; + case VIR_DOMAIN_SCHED_FIELD_BOOLEAN: + args.params.params_val[i].value.remote_sched_param_value_u.b = params[i].value.b; break; + default: + error (domain->conn, VIR_ERR_RPC, "unknown parameter type"); + do_error = 1; + } + } + + if (do_error) { + xdr_free ((xdrproc_t) xdr_remote_domain_set_scheduler_parameters_args, (char *) &args); + return -1; + } + + if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_SCHEDULER_PARAMETERS, + (xdrproc_t) xdr_remote_domain_set_scheduler_parameters_args, (char *) &args, + (xdrproc_t) xdr_void, (char *) NULL) == -1) + return -1; + + return 0; +} + /*----------------------------------------------------------------------*/ static int @@ -2499,6 +2637,9 @@ static virDriver driver = { .domainDetachDevice = remoteDomainDetachDevice, .domainGetAutostart = remoteDomainGetAutostart, .domainSetAutostart = remoteDomainSetAutostart, + .domainGetSchedulerType = remoteDomainGetSchedulerType, + .domainGetSchedulerParameters = remoteDomainGetSchedulerParameters, + .domainSetSchedulerParameters = remoteDomainSetSchedulerParameters, }; static virNetworkDriver network_driver = {