mirror of https://gitee.com/openkylin/libvirt.git
* src/xend_internal.c: applied patch from Saori Fukuta adding the
scheduler API for the Xen daemon driver * po/POTFILES.in: add the two new linux container modules Daniel
This commit is contained in:
parent
f163895204
commit
979bb2bb67
|
@ -1,3 +1,9 @@
|
|||
Mon Mar 24 10:20:21 CET 2008 Daniel Veillard <veillard@redhat.com>
|
||||
|
||||
* src/xend_internal.c: applied patch from Saori Fukuta adding the
|
||||
scheduler API for the Xen daemon driver
|
||||
* po/POTFILES.in: add the two new linux container modules
|
||||
|
||||
Fri Mar 21 15:59:53 CET 2008 Daniel Veillard <veillard@redhat.com>
|
||||
|
||||
* configure.in include/libvirt/virterror.h src/Makefile.am
|
||||
|
|
|
@ -6,6 +6,8 @@ src/console.c
|
|||
src/hash.c
|
||||
src/iptables.c
|
||||
src/libvirt.c
|
||||
src/lxc_conf.c
|
||||
src/lxc_driver.c
|
||||
src/proxy_internal.c
|
||||
src/qemu_conf.c
|
||||
src/qemu_driver.c
|
||||
|
|
|
@ -65,6 +65,18 @@ static int xenDaemonAttachDevice(virDomainPtr domain, const char *xml);
|
|||
static int xenDaemonDetachDevice(virDomainPtr domain, const char *xml);
|
||||
static int xenDaemonDomainCoreDump(virDomainPtr domain, const char *filename,
|
||||
int flags);
|
||||
static char *xenDaemonGetSchedulerType(virDomainPtr domain, int *nparams);
|
||||
static int xenDaemonGetSchedulerParameters(virDomainPtr domain,
|
||||
virSchedParameterPtr params, int *nparams);
|
||||
static int xenDaemonSetSchedulerParameters(virDomainPtr domain,
|
||||
virSchedParameterPtr params, int nparams);
|
||||
|
||||
/*
|
||||
* The number of Xen scheduler parameters
|
||||
*/
|
||||
#define XEN_SCHED_SEDF_NPARAM 6
|
||||
#define XEN_SCHED_CRED_NPARAM 2
|
||||
|
||||
#endif /* PROXY */
|
||||
|
||||
#ifndef PROXY
|
||||
|
@ -105,9 +117,9 @@ struct xenUnifiedDriver xenDaemonDriver = {
|
|||
xenDaemonDetachDevice, /* domainDetachDevice */
|
||||
NULL, /* domainGetAutostart */
|
||||
NULL, /* domainSetAutostart */
|
||||
NULL, /* domainGetSchedulerType */
|
||||
NULL, /* domainGetSchedulerParameters */
|
||||
NULL, /* domainSetSchedulerParameters */
|
||||
xenDaemonGetSchedulerType, /* domainGetSchedulerType */
|
||||
xenDaemonGetSchedulerParameters, /* domainGetSchedulerParameters */
|
||||
xenDaemonSetSchedulerParameters, /* domainSetSchedulerParameters */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -3657,6 +3669,281 @@ error:
|
|||
return(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* xenDaemonGetSchedulerType:
|
||||
* @domain: pointer to the Domain block
|
||||
* @nparams: give a number of scheduler parameters
|
||||
*
|
||||
* Get the scheduler type of Xen
|
||||
*
|
||||
* Returns a scheduler name (credit or sedf) which must be freed by the
|
||||
* caller or NULL in case of failure
|
||||
*/
|
||||
static char *
|
||||
xenDaemonGetSchedulerType(virDomainPtr domain, int *nparams)
|
||||
{
|
||||
xenUnifiedPrivatePtr priv;
|
||||
struct sexpr *root;
|
||||
const char *ret = NULL;
|
||||
char *schedulertype = NULL;
|
||||
|
||||
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)
|
||||
|| (nparams == NULL)) {
|
||||
virXendError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
|
||||
__FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Support only xendConfigVersion >=4 */
|
||||
priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
|
||||
if (priv->xendConfigVersion < 4) {
|
||||
virXendError (domain->conn, VIR_ERR_NO_SUPPORT,
|
||||
_("unsupported in xendConfigVersion < 4"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
root = sexpr_get(domain->conn, "/xend/node/");
|
||||
if (root == NULL)
|
||||
return NULL;
|
||||
|
||||
/* get xen_scheduler from xend/node */
|
||||
ret = sexpr_node(root, "node/xen_scheduler");
|
||||
if (ret == NULL){
|
||||
virXendError(domain->conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("node information incomplete, missing scheduler name"));
|
||||
goto error;
|
||||
}
|
||||
if (STREQ (ret, "credit")) {
|
||||
schedulertype = strdup("credit");
|
||||
if (schedulertype == NULL){
|
||||
virXendError(domain->conn, VIR_ERR_SYSTEM_ERROR, _("strdup failed"));
|
||||
goto error;
|
||||
}
|
||||
*nparams = XEN_SCHED_CRED_NPARAM;
|
||||
} else if (STREQ (ret, "sedf")) {
|
||||
schedulertype = strdup("sedf");
|
||||
if (schedulertype == NULL){
|
||||
virXendError(domain->conn, VIR_ERR_SYSTEM_ERROR, _("strdup failed"));
|
||||
goto error;
|
||||
}
|
||||
*nparams = XEN_SCHED_SEDF_NPARAM;
|
||||
} else {
|
||||
virXendError(domain->conn, VIR_ERR_INTERNAL_ERROR, _("Unknown scheduler"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
error:
|
||||
sexpr_free(root);
|
||||
return schedulertype;
|
||||
|
||||
}
|
||||
|
||||
static const char *str_weight = "weight";
|
||||
static const char *str_cap = "cap";
|
||||
|
||||
/**
|
||||
* xenDaemonGetSchedulerParameters:
|
||||
* @domain: pointer to the Domain block
|
||||
* @params: pointer to scheduler parameters
|
||||
* This memory area must be allocated by the caller
|
||||
* @nparams: a number of scheduler parameters which should be same as a
|
||||
* given number from xenDaemonGetSchedulerType()
|
||||
*
|
||||
* Get the scheduler parameters
|
||||
*
|
||||
* Returns 0 or -1 in case of failure
|
||||
*/
|
||||
static int
|
||||
xenDaemonGetSchedulerParameters(virDomainPtr domain,
|
||||
virSchedParameterPtr params, int *nparams)
|
||||
{
|
||||
xenUnifiedPrivatePtr priv;
|
||||
struct sexpr *root;
|
||||
char *sched_type = NULL;
|
||||
int sched_nparam = 0;
|
||||
int ret = -1;
|
||||
|
||||
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)
|
||||
|| (params == NULL) || (nparams == NULL)) {
|
||||
virXendError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
|
||||
__FUNCTION__);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Support only xendConfigVersion >=4 */
|
||||
priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
|
||||
if (priv->xendConfigVersion < 4) {
|
||||
virXendError (domain->conn, VIR_ERR_NO_SUPPORT,
|
||||
_("unsupported in xendConfigVersion < 4"));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* look up the information by domain name */
|
||||
root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name);
|
||||
if (root == NULL)
|
||||
return (-1);
|
||||
|
||||
/* get the scheduler type */
|
||||
sched_type = xenDaemonGetSchedulerType(domain, &sched_nparam);
|
||||
if (sched_type == NULL) {
|
||||
virXendError(domain->conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("Failed to get a scheduler name"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
switch (sched_nparam){
|
||||
case XEN_SCHED_SEDF_NPARAM:
|
||||
/* TODO: Implement for Xen/SEDF */
|
||||
TODO
|
||||
goto error;
|
||||
case XEN_SCHED_CRED_NPARAM:
|
||||
/* get cpu_weight/cpu_cap from xend/domain */
|
||||
if (sexpr_node(root, "domain/cpu_weight") == NULL) {
|
||||
virXendError(domain->conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("domain information incomplete, missing cpu_weight"));
|
||||
goto error;
|
||||
}
|
||||
if (sexpr_node(root, "domain/cpu_cap") == NULL) {
|
||||
virXendError(domain->conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("domain information incomplete, missing cpu_cap"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
strncpy (params[0].field, str_weight, VIR_DOMAIN_SCHED_FIELD_LENGTH);
|
||||
params[0].field[VIR_DOMAIN_SCHED_FIELD_LENGTH-1] = '\0';
|
||||
params[0].type = VIR_DOMAIN_SCHED_FIELD_UINT;
|
||||
params[0].value.ui = sexpr_int(root, "domain/cpu_weight");
|
||||
|
||||
strncpy (params[1].field, str_cap, VIR_DOMAIN_SCHED_FIELD_LENGTH);
|
||||
params[1].field[VIR_DOMAIN_SCHED_FIELD_LENGTH-1] = '\0';
|
||||
params[1].type = VIR_DOMAIN_SCHED_FIELD_UINT;
|
||||
params[1].value.ui = sexpr_int(root, "domain/cpu_cap");
|
||||
*nparams = XEN_SCHED_CRED_NPARAM;
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
virXendError(domain->conn, VIR_ERR_INTERNAL_ERROR, _("Unknown scheduler"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
error:
|
||||
sexpr_free(root);
|
||||
free(sched_type);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* xenDaemonSetSchedulerParameters:
|
||||
* @domain: pointer to the Domain block
|
||||
* @params: pointer to scheduler parameters
|
||||
* @nparams: a number of scheduler setting parameters
|
||||
*
|
||||
* Set the scheduler parameters
|
||||
*
|
||||
* Returns 0 or -1 in case of failure
|
||||
*/
|
||||
static int
|
||||
xenDaemonSetSchedulerParameters(virDomainPtr domain,
|
||||
virSchedParameterPtr params, int nparams)
|
||||
{
|
||||
xenUnifiedPrivatePtr priv;
|
||||
struct sexpr *root;
|
||||
char *sched_type = NULL;
|
||||
int i;
|
||||
int sched_nparam = 0;
|
||||
int ret = -1;
|
||||
|
||||
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)
|
||||
|| (params == NULL)) {
|
||||
virXendError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
|
||||
__FUNCTION__);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Support only xendConfigVersion >=4 and active domains */
|
||||
priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
|
||||
if (priv->xendConfigVersion < 4) {
|
||||
virXendError (domain->conn, VIR_ERR_NO_SUPPORT,
|
||||
_("unsupported in xendConfigVersion < 4"));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* look up the information by domain name */
|
||||
root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name);
|
||||
if (root == NULL)
|
||||
return (-1);
|
||||
|
||||
/* get the scheduler type */
|
||||
sched_type = xenDaemonGetSchedulerType(domain, &sched_nparam);
|
||||
if (sched_type == NULL) {
|
||||
virXendError(domain->conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("Failed to get a scheduler name"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
switch (sched_nparam){
|
||||
case XEN_SCHED_SEDF_NPARAM:
|
||||
/* TODO: Implement for Xen/SEDF */
|
||||
TODO
|
||||
goto error;
|
||||
case XEN_SCHED_CRED_NPARAM: {
|
||||
char buf_weight[VIR_UUID_BUFLEN];
|
||||
char buf_cap[VIR_UUID_BUFLEN];
|
||||
const char *weight = NULL;
|
||||
const char *cap = NULL;
|
||||
|
||||
/* get the scheduler parameters */
|
||||
memset(&buf_weight, 0, VIR_UUID_BUFLEN);
|
||||
memset(&buf_cap, 0, VIR_UUID_BUFLEN);
|
||||
for (i = 0; i < nparams; i++) {
|
||||
if (STREQ (params[i].field, str_weight) &&
|
||||
params[i].type == VIR_DOMAIN_SCHED_FIELD_UINT) {
|
||||
snprintf(buf_weight, sizeof(buf_weight), "%u", params[i].value.ui);
|
||||
} else if (STREQ (params[i].field, str_cap) &&
|
||||
params[i].type == VIR_DOMAIN_SCHED_FIELD_UINT) {
|
||||
snprintf(buf_cap, sizeof(buf_cap), "%u", params[i].value.ui);
|
||||
} else {
|
||||
virXendError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* if not get the scheduler parameter, set the current setting */
|
||||
if (strlen(buf_weight) == 0) {
|
||||
weight = sexpr_node(root, "domain/cpu_weight");
|
||||
if (weight == NULL) {
|
||||
virXendError(domain->conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("domain information incomplete, missing cpu_weight"));
|
||||
goto error;
|
||||
}
|
||||
snprintf(buf_weight, sizeof(buf_weight), "%s", weight);
|
||||
}
|
||||
if (strlen(buf_cap) == 0) {
|
||||
cap = sexpr_node(root, "domain/cpu_cap");
|
||||
if (cap == NULL) {
|
||||
virXendError(domain->conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("domain information incomplete, missing cpu_cap"));
|
||||
goto error;
|
||||
}
|
||||
snprintf(buf_cap, sizeof(buf_cap), "%s", cap);
|
||||
}
|
||||
|
||||
ret = xend_op(domain->conn, domain->name, "op",
|
||||
"domain_sched_credit_set", "weight", buf_weight,
|
||||
"cap", buf_cap, NULL);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
virXendError(domain->conn, VIR_ERR_INTERNAL_ERROR, _("Unknown scheduler"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
error:
|
||||
sexpr_free(root);
|
||||
free(sched_type);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#endif /* ! PROXY */
|
||||
#endif /* WITH_XEN */
|
||||
|
||||
|
|
Loading…
Reference in New Issue