mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-22 14:09:22 +00:00
vcpu: add virsh support
* tools/virsh.c (cmdSetvcpus): Add new flags. Let invalid commands through to driver, to ease testing of hypervisor argument validation. (cmdMaxvcpus, cmdVcpucount): New commands. (commands): Add new commands. * tools/virsh.pod (setvcpus, vcpucount, maxvcpus): Document new behavior.
This commit is contained in:
parent
4617eedfae
commit
bf945ee97b
247
tools/virsh.c
247
tools/virsh.c
@ -2280,11 +2280,217 @@ cmdFreecell(vshControl *ctl, const vshCmd *cmd)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "maxvcpus" command
|
||||||
|
*/
|
||||||
|
static const vshCmdInfo info_maxvcpus[] = {
|
||||||
|
{"help", N_("connection vcpu maximum")},
|
||||||
|
{"desc", N_("Show maximum number of virtual CPUs for guests on this connection.")},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const vshCmdOptDef opts_maxvcpus[] = {
|
||||||
|
{"type", VSH_OT_STRING, 0, N_("domain type")},
|
||||||
|
{NULL, 0, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmdMaxvcpus(vshControl *ctl, const vshCmd *cmd)
|
||||||
|
{
|
||||||
|
char *type;
|
||||||
|
int vcpus;
|
||||||
|
|
||||||
|
type = vshCommandOptString(cmd, "type", NULL);
|
||||||
|
|
||||||
|
if (!vshConnectionUsability(ctl, ctl->conn))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
vcpus = virConnectGetMaxVcpus(ctl->conn, type);
|
||||||
|
if (vcpus < 0)
|
||||||
|
return FALSE;
|
||||||
|
vshPrint(ctl, "%d\n", vcpus);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "vcpucount" command
|
||||||
|
*/
|
||||||
|
static const vshCmdInfo info_vcpucount[] = {
|
||||||
|
{"help", N_("domain vcpu counts")},
|
||||||
|
{"desc", N_("Returns the number of virtual CPUs used by the domain.")},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const vshCmdOptDef opts_vcpucount[] = {
|
||||||
|
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
|
||||||
|
{"maximum", VSH_OT_BOOL, 0, N_("get maximum cap on vcpus")},
|
||||||
|
{"current", VSH_OT_BOOL, 0, N_("get current vcpu usage")},
|
||||||
|
{"config", VSH_OT_BOOL, 0, N_("get value to be used on next boot")},
|
||||||
|
{"live", VSH_OT_BOOL, 0, N_("get value from running domain")},
|
||||||
|
{NULL, 0, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmdVcpucount(vshControl *ctl, const vshCmd *cmd)
|
||||||
|
{
|
||||||
|
virDomainPtr dom;
|
||||||
|
int ret = TRUE;
|
||||||
|
int maximum = vshCommandOptBool(cmd, "maximum");
|
||||||
|
int current = vshCommandOptBool(cmd, "current");
|
||||||
|
int config = vshCommandOptBool(cmd, "config");
|
||||||
|
int live = vshCommandOptBool(cmd, "live");
|
||||||
|
bool all = maximum + current + config + live == 0;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
if (maximum && current) {
|
||||||
|
vshError(ctl, "%s",
|
||||||
|
_("--maximum and --current cannot both be specified"));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (config && live) {
|
||||||
|
vshError(ctl, "%s",
|
||||||
|
_("--config and --live cannot both be specified"));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
/* We want one of each pair of mutually exclusive options; that
|
||||||
|
* is, use of flags requires exactly two options. */
|
||||||
|
if (maximum + current + config + live == 1) {
|
||||||
|
vshError(ctl,
|
||||||
|
_("when using --%s, either --%s or --%s must be specified"),
|
||||||
|
(maximum ? "maximum" : current ? "current"
|
||||||
|
: config ? "config" : "live"),
|
||||||
|
maximum + current ? "config" : "maximum",
|
||||||
|
maximum + current ? "live" : "current");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vshConnectionUsability(ctl, ctl->conn))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* In all cases, try the new API first; if it fails because we are
|
||||||
|
* talking to an older client, try a fallback API before giving
|
||||||
|
* up. */
|
||||||
|
if (all || (maximum && config)) {
|
||||||
|
count = virDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_MAXIMUM |
|
||||||
|
VIR_DOMAIN_VCPU_CONFIG));
|
||||||
|
if (count < 0 && (last_error->code == VIR_ERR_NO_SUPPORT
|
||||||
|
|| last_error->code == VIR_ERR_INVALID_ARG)) {
|
||||||
|
char *tmp;
|
||||||
|
char *xml = virDomainGetXMLDesc(dom, VIR_DOMAIN_XML_INACTIVE);
|
||||||
|
if (xml && (tmp = strstr(xml, "<vcpu"))) {
|
||||||
|
tmp = strchr(tmp, '>');
|
||||||
|
if (!tmp || virStrToLong_i(tmp + 1, &tmp, 10, &count) < 0)
|
||||||
|
count = -1;
|
||||||
|
}
|
||||||
|
VIR_FREE(xml);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count < 0) {
|
||||||
|
virshReportError(ctl);
|
||||||
|
ret = FALSE;
|
||||||
|
} else if (all) {
|
||||||
|
vshPrint(ctl, "%-12s %-12s %3d\n", _("maximum"), _("config"),
|
||||||
|
count);
|
||||||
|
} else {
|
||||||
|
vshPrint(ctl, "%d\n", count);
|
||||||
|
}
|
||||||
|
virFreeError(last_error);
|
||||||
|
last_error = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (all || (maximum && live)) {
|
||||||
|
count = virDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_MAXIMUM |
|
||||||
|
VIR_DOMAIN_VCPU_LIVE));
|
||||||
|
if (count < 0 && (last_error->code == VIR_ERR_NO_SUPPORT
|
||||||
|
|| last_error->code == VIR_ERR_INVALID_ARG)) {
|
||||||
|
count = virDomainGetMaxVcpus(dom);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count < 0) {
|
||||||
|
virshReportError(ctl);
|
||||||
|
ret = FALSE;
|
||||||
|
} else if (all) {
|
||||||
|
vshPrint(ctl, "%-12s %-12s %3d\n", _("maximum"), _("live"),
|
||||||
|
count);
|
||||||
|
} else {
|
||||||
|
vshPrint(ctl, "%d\n", count);
|
||||||
|
}
|
||||||
|
virFreeError(last_error);
|
||||||
|
last_error = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (all || (current && config)) {
|
||||||
|
count = virDomainGetVcpusFlags(dom, VIR_DOMAIN_VCPU_CONFIG);
|
||||||
|
if (count < 0 && (last_error->code == VIR_ERR_NO_SUPPORT
|
||||||
|
|| last_error->code == VIR_ERR_INVALID_ARG)) {
|
||||||
|
char *tmp, *end;
|
||||||
|
char *xml = virDomainGetXMLDesc(dom, VIR_DOMAIN_XML_INACTIVE);
|
||||||
|
if (xml && (tmp = strstr(xml, "<vcpu"))) {
|
||||||
|
end = strchr(tmp, '>');
|
||||||
|
if (end) {
|
||||||
|
*end = '\0';
|
||||||
|
tmp = strstr(tmp, "current=");
|
||||||
|
if (!tmp)
|
||||||
|
tmp = end + 1;
|
||||||
|
else {
|
||||||
|
tmp += strlen("current=");
|
||||||
|
tmp += *tmp == '\'' || *tmp == '"';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!tmp || virStrToLong_i(tmp, &tmp, 10, &count) < 0)
|
||||||
|
count = -1;
|
||||||
|
}
|
||||||
|
VIR_FREE(xml);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count < 0) {
|
||||||
|
virshReportError(ctl);
|
||||||
|
ret = FALSE;
|
||||||
|
} else if (all) {
|
||||||
|
vshPrint(ctl, "%-12s %-12s %3d\n", _("current"), _("config"),
|
||||||
|
count);
|
||||||
|
} else {
|
||||||
|
vshPrint(ctl, "%d\n", count);
|
||||||
|
}
|
||||||
|
virFreeError(last_error);
|
||||||
|
last_error = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (all || (current && live)) {
|
||||||
|
count = virDomainGetVcpusFlags(dom, VIR_DOMAIN_VCPU_LIVE);
|
||||||
|
if (count < 0 && (last_error->code == VIR_ERR_NO_SUPPORT
|
||||||
|
|| last_error->code == VIR_ERR_INVALID_ARG)) {
|
||||||
|
virDomainInfo info;
|
||||||
|
if (virDomainGetInfo(dom, &info) == 0)
|
||||||
|
count = info.nrVirtCpu;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count < 0) {
|
||||||
|
virshReportError(ctl);
|
||||||
|
ret = FALSE;
|
||||||
|
} else if (all) {
|
||||||
|
vshPrint(ctl, "%-12s %-12s %3d\n", _("current"), _("live"),
|
||||||
|
count);
|
||||||
|
} else {
|
||||||
|
vshPrint(ctl, "%d\n", count);
|
||||||
|
}
|
||||||
|
virFreeError(last_error);
|
||||||
|
last_error = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
virDomainFree(dom);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "vcpuinfo" command
|
* "vcpuinfo" command
|
||||||
*/
|
*/
|
||||||
static const vshCmdInfo info_vcpuinfo[] = {
|
static const vshCmdInfo info_vcpuinfo[] = {
|
||||||
{"help", N_("domain vcpu information")},
|
{"help", N_("detailed domain vcpu information")},
|
||||||
{"desc", N_("Returns basic information about the domain virtual CPUs.")},
|
{"desc", N_("Returns basic information about the domain virtual CPUs.")},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
@ -2514,6 +2720,9 @@ static const vshCmdInfo info_setvcpus[] = {
|
|||||||
static const vshCmdOptDef opts_setvcpus[] = {
|
static const vshCmdOptDef opts_setvcpus[] = {
|
||||||
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
|
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
|
||||||
{"count", VSH_OT_DATA, VSH_OFLAG_REQ, N_("number of virtual CPUs")},
|
{"count", VSH_OT_DATA, VSH_OFLAG_REQ, N_("number of virtual CPUs")},
|
||||||
|
{"maximum", VSH_OT_BOOL, 0, N_("set maximum limit on next boot")},
|
||||||
|
{"config", VSH_OT_BOOL, 0, N_("affect next boot")},
|
||||||
|
{"live", VSH_OT_BOOL, 0, N_("affect running domain")},
|
||||||
{NULL, 0, 0, NULL}
|
{NULL, 0, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2522,8 +2731,13 @@ cmdSetvcpus(vshControl *ctl, const vshCmd *cmd)
|
|||||||
{
|
{
|
||||||
virDomainPtr dom;
|
virDomainPtr dom;
|
||||||
int count;
|
int count;
|
||||||
int maxcpu;
|
|
||||||
int ret = TRUE;
|
int ret = TRUE;
|
||||||
|
int maximum = vshCommandOptBool(cmd, "maximum");
|
||||||
|
int config = vshCommandOptBool(cmd, "config");
|
||||||
|
int live = vshCommandOptBool(cmd, "live");
|
||||||
|
int flags = ((maximum ? VIR_DOMAIN_VCPU_MAXIMUM : 0) |
|
||||||
|
(config ? VIR_DOMAIN_VCPU_CONFIG : 0) |
|
||||||
|
(live ? VIR_DOMAIN_VCPU_LIVE : 0));
|
||||||
|
|
||||||
if (!vshConnectionUsability(ctl, ctl->conn))
|
if (!vshConnectionUsability(ctl, ctl->conn))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -2532,26 +2746,15 @@ cmdSetvcpus(vshControl *ctl, const vshCmd *cmd)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
count = vshCommandOptInt(cmd, "count", &count);
|
count = vshCommandOptInt(cmd, "count", &count);
|
||||||
if (count <= 0) {
|
|
||||||
vshError(ctl, "%s", _("Invalid number of virtual CPUs."));
|
|
||||||
virDomainFree(dom);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
maxcpu = virDomainGetMaxVcpus(dom);
|
if (!flags) {
|
||||||
if (maxcpu <= 0) {
|
if (virDomainSetVcpus(dom, count) != 0) {
|
||||||
virDomainFree(dom);
|
ret = FALSE;
|
||||||
return FALSE;
|
}
|
||||||
}
|
} else {
|
||||||
|
if (virDomainSetVcpusFlags(dom, count, flags) < 0) {
|
||||||
if (count > maxcpu) {
|
ret = FALSE;
|
||||||
vshError(ctl, "%s", _("Too many virtual CPUs."));
|
}
|
||||||
virDomainFree(dom);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (virDomainSetVcpus(dom, count) != 0) {
|
|
||||||
ret = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virDomainFree(dom);
|
virDomainFree(dom);
|
||||||
@ -9642,6 +9845,7 @@ static const vshCmdDef commands[] = {
|
|||||||
{"freecell", cmdFreecell, opts_freecell, info_freecell},
|
{"freecell", cmdFreecell, opts_freecell, info_freecell},
|
||||||
{"hostname", cmdHostname, NULL, info_hostname},
|
{"hostname", cmdHostname, NULL, info_hostname},
|
||||||
{"list", cmdList, opts_list, info_list},
|
{"list", cmdList, opts_list, info_list},
|
||||||
|
{"maxvcpus", cmdMaxvcpus, opts_maxvcpus, info_maxvcpus},
|
||||||
{"migrate", cmdMigrate, opts_migrate, info_migrate},
|
{"migrate", cmdMigrate, opts_migrate, info_migrate},
|
||||||
{"migrate-setmaxdowntime", cmdMigrateSetMaxDowntime, opts_migrate_setmaxdowntime, info_migrate_setmaxdowntime},
|
{"migrate-setmaxdowntime", cmdMigrateSetMaxDowntime, opts_migrate_setmaxdowntime, info_migrate_setmaxdowntime},
|
||||||
|
|
||||||
@ -9748,6 +9952,7 @@ static const vshCmdDef commands[] = {
|
|||||||
{"vol-name", cmdVolName, opts_vol_name, info_vol_name},
|
{"vol-name", cmdVolName, opts_vol_name, info_vol_name},
|
||||||
{"vol-key", cmdVolKey, opts_vol_key, info_vol_key},
|
{"vol-key", cmdVolKey, opts_vol_key, info_vol_key},
|
||||||
|
|
||||||
|
{"vcpucount", cmdVcpucount, opts_vcpucount, info_vcpucount},
|
||||||
{"vcpuinfo", cmdVcpuinfo, opts_vcpuinfo, info_vcpuinfo},
|
{"vcpuinfo", cmdVcpuinfo, opts_vcpuinfo, info_vcpuinfo},
|
||||||
{"vcpupin", cmdVcpupin, opts_vcpupin, info_vcpupin},
|
{"vcpupin", cmdVcpupin, opts_vcpupin, info_vcpupin},
|
||||||
{"version", cmdVersion, NULL, info_version},
|
{"version", cmdVersion, NULL, info_version},
|
||||||
|
@ -443,7 +443,14 @@ Remove the managed save file for a domain if it exists. The next time the
|
|||||||
domain is started it will not restore to its previous state but instead will
|
domain is started it will not restore to its previous state but instead will
|
||||||
do a full boot.
|
do a full boot.
|
||||||
|
|
||||||
=item B<migrate> optional I<--live> I<--suspend> I<domain-id> I<desturi> I<migrateuri>
|
=item B<maxvcpus> optional I<type>
|
||||||
|
|
||||||
|
Provide the maximum number of virtual CPUs supported for a guest VM on
|
||||||
|
this connection. If provided, the I<type> parameter must be a valid
|
||||||
|
type attribute for the <domain> element of XML.
|
||||||
|
|
||||||
|
=item B<migrate> optional I<--live> I<--suspend> I<domain-id> I<desturi>
|
||||||
|
I<migrateuri>
|
||||||
|
|
||||||
Migrate domain to another host. Add --live for live migration; --suspend
|
Migrate domain to another host. Add --live for live migration; --suspend
|
||||||
leaves the domain paused on the destination host. The I<desturi> is the
|
leaves the domain paused on the destination host. The I<desturi> is the
|
||||||
@ -521,7 +528,8 @@ Displays the domain memory parameters.
|
|||||||
|
|
||||||
Allows you to set the domain memory parameters. LXC and QEMU/KVM supports these parameters.
|
Allows you to set the domain memory parameters. LXC and QEMU/KVM supports these parameters.
|
||||||
|
|
||||||
=item B<setvcpus> I<domain-id> I<count>
|
=item B<setvcpus> I<domain-id> I<count> optional I<--maximum> I<--config>
|
||||||
|
I<--live>
|
||||||
|
|
||||||
Change the number of virtual CPUs active in the guest domain. Note that
|
Change the number of virtual CPUs active in the guest domain. Note that
|
||||||
I<count> may be limited by host, hypervisor or limit coming from the
|
I<count> may be limited by host, hypervisor or limit coming from the
|
||||||
@ -530,6 +538,17 @@ original description of domain.
|
|||||||
For Xen, you can only adjust the virtual CPUs of a running domain if
|
For Xen, you can only adjust the virtual CPUs of a running domain if
|
||||||
the domain is paravirtualized.
|
the domain is paravirtualized.
|
||||||
|
|
||||||
|
If I<--config> is specified, the change will only affect the next
|
||||||
|
boot of a domain. If I<--live> is specified, the domain must be
|
||||||
|
running, and the change takes place immediately. Both flags may be
|
||||||
|
specified, if supported by the hypervisor. If neither flag is given,
|
||||||
|
then I<--live> is implied and it is up to the hypervisor whether
|
||||||
|
I<--config> is also implied.
|
||||||
|
|
||||||
|
If I<--maximum> is specified, then you must use I<--config> and
|
||||||
|
avoid I<--live>; this flag controls the maximum limit of vcpus that
|
||||||
|
can be hot-plugged the next time the domain is booted.
|
||||||
|
|
||||||
=item B<shutdown> I<domain-id>
|
=item B<shutdown> I<domain-id>
|
||||||
|
|
||||||
Gracefully shuts down a domain. This coordinates with the domain OS
|
Gracefully shuts down a domain. This coordinates with the domain OS
|
||||||
@ -568,6 +587,21 @@ is not available the processes will provide an exit code of 1.
|
|||||||
Undefine the configuration for an inactive domain. Since it's not running
|
Undefine the configuration for an inactive domain. Since it's not running
|
||||||
the domain name or UUID must be used as the I<domain-id>.
|
the domain name or UUID must be used as the I<domain-id>.
|
||||||
|
|
||||||
|
=item B<vcpucount> I<domain-id> optional I<--maximum> I<--current>
|
||||||
|
I<--config> I<--live>
|
||||||
|
|
||||||
|
Print information about the virtual cpu counts of the given
|
||||||
|
I<domain-id>. If no flags are specified, all possible counts are
|
||||||
|
listed in a table; otherwise, the output is limited to just the
|
||||||
|
numeric value requested.
|
||||||
|
|
||||||
|
I<--maximum> requests information on the maximum cap of vcpus that a
|
||||||
|
domain can add via B<setvcpus>, while I<--current> shows the current
|
||||||
|
usage; these two flags cannot both be specified. I<--config>
|
||||||
|
requests information regarding the next time the domain will be
|
||||||
|
booted, while I<--live> requires a running domain and lists current
|
||||||
|
values; these two flags cannot both be specified.
|
||||||
|
|
||||||
=item B<vcpuinfo> I<domain-id>
|
=item B<vcpuinfo> I<domain-id>
|
||||||
|
|
||||||
Returns basic information about the domain virtual CPUs, like the number of
|
Returns basic information about the domain virtual CPUs, like the number of
|
||||||
|
Loading…
Reference in New Issue
Block a user