* 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
Daniel
This commit is contained in:
Daniel Veillard 2007-06-05 12:06:08 +00:00
parent c6e2ef60df
commit 652f3bb13b
16 changed files with 869 additions and 10 deletions

View File

@ -1,3 +1,14 @@
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

View File

@ -168,6 +168,71 @@ struct _virNodeInfo {
};
/**
* 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
@ -302,6 +367,12 @@ int virDomainCoreDump (virDomainPtr domain,
int virDomainGetInfo (virDomainPtr domain,
virDomainInfoPtr info);
/*
* Return scheduler type in effect 'sedf', 'credit', 'linux'
*/
char * virDomainGetSchedulerType(virDomainPtr domain,
int *nparams);
/*
* Dynamic control of domains
*/

View File

@ -168,6 +168,71 @@ struct _virNodeInfo {
};
/**
* 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
@ -302,6 +367,12 @@ int virDomainCoreDump (virDomainPtr domain,
int virDomainGetInfo (virDomainPtr domain,
virDomainInfoPtr info);
/*
* Return scheduler type in effect 'sedf', 'credit', 'linux'
*/
char * virDomainGetSchedulerType(virDomainPtr domain,
int *nparams);
/*
* Dynamic control of domains
*/

View File

@ -54,7 +54,8 @@ typedef int
(*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);
@ -125,7 +126,8 @@ typedef int
typedef int
(*virDrvDomainCreate) (virDomainPtr dom);
typedef virDomainPtr
(*virDrvDomainDefineXML)(virConnectPtr conn, const char *xml);
(*virDrvDomainDefineXML) (virConnectPtr conn,
const char *xml);
typedef int
(*virDrvDomainUndefine) (virDomainPtr dom);
typedef int
@ -157,6 +159,22 @@ typedef int
(*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;
@ -216,6 +234,9 @@ struct _virDriver {
virDrvDomainDetachDevice domainDetachDevice;
virDrvDomainGetAutostart domainGetAutostart;
virDrvDomainSetAutostart domainSetAutostart;
virDrvDomainGetSchedulerType domainGetSchedulerType;
virDrvDomainGetSchedulerParameters domainGetSchedulerParameters;
virDrvDomainSetSchedulerParameters domainSetSchedulerParameters;
};
typedef int
@ -240,7 +261,8 @@ typedef virNetworkPtr
(*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

View File

@ -1427,6 +1427,118 @@ virConnectGetCapabilities (virConnectPtr conn)
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 *

View File

@ -59,6 +59,9 @@
virDomainPinVcpu;
virDomainGetVcpus;
virDomainGetMaxVcpus;
virDomainGetSchedulerType;
virDomainGetSchedulerParameters;
virDomainSetSchedulerParameters;
virDomainAttachDevice;
virDomainDetachDevice;

View File

@ -88,6 +88,9 @@ virDriver xenProxyDriver = {
NULL, /* domainDetachDevice */
NULL, /* domainGetAutostart */
NULL, /* domainSetAutostart */
NULL, /* domainGetSchedulerType */
NULL, /* domainGetSchedulerParameters */
NULL, /* domainSetSchedulerParameters */
};
/**

View File

@ -1350,6 +1350,9 @@ static virDriver qemuDriver = {
NULL, /* domainDetachDevice */
qemuDomainGetAutostart, /* domainGetAutostart */
qemuDomainSetAutostart, /* domainSetAutostart */
NULL, /* domainGetSchedulerType */
NULL, /* domainGetSchedulerParameters */
NULL, /* domainSetSchedulerParameters */
};
static virNetworkDriver qemuNetworkDriver = {

View File

@ -132,6 +132,9 @@ static virDriver testDriver = {
NULL, /* domainDetachDevice */
NULL, /* domainGetAutostart */
NULL, /* domainSetAutostart */
NULL, /* domainGetSchedulerType */
NULL, /* domainGetSchedulerParameters */
NULL, /* domainSetSchedulerParameters */
};
/* Per-connection private data. */

View File

@ -29,6 +29,7 @@
#include <ctype.h>
#include <fcntl.h>
#include <locale.h>
#include <assert.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
@ -939,6 +940,129 @@ cmdSave(vshControl * ctl, vshCmd * cmd)
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
*/
@ -2592,6 +2716,7 @@ static vshCmdDef commands[] = {
{"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},

View File

@ -180,6 +180,19 @@ union xen_getdomaininfolist {
};
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) : \
@ -468,6 +481,43 @@ typedef struct xen_v2d5_vcpuinfo xen_v2d5_vcpuinfo;
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
@ -496,6 +546,7 @@ struct xen_op_v2_sys {
union {
xen_v2_getdomaininfolistop getdomaininfolist;
xen_v2s3_getdomaininfolistop getdomaininfolists3;
xen_v2_getschedulerid getschedulerid;
uint8_t padding[128];
} u;
};
@ -516,6 +567,8 @@ struct xen_op_v2_dom {
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;
};
@ -580,6 +633,9 @@ virDriver xenHypervisorDriver = {
NULL, /* domainDetachDevice */
NULL, /* domainGetAutostart */
NULL, /* domainSetAutostart */
xenHypervisorGetSchedulerType, /* domainGetSchedulerType */
xenHypervisorGetSchedulerParameters, /* domainGetSchedulerParameters */
xenHypervisorSetSchedulerParameters, /* domainSetSchedulerParameters */
};
#endif /* !PROXY */
@ -604,6 +660,38 @@ virXenError(virErrorNumber error, const char *info, int value)
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)
@ -739,7 +827,7 @@ xenHypervisorDoV2Sys(int handle, xen_op_v2_sys* op)
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) {
@ -893,6 +981,278 @@ virXen_getdomaininfo(int handle, int first_domain,
#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

View File

@ -66,6 +66,17 @@ int xenHypervisorGetVcpus (virDomainPtr domain,
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

View File

@ -775,6 +775,58 @@ xenUnifiedDomainSetAutostart (virDomainPtr dom, int autostart)
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 + \
@ -826,6 +878,9 @@ static virDriver xenUnifiedDriver = {
.domainDetachDevice = xenUnifiedDomainDetachDevice,
.domainGetAutostart = xenUnifiedDomainGetAutostart,
.domainSetAutostart = xenUnifiedDomainSetAutostart,
.domainGetSchedulerType = xenUnifiedDomainGetSchedulerType,
.domainGetSchedulerParameters = xenUnifiedDomainGetSchedulerParameters,
.domainSetSchedulerParameters = xenUnifiedDomainSetSchedulerParameters,
};
/**

View File

@ -108,6 +108,9 @@ virDriver xenDaemonDriver = {
xenDaemonDetachDevice, /* domainDetachDevice */
NULL, /* domainGetAutostart */
NULL, /* domainSetAutostart */
NULL, /* domainGetSchedulerType */
NULL, /* domainGetSchedulerParameters */
NULL, /* domainSetSchedulerParameters */
};
/**

View File

@ -113,6 +113,9 @@ virDriver xenXMDriver = {
NULL, /* domainDetachDevice */
NULL, /* domainGetAutostart */
NULL, /* domainSetAutostart */
NULL, /* domainGetSchedulerType */
NULL, /* domainGetSchedulerParameters */
NULL, /* domainSetSchedulerParameters */
};
static void

View File

@ -82,6 +82,9 @@ virDriver xenStoreDriver = {
NULL, /* domainDetachDevice */
NULL, /* domainGetAutostart */
NULL, /* domainSetAutostart */
NULL, /* domainGetSchedulerType */
NULL, /* domainGetSchedulerParameters */
NULL, /* domainSetSchedulerParameters */
};
/**