+Tue Jun 5 14:03:38 CEST 2007 Daniel Veillard <veillard@redhat.com>
+
+ * include/libvirt/libvirt.h include/libvirt/libvirt.h.in
+ src/driver.h src/libvirt.c src/libvirt_sym.version
+ src/proxy_internal.c src/qemu_internal.c src/test.c
+ src/virsh.c src/xen_internal.c src/xen_internal.h src/xen_unified.c
+ src/xend_internal.c src/xm_internal.c src/xs_internal.c:
+ Applied patches from Atsushi SAKAI to add the scheduler API,
+ with patch from Rich Jones for error handing, and a number
+ of cleanups and more error checking from me
+
Mon Jun 4 10:41:25 CEST 2007 Daniel Veillard <veillard@redhat.com>
* src/xml.c: apply patch from Masayuki Sunou about an uninitialized
};
+/**
+ * virDomainSchedParameterType:
+ *
+ * A scheduler parameter field type
+ */
+typedef enum {
+ VIR_DOMAIN_SCHED_FIELD_INT = 1, /* integer case */
+ VIR_DOMAIN_SCHED_FIELD_UINT = 2, /* unsigned integer case */
+ VIR_DOMAIN_SCHED_FIELD_LLONG = 3, /* long long case */
+ VIR_DOMAIN_SCHED_FIELD_ULLONG = 4, /* unsigned long long case */
+ VIR_DOMAIN_SCHED_FIELD_DOUBLE = 5, /* double case */
+ VIR_DOMAIN_SCHED_FIELD_BOOLEAN = 6 /* boolean(character) case */
+} virSchedParameterType;
+
+/**
+ * VIR_DOMAIN_SCHED_FIELD_LENGTH:
+ *
+ * Macro providing the field length of virSchedParameter
+ */
+
+#define VIR_DOMAIN_SCHED_FIELD_LENGTH 80
+
+/**
+ * virDomainSchedParameter:
+ *
+ * a virDomainSchedParameter is the set of scheduler parameters
+ */
+
+typedef struct _virSchedParameter virSchedParameter;
+
+struct _virSchedParameter {
+ char field[VIR_DOMAIN_SCHED_FIELD_LENGTH]; /* parameter name */
+ int type; /* parameter type */
+ union {
+ int i; /* data for integer case */
+ unsigned int ui; /* data for unsigned integer case */
+ long long int l; /* data for long long integer case */
+ unsigned long long int ul; /* data for unsigned long long integer case */
+ double d; /* data for double case */
+ char b; /* data for char case */
+ } value; /* parameter value */
+};
+
+/**
+ * virSchedParameterPtr:
+ *
+ * a virSchedParameterPtr is a pointer to a virSchedParameter structure.
+ */
+
+typedef virSchedParameter *virSchedParameterPtr;
+
+/*
+ * Fetch scheduler parameters, caller allocates 'params' field of size 'nparams'
+ */
+int virDomainGetSchedulerParameters (virDomainPtr domain,
+ virSchedParameterPtr params,
+ int *nparams);
+
+/*
+ * Change scheduler parameters
+ */
+int virDomainSetSchedulerParameters (virDomainPtr domain,
+ virSchedParameterPtr params,
+ int nparams);
+
/**
* VIR_NODEINFO_MAXCPUS:
* @nodeinfo: virNodeInfo instance
int virDomainGetInfo (virDomainPtr domain,
virDomainInfoPtr info);
+/*
+ * Return scheduler type in effect 'sedf', 'credit', 'linux'
+ */
+char * virDomainGetSchedulerType(virDomainPtr domain,
+ int *nparams);
+
/*
* Dynamic control of domains
*/
};
+/**
+ * virDomainSchedParameterType:
+ *
+ * A scheduler parameter field type
+ */
+typedef enum {
+ VIR_DOMAIN_SCHED_FIELD_INT = 1, /* integer case */
+ VIR_DOMAIN_SCHED_FIELD_UINT = 2, /* unsigned integer case */
+ VIR_DOMAIN_SCHED_FIELD_LLONG = 3, /* long long case */
+ VIR_DOMAIN_SCHED_FIELD_ULLONG = 4, /* unsigned long long case */
+ VIR_DOMAIN_SCHED_FIELD_DOUBLE = 5, /* double case */
+ VIR_DOMAIN_SCHED_FIELD_BOOLEAN = 6 /* boolean(character) case */
+} virSchedParameterType;
+
+/**
+ * VIR_DOMAIN_SCHED_FIELD_LENGTH:
+ *
+ * Macro providing the field length of virSchedParameter
+ */
+
+#define VIR_DOMAIN_SCHED_FIELD_LENGTH 80
+
+/**
+ * virDomainSchedParameter:
+ *
+ * a virDomainSchedParameter is the set of scheduler parameters
+ */
+
+typedef struct _virSchedParameter virSchedParameter;
+
+struct _virSchedParameter {
+ char field[VIR_DOMAIN_SCHED_FIELD_LENGTH]; /* parameter name */
+ int type; /* parameter type */
+ union {
+ int i; /* data for integer case */
+ unsigned int ui; /* data for unsigned integer case */
+ long long int l; /* data for long long integer case */
+ unsigned long long int ul; /* data for unsigned long long integer case */
+ double d; /* data for double case */
+ char b; /* data for char case */
+ } value; /* parameter value */
+};
+
+/**
+ * virSchedParameterPtr:
+ *
+ * a virSchedParameterPtr is a pointer to a virSchedParameter structure.
+ */
+
+typedef virSchedParameter *virSchedParameterPtr;
+
+/*
+ * Fetch scheduler parameters, caller allocates 'params' field of size 'nparams'
+ */
+int virDomainGetSchedulerParameters (virDomainPtr domain,
+ virSchedParameterPtr params,
+ int *nparams);
+
+/*
+ * Change scheduler parameters
+ */
+int virDomainSetSchedulerParameters (virDomainPtr domain,
+ virSchedParameterPtr params,
+ int nparams);
+
/**
* VIR_NODEINFO_MAXCPUS:
* @nodeinfo: virNodeInfo instance
int virDomainGetInfo (virDomainPtr domain,
virDomainInfoPtr info);
+/*
+ * Return scheduler type in effect 'sedf', 'credit', 'linux'
+ */
+char * virDomainGetSchedulerType(virDomainPtr domain,
+ int *nparams);
+
/*
* Dynamic control of domains
*/
} virDrvOpenStatus;
typedef virDrvOpenStatus
- (*virDrvOpen) (virConnectPtr conn,
- const char *name,
- int flags);
+ (*virDrvOpen) (virConnectPtr conn,
+ const char *name,
+ int flags);
typedef int
(*virDrvClose) (virConnectPtr conn);
typedef const char *
(*virDrvGetVersion) (virConnectPtr conn,
unsigned long *hvVer);
typedef int
- (*virDrvGetMaxVcpus) (virConnectPtr conn, const char *type);
+ (*virDrvGetMaxVcpus) (virConnectPtr conn,
+ const char *type);
typedef int
(*virDrvNodeGetInfo) (virConnectPtr conn,
virNodeInfoPtr info);
typedef int
(*virDrvNumOfDefinedDomains) (virConnectPtr conn);
typedef int
- (*virDrvDomainCreate) (virDomainPtr dom);
+ (*virDrvDomainCreate) (virDomainPtr dom);
typedef virDomainPtr
- (*virDrvDomainDefineXML)(virConnectPtr conn, const char *xml);
+ (*virDrvDomainDefineXML) (virConnectPtr conn,
+ const char *xml);
typedef int
- (*virDrvDomainUndefine) (virDomainPtr dom);
+ (*virDrvDomainUndefine) (virDomainPtr dom);
typedef int
(*virDrvDomainSetVcpus) (virDomainPtr domain,
unsigned int nvcpus);
(*virDrvDomainSetAutostart) (virDomainPtr domain,
int autostart);
+typedef char *
+ (*virDrvDomainGetSchedulerType) (virDomainPtr domain,
+ int *nparams);
+
+typedef int
+ (*virDrvDomainGetSchedulerParameters)
+ (virDomainPtr domain,
+ virSchedParameterPtr params,
+ int *nparams);
+
+typedef int
+ (*virDrvDomainSetSchedulerParameters)
+ (virDomainPtr domain,
+ virSchedParameterPtr params,
+ int nparams);
+
typedef struct _virDriver virDriver;
typedef virDriver *virDriverPtr;
virDrvGetVersion version;
virDrvGetMaxVcpus getMaxVcpus;
virDrvNodeGetInfo nodeGetInfo;
- virDrvGetCapabilities getCapabilities;
+ virDrvGetCapabilities getCapabilities;
virDrvListDomains listDomains;
virDrvNumOfDomains numOfDomains;
virDrvDomainCreateLinux domainCreateLinux;
virDrvDomainDetachDevice domainDetachDevice;
virDrvDomainGetAutostart domainGetAutostart;
virDrvDomainSetAutostart domainSetAutostart;
+ virDrvDomainGetSchedulerType domainGetSchedulerType;
+ virDrvDomainGetSchedulerParameters domainGetSchedulerParameters;
+ virDrvDomainSetSchedulerParameters domainSetSchedulerParameters;
};
typedef int
(*virDrvNetworkCreateXML) (virConnectPtr conn,
const char *xmlDesc);
typedef virNetworkPtr
- (*virDrvNetworkDefineXML) (virConnectPtr conn, const char *xml);
+ (*virDrvNetworkDefineXML) (virConnectPtr conn,
+ const char *xml);
typedef int
(*virDrvNetworkUndefine) (virNetworkPtr network);
typedef int
return NULL;
}
+/**
+ * virDomainGetSchedulerType:
+ * @domain: pointer to domain object
+ * @nparams: number of scheduler parameters(return value)
+ *
+ * Get the scheduler type.
+ *
+ * Returns NULL in case of error. The caller must free the returned string.
+ */
+char *
+virDomainGetSchedulerType(virDomainPtr domain, int *nparams)
+{
+ virConnectPtr conn;
+ char *schedtype;
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(domain, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return NULL;
+ }
+ conn = domain->conn;
+
+ if (!VIR_IS_CONNECT (conn)) {
+ virLibConnError (conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return NULL;
+ }
+
+ if (conn->driver->domainGetSchedulerType){
+ schedtype = conn->driver->domainGetSchedulerType (domain, nparams);
+ return schedtype;
+ }
+
+ virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+ return NULL;
+}
+
+
+/**
+ * virDomainGetSchedulerParameters:
+ * @domain: pointer to domain object
+ * @params: pointer to scheduler parameter object
+ * (return value)
+ * @nparams: pointer to number of scheduler parameter
+ * (this value should be same than the returned value
+ * nparams of virDomainGetSchedulerType)
+ *
+ * Get the scheduler parameters, the @params array will be filled with the
+ * values.
+ *
+ * Returns -1 in case of error, 0 in case of success.
+ */
+int
+virDomainGetSchedulerParameters(virDomainPtr domain,
+ virSchedParameterPtr params, int *nparams)
+{
+ virConnectPtr conn;
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(domain, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return -1;
+ }
+ conn = domain->conn;
+
+ if (!VIR_IS_CONNECT (conn)) {
+ virLibConnError (conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return -1;
+ }
+
+ if (conn->driver->domainGetSchedulerParameters)
+ return conn->driver->domainGetSchedulerParameters (domain, params, nparams);
+
+ virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+ return -1;
+}
+
+/**
+ * virDomainSetSchedulerParameters:
+ * @domain: pointer to domain object
+ * @params: pointer to scheduler parameter objects
+ * @nparams: number of scheduler parameter
+ * (this value should be same or less than the returned value
+ * nparams of virDomainGetSchedulerType)
+ *
+ * Change the scheduler parameters
+ *
+ * Returns -1 in case of error, 0 in case of success.
+ */
+int
+virDomainSetSchedulerParameters(virDomainPtr domain,
+ virSchedParameterPtr params, int nparams)
+{
+ virConnectPtr conn;
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(domain, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return -1;
+ }
+ conn = domain->conn;
+
+ if (!VIR_IS_CONNECT (conn)) {
+ virLibConnError (conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return -1;
+ }
+
+ if (conn->driver->domainSetSchedulerParameters)
+ return conn->driver->domainSetSchedulerParameters (domain, params, nparams);
+
+ virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+ return -1;
+}
+
+
+
/************************************************************************
* *
* Handling of defined but not running domains *
virDomainPinVcpu;
virDomainGetVcpus;
virDomainGetMaxVcpus;
+ virDomainGetSchedulerType;
+ virDomainGetSchedulerParameters;
+ virDomainSetSchedulerParameters;
virDomainAttachDevice;
virDomainDetachDevice;
NULL, /* domainDetachDevice */
NULL, /* domainGetAutostart */
NULL, /* domainSetAutostart */
+ NULL, /* domainGetSchedulerType */
+ NULL, /* domainGetSchedulerParameters */
+ NULL, /* domainSetSchedulerParameters */
};
/**
NULL, /* domainDetachDevice */
qemuDomainGetAutostart, /* domainGetAutostart */
qemuDomainSetAutostart, /* domainSetAutostart */
+ NULL, /* domainGetSchedulerType */
+ NULL, /* domainGetSchedulerParameters */
+ NULL, /* domainSetSchedulerParameters */
};
static virNetworkDriver qemuNetworkDriver = {
NULL, /* domainDetachDevice */
NULL, /* domainGetAutostart */
NULL, /* domainSetAutostart */
+ NULL, /* domainGetSchedulerType */
+ NULL, /* domainGetSchedulerParameters */
+ NULL, /* domainSetSchedulerParameters */
};
/* Per-connection private data. */
#include <ctype.h>
#include <fcntl.h>
#include <locale.h>
+#include <assert.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
return ret;
}
+/*
+ * "schedinfo" command
+ */
+static vshCmdInfo info_schedinfo[] = {
+ {"syntax", "sched <domain>"},
+ {"help", gettext_noop("show/set scheduler parameters")},
+ {"desc", gettext_noop("Show/Set scheduler parameters.")},
+ {NULL, NULL}
+};
+
+static vshCmdOptDef opts_schedinfo[] = {
+ {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")},
+ {"weight", VSH_OT_INT, VSH_OFLAG_NONE, gettext_noop("weight for XEN_CREDIT")},
+ {"cap", VSH_OT_INT, VSH_OFLAG_NONE, gettext_noop("cap for XEN_CREDIT")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdSchedinfo(vshControl * ctl, vshCmd * cmd)
+{
+ char *schedulertype;
+ virDomainPtr dom;
+ virSchedParameterPtr params;
+ int i, ret;
+ int nparams = 0;
+ int nr_inputparams = 0;
+ int inputparams = 0;
+ int weightfound = 0;
+ int weight;
+ int capfound = 0;
+ int cap;
+ char str_weight[] = "weight";
+ char str_cap[] = "cap";
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ return FALSE;
+
+ if (!(dom = vshCommandOptDomain(ctl, cmd, "domain", NULL)))
+ return FALSE;
+
+ /* Currently supports Xen Credit only */
+ weight = vshCommandOptInt(cmd, "weight", &weightfound);
+ if (weightfound) nr_inputparams++;
+
+ cap = vshCommandOptInt(cmd, "cap", &capfound);
+ if (capfound) nr_inputparams++;
+
+ params = vshMalloc(ctl, sizeof (virSchedParameter) * nr_inputparams);
+ if (params == NULL) return FALSE;
+
+ if (weightfound) {
+ strncpy(params[inputparams].field,str_weight,sizeof(str_weight));
+ params[inputparams].type = VIR_DOMAIN_SCHED_FIELD_UINT;
+ params[inputparams].value.ui = weight;
+ inputparams++;
+ }
+
+ if (capfound) {
+ strncpy(params[inputparams].field,str_cap,sizeof(str_cap));
+ params[inputparams].type = VIR_DOMAIN_SCHED_FIELD_UINT;
+ params[inputparams].value.ui = cap;
+ inputparams++;
+ }
+ /* End Currently supports Xen Credit only */
+
+ assert (inputparams == nr_inputparams);
+
+ /* Set SchedulerParameters */
+ if (inputparams > 0) {
+ ret = virDomainSetSchedulerParameters(dom, params, inputparams);
+ if (ret == -1) return FALSE;
+ }
+ free(params);
+
+ /* Print SchedulerType */
+ schedulertype = virDomainGetSchedulerType(dom, &nparams);
+ if (schedulertype!= NULL){
+ vshPrint(ctl, "%-15s %s\n", _("Scheduler:"),
+ schedulertype);
+ free(schedulertype);
+ } else {
+ vshPrint(ctl, "%-15s %s\n", _("Scheduler:"), _("Unknown"));
+ return FALSE;
+ }
+
+ /* Get SchedulerParameters */
+ params = vshMalloc(ctl, sizeof(virSchedParameter)* nparams);
+ for (i = 0; i < nparams; i++){
+ params[i].type = 0;
+ memset (params[i].field, 0, sizeof params[i].field);
+ }
+ ret = virDomainGetSchedulerParameters(dom, params, &nparams);
+ if (ret == -1) return FALSE;
+ if(nparams){
+ for (i = 0; i < nparams; i++){
+ switch (params[i].type) {
+ case VIR_DOMAIN_SCHED_FIELD_INT:
+ printf("%-15s: %d\n", params[i].field, params[i].value.i);
+ break;
+ case VIR_DOMAIN_SCHED_FIELD_UINT:
+ printf("%-15s: %u\n", params[i].field, params[i].value.ui);
+ break;
+ case VIR_DOMAIN_SCHED_FIELD_LLONG:
+ printf("%-15s: %Ld\n", params[i].field, params[i].value.l);
+ break;
+ case VIR_DOMAIN_SCHED_FIELD_ULLONG:
+ printf("%-15s: %Lu\n", params[i].field, params[i].value.ul);
+ break;
+ case VIR_DOMAIN_SCHED_FIELD_DOUBLE:
+ printf("%-15s: %f\n", params[i].field, params[i].value.d);
+ break;
+ case VIR_DOMAIN_SCHED_FIELD_BOOLEAN:
+ printf("%-15s: %d\n", params[i].field, params[i].value.b);
+ break;
+ default:
+ printf("not implemented scheduler parameter type\n");
+ }
+ }
+ }
+ free(params);
+ return TRUE;
+}
+
/*
* "restore" command
*/
{"restore", cmdRestore, opts_restore, info_restore},
{"resume", cmdResume, opts_resume, info_resume},
{"save", cmdSave, opts_save, info_save},
+ {"schedinfo", cmdSchedinfo, opts_schedinfo, info_schedinfo},
{"dump", cmdDump, opts_dump, info_dump},
{"shutdown", cmdShutdown, opts_shutdown, info_shutdown},
{"setmem", cmdSetmem, opts_setmem, info_setmem},
};
typedef union xen_getdomaininfolist xen_getdomaininfolist;
+
+struct xen_v2_getschedulerid {
+ uint32_t sched_id; /* Get Scheduler ID from Xen */
+};
+typedef struct xen_v2_getschedulerid xen_v2_getschedulerid;
+
+
+union xen_getschedulerid {
+ struct xen_v2_getschedulerid *v2;
+};
+typedef union xen_getschedulerid xen_getschedulerid;
+
+
#define XEN_GETDOMAININFOLIST_ALLOC(domlist, size) \
(hypervisor_version < 2 ? \
((domlist.v0 = malloc(sizeof(xen_v0_getdomaininfo)*(size))) != NULL) : \
typedef struct xen_v2_setvcpumap xen_v2_getvcpumap;
typedef struct xen_v2d5_setvcpumap xen_v2d5_getvcpumap;
+/*
+ * from V2 we get the scheduler information
+ */
+#define XEN_V2_OP_GETSCHEDULERID 4
+
+/*
+ * from V2 we get the scheduler parameter
+ */
+#define XEN_V2_OP_SCHEDULER 16
+/* Scheduler types. */
+#define XEN_SCHEDULER_SEDF 4
+#define XEN_SCHEDULER_CREDIT 5
+/* get/set scheduler parameters */
+#define XEN_DOMCTL_SCHEDOP_putinfo 0
+#define XEN_DOMCTL_SCHEDOP_getinfo 1
+
+struct xen_v2_setschedinfo {
+ uint32_t sched_id;
+ uint32_t cmd;
+ union {
+ struct xen_domctl_sched_sedf {
+ uint64_t period ALIGN_64;
+ uint64_t slice ALIGN_64;
+ uint64_t latency ALIGN_64;
+ uint32_t extratime;
+ uint32_t weight;
+ } sedf;
+ struct xen_domctl_sched_credit {
+ uint16_t weight;
+ uint16_t cap;
+ } credit;
+ } u;
+};
+typedef struct xen_v2_setschedinfo xen_v2_setschedinfo;
+typedef struct xen_v2_setschedinfo xen_v2_getschedinfo;
+
+
/*
* The hypercall operation structures also have changed on
* changeset 86d26e6ec89b
union {
xen_v2_getdomaininfolistop getdomaininfolist;
xen_v2s3_getdomaininfolistop getdomaininfolists3;
+ xen_v2_getschedulerid getschedulerid;
uint8_t padding[128];
} u;
};
xen_v2d5_vcpuinfo getvcpuinfod5;
xen_v2_getvcpumap getvcpumap;
xen_v2d5_getvcpumap getvcpumapd5;
+ xen_v2_setschedinfo setschedinfo;
+ xen_v2_getschedinfo getschedinfo;
uint8_t padding[128];
} u;
};
NULL, /* domainDetachDevice */
NULL, /* domainGetAutostart */
NULL, /* domainSetAutostart */
+ xenHypervisorGetSchedulerType, /* domainGetSchedulerType */
+ xenHypervisorGetSchedulerParameters, /* domainGetSchedulerParameters */
+ xenHypervisorSetSchedulerParameters, /* domainSetSchedulerParameters */
};
#endif /* !PROXY */
errmsg, info, NULL, value, 0, errmsg, info);
}
+/**
+ * virXenErrorFunc:
+ * @error: the error number
+ * @func: the function failing
+ * @info: extra information string
+ * @value: extra information number
+ *
+ * Handle an error at the xend daemon interface
+ */
+static void
+virXenErrorFunc(virErrorNumber error, const char *func, const char *info,
+ int value)
+{
+ char fullinfo[1000]
+ const char *errmsg;
+
+ if ((error == VIR_ERR_OK) || (in_init != 0))
+ return;
+
+
+ errmsg = __virErrorMsg(error, info);
+ if (func != NULL) {
+ snprintf(fullinfo, 999, "%s: %s", func, info);
+ fullinfo[999] = 0;
+ __virRaiseError(NULL, NULL, NULL, VIR_FROM_XEN, error, VIR_ERR_ERROR,
+ errmsg, fullinfo, NULL, value, 0, errmsg, fullinfo);
+ } else {
+ __virRaiseError(NULL, NULL, NULL, VIR_FROM_XEN, error, VIR_ERR_ERROR,
+ errmsg, info, NULL, value, 0, errmsg, info);
+ }
+}
+
/**
* virXenPerror:
* @conn: the connection (if available)
ret = ioctl(handle, xen_ioctl_hypercall_cmd, (unsigned long) &hc);
if (ret < 0) {
- virXenError(VIR_ERR_XEN_CALL, " ioctl ", xen_ioctl_hypercall_cmd);
+ virXenError(VIR_ERR_XEN_CALL, " sys ioctl ", xen_ioctl_hypercall_cmd);
}
if (munlock(op, sizeof(dom0_op_t)) < 0) {
#ifndef PROXY
+/**
+ * xenHypervisorGetSchedulerType:
+ * @domain: pointer to the Xen Hypervisor block
+ * @nparams:give a number of scheduler parameters.
+ *
+ * Do a low level hypercall to get scheduler type
+ *
+ * Returns scheduler name or NULL in case of failure
+ */
+char *
+xenHypervisorGetSchedulerType(virDomainPtr domain, int *nparams)
+{
+ char *schedulertype = NULL;
+ xenUnifiedPrivatePtr priv;
+
+ if ((domain == NULL) || (domain->conn == NULL)) {
+ virXenErrorFunc(VIR_ERR_INTERNAL_ERROR, __FUNCTION__,
+ "domain or conn is NULL", 0);
+ return NULL;
+ }
+
+ priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+ if (priv->handle < 0 || domain->id < 0) {
+ virXenErrorFunc(VIR_ERR_INTERNAL_ERROR, __FUNCTION__,
+ "priv->handle or domain->id invalid", 0);
+ return NULL;
+ }
+
+ /*
+ * Support only dom_interface_version >=5
+ * (Xen3.1.0 or later)
+ */
+ if (dom_interface_version < 5) {
+ virXenErrorFunc(VIR_ERR_NO_XEN, __FUNCTION__,
+ "unsupported in dom interface < 5", 0);
+ return NULL;
+ }
+
+ if (hypervisor_version > 1) {
+ xen_op_v2_sys op;
+ int ret;
+
+ memset(&op, 0, sizeof(op));
+ op.cmd = XEN_V2_OP_GETSCHEDULERID;
+ ret = xenHypervisorDoV2Sys(priv->handle, &op);
+ if (ret < 0)
+ return(NULL);
+
+ switch (op.u.getschedulerid.sched_id){
+ case XEN_SCHEDULER_SEDF:
+ schedulertype = strdup("sedf");
+ if (nparams)
+ *nparams = 6;
+ break;
+ case XEN_SCHEDULER_CREDIT:
+ schedulertype = strdup("credit");
+ if (nparams)
+ *nparams = 2;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return schedulertype;
+}
+
+/**
+ * xenHypervisorGetSchedulerParameters:
+ * @domain: pointer to the Xen Hypervisor block
+ * @params: pointer to scheduler parameters.
+ * This memory area should be allocated before calling.
+ * @nparams:this parameter should be same as
+ * a given number of scheduler parameters.
+ * from xenHypervisorGetSchedulerType().
+ *
+ * Do a low level hypercall to get scheduler parameters
+ *
+ * Returns 0 or -1 in case of failure
+ */
+int
+xenHypervisorGetSchedulerParameters(virDomainPtr domain,
+ virSchedParameterPtr params, int *nparams)
+{
+ xenUnifiedPrivatePtr priv;
+ char str_weight[] ="weight";
+ char str_cap[] ="cap";
+
+ if ((domain == NULL) || (domain->conn == NULL)) {
+ virXenErrorFunc(VIR_ERR_INTERNAL_ERROR, __FUNCTION__,
+ "domain or conn is NULL", 0);
+ return -1;
+ }
+
+ priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+ if (priv->handle < 0 || domain->id < 0) {
+ virXenErrorFunc(VIR_ERR_INTERNAL_ERROR, __FUNCTION__,
+ "priv->handle or domain->id invalid", 0);
+ return -1;
+ }
+
+ /*
+ * Support only dom_interface_version >=5
+ * (Xen3.1.0 or later)
+ * TODO: check on Xen 3.0.3
+ */
+ if (dom_interface_version < 5) {
+ virXenErrorFunc(VIR_ERR_NO_XEN, __FUNCTION__,
+ "unsupported in dom interface < 5", 0);
+ return -1;
+ }
+
+ if (hypervisor_version > 1) {
+ xen_op_v2_sys op_sys;
+ xen_op_v2_dom op_dom;
+ int ret;
+
+ memset(&op_sys, 0, sizeof(op_sys));
+ op_sys.cmd = XEN_V2_OP_GETSCHEDULERID;
+ ret = xenHypervisorDoV2Sys(priv->handle, &op_sys);
+ if (ret < 0)
+ return -1;
+
+ switch (op_sys.u.getschedulerid.sched_id){
+ case XEN_SCHEDULER_SEDF:
+ /* TODO: Implement for Xen/SEDF */
+ TODO
+ return(-1);
+ case XEN_SCHEDULER_CREDIT:
+ if (*nparams < 2)
+ return(-1);
+ memset(&op_dom, 0, sizeof(op_dom));
+ op_dom.cmd = XEN_V2_OP_SCHEDULER;
+ op_dom.domain = (domid_t) domain->id;
+ op_dom.u.getschedinfo.sched_id = XEN_SCHEDULER_CREDIT;
+ op_dom.u.getschedinfo.cmd = XEN_DOMCTL_SCHEDOP_getinfo;
+ ret = xenHypervisorDoV2Dom(priv->handle, &op_dom);
+ if (ret < 0)
+ return(-1);
+
+ strncpy(params[0].field, str_weight, strlen(str_weight));
+ params[0].type = VIR_DOMAIN_SCHED_FIELD_UINT;
+ params[0].value.ui = op_dom.u.getschedinfo.u.credit.weight;
+
+ strncpy(params[1].field, str_cap, strlen(str_cap));
+ params[1].type = VIR_DOMAIN_SCHED_FIELD_UINT;
+ params[1].value.ui = op_dom.u.getschedinfo.u.credit.cap;
+
+ *nparams = 2;
+ break;
+ default:
+ virXenErrorFunc(VIR_ERR_INVALID_ARG, __FUNCTION__,
+ "Unknown scheduler", op_sys.u.getschedulerid.sched_id);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * xenHypervisorSetSchedulerParameters:
+ * @domain: pointer to the Xen Hypervisor block
+ * @nparams:give a number of scheduler setting parameters .
+ *
+ * Do a low level hypercall to set scheduler parameters
+ *
+ * Returns 0 or -1 in case of failure
+ */
+int
+xenHypervisorSetSchedulerParameters(virDomainPtr domain,
+ virSchedParameterPtr params, int nparams)
+{
+ int i;
+ xenUnifiedPrivatePtr priv;
+ char str_weight[] ="weight";
+ char str_cap[] ="cap";
+
+ if ((domain == NULL) || (domain->conn == NULL)) {
+ virXenErrorFunc (VIR_ERR_INTERNAL_ERROR, __FUNCTION__,
+ "domain or conn is NULL", 0);
+ return -1;
+ }
+
+ if ((nparams == 0) || (params == NULL)) {
+ virXenErrorFunc (VIR_ERR_INVALID_ARG, __FUNCTION__,
+ "Noparameters given", 0);
+ return(-1);
+ }
+
+ priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+ if (priv->handle < 0 || domain->id < 0) {
+ virXenErrorFunc (VIR_ERR_INTERNAL_ERROR, __FUNCTION__,
+ "priv->handle or domain->id invalid", 0);
+ return -1;
+ }
+
+ /*
+ * Support only dom_interface_version >=5
+ * (Xen3.1.0 or later)
+ * TODO: check on Xen 3.0.3
+ */
+ if (dom_interface_version < 5) {
+ virXenError(VIR_ERR_NO_XEN, __FUNCTION__,
+ "unsupported in dom interface < 5", 0);
+ return -1;
+ }
+
+ if (hypervisor_version > 1) {
+ xen_op_v2_sys op_sys;
+ xen_op_v2_dom op_dom;
+ int ret;
+
+ memset(&op_sys, 0, sizeof(op_sys));
+ op_sys.cmd = XEN_V2_OP_GETSCHEDULERID;
+ ret = xenHypervisorDoV2Sys(priv->handle, &op_sys);
+ if (ret == -1) return -1;
+
+ switch (op_sys.u.getschedulerid.sched_id){
+ case XEN_SCHEDULER_SEDF:
+ /* TODO: Implement for Xen/SEDF */
+ TODO
+ return(-1);
+ case XEN_SCHEDULER_CREDIT: {
+ int weight_set = 0;
+ int cap_set = 0;
+
+ memset(&op_dom, 0, sizeof(op_dom));
+ op_dom.cmd = XEN_V2_OP_SCHEDULER;
+ op_dom.domain = (domid_t) domain->id;
+ op_dom.u.getschedinfo.sched_id = XEN_SCHEDULER_CREDIT;
+ op_dom.u.getschedinfo.cmd = XEN_DOMCTL_SCHEDOP_putinfo;
+
+ /*
+ * credit scheduler parameters
+ * following values do not change the parameters
+ */
+ op_dom.u.getschedinfo.u.credit.weight = 0;
+ op_dom.u.getschedinfo.u.credit.cap = (uint16_t)~0U;
+
+ for (i = 0; i < nparams; i++) {
+ if (!strncmp(params[i].field,str_weight,strlen(str_weight)) &&
+ params[i].type == VIR_DOMAIN_SCHED_FIELD_UINT) {
+ op_dom.u.getschedinfo.u.credit.weight = params[i].value.ui;
+ weight_set = 1;
+ } else if (!strncmp(params[i].field,str_cap,strlen(str_cap)) &&
+ params[i].type == VIR_DOMAIN_SCHED_FIELD_UINT) {
+ op_dom.u.getschedinfo.u.credit.cap = params[i].value.ui;
+ cap_set = 1;
+ } else {
+ virXenErrorFunc (VIR_ERR_INVALID_ARG, __FUNCTION__,
+ "Credit scheduler accepts 'cap' and 'weight' integer parameters",
+ 0);
+ return(-1);
+ }
+ }
+
+ ret = xenHypervisorDoV2Dom(priv->handle, &op_dom);
+ if (ret < 0)
+ return -1;
+ break;
+ }
+ default:
+ virXenErrorFunc(VIR_ERR_INVALID_ARG, __FUNCTION__,
+ "Unknown scheduler", op_sys.u.getschedulerid.sched_id);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
/**
* virXen_pausedomain:
* @handle: the hypervisor handle
int maplen);
int xenHypervisorGetVcpuMax (virDomainPtr domain);
+char * xenHypervisorGetSchedulerType (virDomainPtr domain,
+ int *nparams);
+
+int xenHypervisorGetSchedulerParameters (virDomainPtr domain,
+ virSchedParameterPtr params,
+ int *nparams);
+
+int xenHypervisorSetSchedulerParameters (virDomainPtr domain,
+ virSchedParameterPtr params,
+ int nparams);
+
#ifdef __cplusplus
}
#endif
return -1;
}
+static char *
+xenUnifiedDomainGetSchedulerType (virDomainPtr dom, int *nparams)
+{
+ GET_PRIVATE(dom->conn);
+ int i;
+ char *schedulertype;
+
+ for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; i++) {
+ if (priv->opened[i] && drivers[i]->domainGetSchedulerType) {
+ schedulertype = drivers[i]->domainGetSchedulerType (dom, nparams);
+ if (schedulertype != NULL)
+ return(schedulertype);
+ }
+ }
+ return(NULL);
+}
+
+static int
+xenUnifiedDomainGetSchedulerParameters (virDomainPtr dom,
+ virSchedParameterPtr params, int *nparams)
+{
+ GET_PRIVATE(dom->conn);
+ int i, ret;
+
+ for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i) {
+ if (priv->opened[i] && drivers[i]->domainGetSchedulerParameters) {
+ ret = drivers[i]->domainGetSchedulerParameters(dom, params, nparams);
+ if (ret == 0)
+ return(0);
+ }
+ }
+ return(-1);
+}
+
+static int
+xenUnifiedDomainSetSchedulerParameters (virDomainPtr dom,
+ virSchedParameterPtr params, int nparams)
+{
+ GET_PRIVATE(dom->conn);
+ int i, ret;
+
+ for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i) {
+ if (priv->opened[i] && drivers[i]->domainSetSchedulerParameters) {
+ ret = drivers[i]->domainSetSchedulerParameters(dom, params, nparams);
+ if (ret == 0)
+ return 0;
+ }
+ }
+
+ return(-1);
+}
+
/*----- Register with libvirt.c, and initialise Xen drivers. -----*/
#define VERSION ((DOM0_INTERFACE_VERSION >> 24) * 1000000 + \
.domainDetachDevice = xenUnifiedDomainDetachDevice,
.domainGetAutostart = xenUnifiedDomainGetAutostart,
.domainSetAutostart = xenUnifiedDomainSetAutostart,
+ .domainGetSchedulerType = xenUnifiedDomainGetSchedulerType,
+ .domainGetSchedulerParameters = xenUnifiedDomainGetSchedulerParameters,
+ .domainSetSchedulerParameters = xenUnifiedDomainSetSchedulerParameters,
};
/**
xenDaemonDetachDevice, /* domainDetachDevice */
NULL, /* domainGetAutostart */
NULL, /* domainSetAutostart */
+ NULL, /* domainGetSchedulerType */
+ NULL, /* domainGetSchedulerParameters */
+ NULL, /* domainSetSchedulerParameters */
};
/**
NULL, /* domainDetachDevice */
NULL, /* domainGetAutostart */
NULL, /* domainSetAutostart */
+ NULL, /* domainGetSchedulerType */
+ NULL, /* domainGetSchedulerParameters */
+ NULL, /* domainSetSchedulerParameters */
};
static void
NULL, /* domainDetachDevice */
NULL, /* domainGetAutostart */
NULL, /* domainSetAutostart */
+ NULL, /* domainGetSchedulerType */
+ NULL, /* domainGetSchedulerParameters */
+ NULL, /* domainSetSchedulerParameters */
};
/**