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>
|
Fri Mar 21 15:59:53 CET 2008 Daniel Veillard <veillard@redhat.com>
|
||||||
|
|
||||||
* configure.in include/libvirt/virterror.h src/Makefile.am
|
* configure.in include/libvirt/virterror.h src/Makefile.am
|
||||||
|
|
|
@ -6,6 +6,8 @@ src/console.c
|
||||||
src/hash.c
|
src/hash.c
|
||||||
src/iptables.c
|
src/iptables.c
|
||||||
src/libvirt.c
|
src/libvirt.c
|
||||||
|
src/lxc_conf.c
|
||||||
|
src/lxc_driver.c
|
||||||
src/proxy_internal.c
|
src/proxy_internal.c
|
||||||
src/qemu_conf.c
|
src/qemu_conf.c
|
||||||
src/qemu_driver.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 xenDaemonDetachDevice(virDomainPtr domain, const char *xml);
|
||||||
static int xenDaemonDomainCoreDump(virDomainPtr domain, const char *filename,
|
static int xenDaemonDomainCoreDump(virDomainPtr domain, const char *filename,
|
||||||
int flags);
|
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 */
|
#endif /* PROXY */
|
||||||
|
|
||||||
#ifndef PROXY
|
#ifndef PROXY
|
||||||
|
@ -105,9 +117,9 @@ struct xenUnifiedDriver xenDaemonDriver = {
|
||||||
xenDaemonDetachDevice, /* domainDetachDevice */
|
xenDaemonDetachDevice, /* domainDetachDevice */
|
||||||
NULL, /* domainGetAutostart */
|
NULL, /* domainGetAutostart */
|
||||||
NULL, /* domainSetAutostart */
|
NULL, /* domainSetAutostart */
|
||||||
NULL, /* domainGetSchedulerType */
|
xenDaemonGetSchedulerType, /* domainGetSchedulerType */
|
||||||
NULL, /* domainGetSchedulerParameters */
|
xenDaemonGetSchedulerParameters, /* domainGetSchedulerParameters */
|
||||||
NULL, /* domainSetSchedulerParameters */
|
xenDaemonSetSchedulerParameters, /* domainSetSchedulerParameters */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3657,6 +3669,281 @@ error:
|
||||||
return(ret);
|
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 /* ! PROXY */
|
||||||
#endif /* WITH_XEN */
|
#endif /* WITH_XEN */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue