diff --git a/daemon/remote.c b/daemon/remote.c index 7b38a1953f..42e1cb9413 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -687,6 +687,77 @@ cleanup: return rv; } +static int +remoteDispatchDomainSetSchedulerParametersFlags(struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, + remote_message_header *hdr ATTRIBUTE_UNUSED, + remote_error *rerr, + remote_domain_set_scheduler_parameters_flags_args *args, + void *ret ATTRIBUTE_UNUSED) +{ + virDomainPtr dom = NULL; + virSchedParameterPtr params = NULL; + int i, nparams; + int rv = -1; + + if (!conn) { + virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open")); + goto cleanup; + } + + nparams = args->params.params_len; + + if (nparams > REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX) { + virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large")); + goto cleanup; + } + if (VIR_ALLOC_N(params, nparams) < 0) { + virReportOOMError(); + goto cleanup; + } + + /* Deserialise parameters. */ + for (i = 0; i < nparams; ++i) { + if (virStrcpyStatic(params[i].field, args->params.params_val[i].field) == NULL) { + virNetError(VIR_ERR_INTERNAL_ERROR, _("Field %s too big for destination"), + args->params.params_val[i].field); + goto cleanup; + } + 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; + } + } + + if (!(dom = get_nonnull_domain(conn, args->dom))) + goto cleanup; + + if (virDomainSetSchedulerParametersFlags(dom, params, nparams, args->flags) < 0) + goto cleanup; + + rv = 0; + +cleanup: + if (rv < 0) + remoteDispatchError(rerr); + if (dom) + virDomainFree(dom); + VIR_FREE(params); + return rv; +} + static int remoteDispatchDomainMemoryStats(struct qemud_server *server ATTRIBUTE_UNUSED, struct qemud_client *client ATTRIBUTE_UNUSED, diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 08f5046a71..8c69743604 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -2636,6 +2636,74 @@ done: return rv; } +static int +remoteDomainSetSchedulerParametersFlags(virDomainPtr domain, + virSchedParameterPtr params, + int nparams, + unsigned int flags) +{ + int rv = -1; + remote_domain_set_scheduler_parameters_flags_args args; + int i, do_error; + struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); + + make_nonnull_domain (&args.dom, domain); + + /* Serialise the scheduler parameters. */ + args.params.params_len = nparams; + args.flags = flags; + if (VIR_ALLOC_N(args.params.params_val, nparams) < 0) { + virReportOOMError(); + goto done; + } + + 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) { + virReportOOMError(); + 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: + remoteError(VIR_ERR_RPC, "%s", _("unknown parameter type")); + do_error = 1; + } + } + + if (do_error) { + xdr_free ((xdrproc_t) xdr_remote_domain_set_scheduler_parameters_flags_args, (char *) &args); + goto done; + } + + if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_SCHEDULER_PARAMETERS_FLAGS, + (xdrproc_t) xdr_remote_domain_set_scheduler_parameters_flags_args, (char *) &args, + (xdrproc_t) xdr_void, (char *) NULL) == -1) + goto done; + + rv = 0; + +done: + remoteDriverUnlock(priv); + return rv; +} + static int remoteDomainMemoryStats (virDomainPtr domain, struct _virDomainMemoryStat *stats, @@ -6799,6 +6867,7 @@ static virDriver remote_driver = { .domainMigratePerform3 = remoteDomainMigratePerform3, /* 0.9.2 */ .domainMigrateFinish3 = remoteDomainMigrateFinish3, /* 0.9.2 */ .domainMigrateConfirm3 = remoteDomainMigrateConfirm3, /* 0.9.2 */ + .domainSetSchedulerParametersFlags = remoteDomainSetSchedulerParametersFlags, /* 0.9.2 */ }; static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 1ce77e39bc..5932b2cf5f 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -476,6 +476,12 @@ struct remote_domain_set_scheduler_parameters_args { remote_sched_param params; }; +struct remote_domain_set_scheduler_parameters_flags_args { + remote_nonnull_domain dom; + remote_sched_param params; + unsigned int flags; +}; + struct remote_domain_set_blkio_parameters_args { remote_nonnull_domain dom; remote_blkio_param params; @@ -2284,7 +2290,8 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL3 = 215, /* skipgen skipgen */ REMOTE_PROC_DOMAIN_MIGRATE_PERFORM3 = 216, /* skipgen skipgen */ REMOTE_PROC_DOMAIN_MIGRATE_FINISH3 = 217, /* skipgen skipgen */ - REMOTE_PROC_DOMAIN_MIGRATE_CONFIRM3 = 218 /* skipgen skipgen */ + REMOTE_PROC_DOMAIN_MIGRATE_CONFIRM3 = 218, /* skipgen skipgen */ + REMOTE_PROC_DOMAIN_SET_SCHEDULER_PARAMETERS_FLAGS = 219 /* skipgen skipgen */ /* * Notice how the entries are grouped in sets of 10 ? diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 28496dd90a..5b43cb400d 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -188,6 +188,14 @@ struct remote_domain_set_scheduler_parameters_args { remote_sched_param * params_val; } params; }; +struct remote_domain_set_scheduler_parameters_flags_args { + remote_nonnull_domain dom; + struct { + u_int params_len; + remote_sched_param * params_val; + } params; + u_int flags; +}; struct remote_domain_set_blkio_parameters_args { remote_nonnull_domain dom; struct {