2012-07-24 08:24:50 +00:00
|
|
|
/*
|
|
|
|
* virsh-domain-monitor.c: Commands to monitor domain status
|
|
|
|
*
|
2016-01-09 13:36:24 +00:00
|
|
|
* Copyright (C) 2005, 2007-2016 Red Hat, Inc.
|
2012-07-24 08:24:50 +00:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2012-09-20 22:30:55 +00:00
|
|
|
* License along with this library. If not, see
|
2012-07-24 08:24:50 +00:00
|
|
|
* <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
* Daniel Veillard <veillard@redhat.com>
|
|
|
|
* Karel Zak <kzak@redhat.com>
|
|
|
|
* Daniel P. Berrange <berrange@redhat.com>
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2012-08-20 13:46:38 +00:00
|
|
|
#include <config.h>
|
|
|
|
#include "virsh-domain-monitor.h"
|
2017-04-10 15:06:15 +00:00
|
|
|
#include "virsh-util.h"
|
2012-08-20 13:46:38 +00:00
|
|
|
|
|
|
|
#include <libxml/parser.h>
|
|
|
|
#include <libxml/tree.h>
|
|
|
|
#include <libxml/xpath.h>
|
|
|
|
#include <libxml/xmlsave.h>
|
|
|
|
|
|
|
|
#include "internal.h"
|
2015-07-17 09:11:23 +00:00
|
|
|
#include "conf/virdomainobjlist.h"
|
2012-07-24 08:24:50 +00:00
|
|
|
#include "intprops.h"
|
2012-12-12 18:06:53 +00:00
|
|
|
#include "viralloc.h"
|
2012-08-20 13:46:38 +00:00
|
|
|
#include "virmacaddr.h"
|
2012-12-13 18:13:21 +00:00
|
|
|
#include "virxml.h"
|
2013-04-03 10:36:23 +00:00
|
|
|
#include "virstring.h"
|
2012-07-24 08:24:50 +00:00
|
|
|
|
2016-01-09 13:36:24 +00:00
|
|
|
#define VIRSH_COMMON_OPT_DOMAIN_FULL \
|
|
|
|
VIRSH_COMMON_OPT_DOMAIN(N_("domain name, id or uuid")) \
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
VIR_ENUM_DECL(virshDomainIOError)
|
|
|
|
VIR_ENUM_IMPL(virshDomainIOError,
|
virsh: use more compact VIR_ENUM_IMPL
Dan Berrange suggested that using VIR_ENUM_IMPL is more compact
than open-coding switch statements, and still just as forceful
at making us remember to update lists if we add enum values
in the future. Make this change throughout virsh.
Sure enough, doing this change caught that we missed at least
VIR_STORAGE_VOL_NETDIR.
* tools/virsh-domain-monitor.c (vshDomainIOErrorToString)
(vshDomainControlStateToString, vshDomainStateToString)
(vshDomainStateReasonToString): Change switch to enum lookup.
(cmdDomControl, cmdDominfo): Update caller.
* tools/virsh-domain.c (vshDomainVcpuStateToString)
(vshDomainEventToString, vshDomainEventDetailToString): Change
switch to enum lookup.
(vshDomainBlockJobToString, vshDomainJobToString): New functions.
(cmdVcpuinfo, cmdBlockJob, cmdDomjobinfo, cmdEvent): Update
callers.
* tools/virsh-network.c (vshNetworkEventToString): Change switch
to enum lookup.
* tools/virsh-pool.c (vshStoragePoolStateToString): New function.
(cmdPoolList, cmdPoolInfo): Update callers.
* tools/virsh-volume.c (vshVolumeTypeToString): Change switch to
enum lookup.
(cmdVolInfo, cmdVolList): Update callers.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-02-21 19:55:06 +00:00
|
|
|
VIR_DOMAIN_DISK_ERROR_LAST,
|
|
|
|
N_("no error"),
|
|
|
|
N_("unspecified error"),
|
|
|
|
N_("no space"))
|
|
|
|
|
2012-07-24 08:24:50 +00:00
|
|
|
static const char *
|
2015-06-15 16:53:58 +00:00
|
|
|
virshDomainIOErrorToString(int error)
|
2012-07-24 08:24:50 +00:00
|
|
|
{
|
2015-06-15 16:53:58 +00:00
|
|
|
const char *str = virshDomainIOErrorTypeToString(error);
|
virsh: use more compact VIR_ENUM_IMPL
Dan Berrange suggested that using VIR_ENUM_IMPL is more compact
than open-coding switch statements, and still just as forceful
at making us remember to update lists if we add enum values
in the future. Make this change throughout virsh.
Sure enough, doing this change caught that we missed at least
VIR_STORAGE_VOL_NETDIR.
* tools/virsh-domain-monitor.c (vshDomainIOErrorToString)
(vshDomainControlStateToString, vshDomainStateToString)
(vshDomainStateReasonToString): Change switch to enum lookup.
(cmdDomControl, cmdDominfo): Update caller.
* tools/virsh-domain.c (vshDomainVcpuStateToString)
(vshDomainEventToString, vshDomainEventDetailToString): Change
switch to enum lookup.
(vshDomainBlockJobToString, vshDomainJobToString): New functions.
(cmdVcpuinfo, cmdBlockJob, cmdDomjobinfo, cmdEvent): Update
callers.
* tools/virsh-network.c (vshNetworkEventToString): Change switch
to enum lookup.
* tools/virsh-pool.c (vshStoragePoolStateToString): New function.
(cmdPoolList, cmdPoolInfo): Update callers.
* tools/virsh-volume.c (vshVolumeTypeToString): Change switch to
enum lookup.
(cmdVolInfo, cmdVolList): Update callers.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-02-21 19:55:06 +00:00
|
|
|
return str ? _(str) : _("unknown error");
|
2012-07-24 08:24:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* extract description or title from domain xml */
|
2012-08-18 03:16:04 +00:00
|
|
|
char *
|
2015-06-15 16:53:58 +00:00
|
|
|
virshGetDomainDescription(vshControl *ctl, virDomainPtr dom, bool title,
|
|
|
|
unsigned int flags)
|
2012-07-24 08:24:50 +00:00
|
|
|
{
|
|
|
|
char *desc = NULL;
|
|
|
|
virErrorPtr err = NULL;
|
|
|
|
xmlDocPtr doc = NULL;
|
|
|
|
xmlXPathContextPtr ctxt = NULL;
|
|
|
|
int type;
|
|
|
|
|
|
|
|
if (title)
|
|
|
|
type = VIR_DOMAIN_METADATA_TITLE;
|
|
|
|
else
|
|
|
|
type = VIR_DOMAIN_METADATA_DESCRIPTION;
|
|
|
|
|
|
|
|
if ((desc = virDomainGetMetadata(dom, type, NULL, flags))) {
|
|
|
|
return desc;
|
|
|
|
} else {
|
|
|
|
err = virGetLastError();
|
|
|
|
|
|
|
|
if (err && err->code == VIR_ERR_NO_DOMAIN_METADATA) {
|
|
|
|
desc = vshStrdup(ctl, "");
|
2012-07-26 09:24:30 +00:00
|
|
|
vshResetLibvirtError();
|
2012-07-24 08:24:50 +00:00
|
|
|
return desc;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (err && err->code != VIR_ERR_NO_SUPPORT)
|
|
|
|
return desc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* fall back to xml */
|
2017-04-11 15:33:53 +00:00
|
|
|
if (virshDomainGetXMLFromDom(ctl, dom, flags, &doc, &ctxt) < 0)
|
2012-07-24 08:24:50 +00:00
|
|
|
goto cleanup;
|
2017-04-11 15:33:53 +00:00
|
|
|
|
2012-07-24 08:24:50 +00:00
|
|
|
if (title)
|
|
|
|
desc = virXPathString("string(./title[1])", ctxt);
|
|
|
|
else
|
|
|
|
desc = virXPathString("string(./description[1])", ctxt);
|
|
|
|
|
|
|
|
if (!desc)
|
|
|
|
desc = vshStrdup(ctl, "");
|
|
|
|
|
2014-03-25 06:53:59 +00:00
|
|
|
cleanup:
|
2012-07-24 08:24:50 +00:00
|
|
|
xmlXPathFreeContext(ctxt);
|
|
|
|
xmlFreeDoc(doc);
|
|
|
|
|
|
|
|
return desc;
|
|
|
|
}
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
VIR_ENUM_DECL(virshDomainControlState)
|
|
|
|
VIR_ENUM_IMPL(virshDomainControlState,
|
virsh: use more compact VIR_ENUM_IMPL
Dan Berrange suggested that using VIR_ENUM_IMPL is more compact
than open-coding switch statements, and still just as forceful
at making us remember to update lists if we add enum values
in the future. Make this change throughout virsh.
Sure enough, doing this change caught that we missed at least
VIR_STORAGE_VOL_NETDIR.
* tools/virsh-domain-monitor.c (vshDomainIOErrorToString)
(vshDomainControlStateToString, vshDomainStateToString)
(vshDomainStateReasonToString): Change switch to enum lookup.
(cmdDomControl, cmdDominfo): Update caller.
* tools/virsh-domain.c (vshDomainVcpuStateToString)
(vshDomainEventToString, vshDomainEventDetailToString): Change
switch to enum lookup.
(vshDomainBlockJobToString, vshDomainJobToString): New functions.
(cmdVcpuinfo, cmdBlockJob, cmdDomjobinfo, cmdEvent): Update
callers.
* tools/virsh-network.c (vshNetworkEventToString): Change switch
to enum lookup.
* tools/virsh-pool.c (vshStoragePoolStateToString): New function.
(cmdPoolList, cmdPoolInfo): Update callers.
* tools/virsh-volume.c (vshVolumeTypeToString): Change switch to
enum lookup.
(cmdVolInfo, cmdVolList): Update callers.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-02-21 19:55:06 +00:00
|
|
|
VIR_DOMAIN_CONTROL_LAST,
|
|
|
|
N_("ok"),
|
|
|
|
N_("background job"),
|
|
|
|
N_("occupied"),
|
|
|
|
N_("error"))
|
|
|
|
|
2012-07-24 08:24:50 +00:00
|
|
|
static const char *
|
2015-06-15 16:53:58 +00:00
|
|
|
virshDomainControlStateToString(int state)
|
2012-07-24 08:24:50 +00:00
|
|
|
{
|
2015-06-15 16:53:58 +00:00
|
|
|
const char *str = virshDomainControlStateTypeToString(state);
|
virsh: use more compact VIR_ENUM_IMPL
Dan Berrange suggested that using VIR_ENUM_IMPL is more compact
than open-coding switch statements, and still just as forceful
at making us remember to update lists if we add enum values
in the future. Make this change throughout virsh.
Sure enough, doing this change caught that we missed at least
VIR_STORAGE_VOL_NETDIR.
* tools/virsh-domain-monitor.c (vshDomainIOErrorToString)
(vshDomainControlStateToString, vshDomainStateToString)
(vshDomainStateReasonToString): Change switch to enum lookup.
(cmdDomControl, cmdDominfo): Update caller.
* tools/virsh-domain.c (vshDomainVcpuStateToString)
(vshDomainEventToString, vshDomainEventDetailToString): Change
switch to enum lookup.
(vshDomainBlockJobToString, vshDomainJobToString): New functions.
(cmdVcpuinfo, cmdBlockJob, cmdDomjobinfo, cmdEvent): Update
callers.
* tools/virsh-network.c (vshNetworkEventToString): Change switch
to enum lookup.
* tools/virsh-pool.c (vshStoragePoolStateToString): New function.
(cmdPoolList, cmdPoolInfo): Update callers.
* tools/virsh-volume.c (vshVolumeTypeToString): Change switch to
enum lookup.
(cmdVolInfo, cmdVolList): Update callers.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-02-21 19:55:06 +00:00
|
|
|
return str ? _(str) : _("unknown");
|
2012-07-24 08:24:50 +00:00
|
|
|
}
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
VIR_ENUM_DECL(virshDomainControlErrorReason)
|
|
|
|
VIR_ENUM_IMPL(virshDomainControlErrorReason,
|
2015-02-19 10:53:42 +00:00
|
|
|
VIR_DOMAIN_CONTROL_ERROR_REASON_LAST,
|
|
|
|
"",
|
|
|
|
N_("unknown"),
|
|
|
|
N_("monitor failure"),
|
|
|
|
N_("internal (locking) error"))
|
|
|
|
|
|
|
|
static const char *
|
2015-06-15 16:53:58 +00:00
|
|
|
virshDomainControlErrorReasonToString(int reason)
|
2015-02-19 10:53:42 +00:00
|
|
|
{
|
2015-06-15 16:53:58 +00:00
|
|
|
const char *ret = virshDomainControlErrorReasonTypeToString(reason);
|
2015-02-19 10:53:42 +00:00
|
|
|
return ret ? _(ret) : _("unknown");
|
|
|
|
}
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
VIR_ENUM_DECL(virshDomainState)
|
|
|
|
VIR_ENUM_IMPL(virshDomainState,
|
virsh: use more compact VIR_ENUM_IMPL
Dan Berrange suggested that using VIR_ENUM_IMPL is more compact
than open-coding switch statements, and still just as forceful
at making us remember to update lists if we add enum values
in the future. Make this change throughout virsh.
Sure enough, doing this change caught that we missed at least
VIR_STORAGE_VOL_NETDIR.
* tools/virsh-domain-monitor.c (vshDomainIOErrorToString)
(vshDomainControlStateToString, vshDomainStateToString)
(vshDomainStateReasonToString): Change switch to enum lookup.
(cmdDomControl, cmdDominfo): Update caller.
* tools/virsh-domain.c (vshDomainVcpuStateToString)
(vshDomainEventToString, vshDomainEventDetailToString): Change
switch to enum lookup.
(vshDomainBlockJobToString, vshDomainJobToString): New functions.
(cmdVcpuinfo, cmdBlockJob, cmdDomjobinfo, cmdEvent): Update
callers.
* tools/virsh-network.c (vshNetworkEventToString): Change switch
to enum lookup.
* tools/virsh-pool.c (vshStoragePoolStateToString): New function.
(cmdPoolList, cmdPoolInfo): Update callers.
* tools/virsh-volume.c (vshVolumeTypeToString): Change switch to
enum lookup.
(cmdVolInfo, cmdVolList): Update callers.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-02-21 19:55:06 +00:00
|
|
|
VIR_DOMAIN_LAST,
|
|
|
|
N_("no state"),
|
|
|
|
N_("running"),
|
|
|
|
N_("idle"),
|
|
|
|
N_("paused"),
|
|
|
|
N_("in shutdown"),
|
|
|
|
N_("shut off"),
|
|
|
|
N_("crashed"),
|
|
|
|
N_("pmsuspended"))
|
|
|
|
|
2012-07-24 08:24:50 +00:00
|
|
|
static const char *
|
2015-06-15 16:53:58 +00:00
|
|
|
virshDomainStateToString(int state)
|
2012-07-24 08:24:50 +00:00
|
|
|
{
|
2015-06-15 16:53:58 +00:00
|
|
|
const char *str = virshDomainStateTypeToString(state);
|
virsh: use more compact VIR_ENUM_IMPL
Dan Berrange suggested that using VIR_ENUM_IMPL is more compact
than open-coding switch statements, and still just as forceful
at making us remember to update lists if we add enum values
in the future. Make this change throughout virsh.
Sure enough, doing this change caught that we missed at least
VIR_STORAGE_VOL_NETDIR.
* tools/virsh-domain-monitor.c (vshDomainIOErrorToString)
(vshDomainControlStateToString, vshDomainStateToString)
(vshDomainStateReasonToString): Change switch to enum lookup.
(cmdDomControl, cmdDominfo): Update caller.
* tools/virsh-domain.c (vshDomainVcpuStateToString)
(vshDomainEventToString, vshDomainEventDetailToString): Change
switch to enum lookup.
(vshDomainBlockJobToString, vshDomainJobToString): New functions.
(cmdVcpuinfo, cmdBlockJob, cmdDomjobinfo, cmdEvent): Update
callers.
* tools/virsh-network.c (vshNetworkEventToString): Change switch
to enum lookup.
* tools/virsh-pool.c (vshStoragePoolStateToString): New function.
(cmdPoolList, cmdPoolInfo): Update callers.
* tools/virsh-volume.c (vshVolumeTypeToString): Change switch to
enum lookup.
(cmdVolInfo, cmdVolList): Update callers.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-02-21 19:55:06 +00:00
|
|
|
return str ? _(str) : _("no state");
|
2012-07-24 08:24:50 +00:00
|
|
|
}
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
VIR_ENUM_DECL(virshDomainNostateReason)
|
|
|
|
VIR_ENUM_IMPL(virshDomainNostateReason,
|
virsh: use more compact VIR_ENUM_IMPL
Dan Berrange suggested that using VIR_ENUM_IMPL is more compact
than open-coding switch statements, and still just as forceful
at making us remember to update lists if we add enum values
in the future. Make this change throughout virsh.
Sure enough, doing this change caught that we missed at least
VIR_STORAGE_VOL_NETDIR.
* tools/virsh-domain-monitor.c (vshDomainIOErrorToString)
(vshDomainControlStateToString, vshDomainStateToString)
(vshDomainStateReasonToString): Change switch to enum lookup.
(cmdDomControl, cmdDominfo): Update caller.
* tools/virsh-domain.c (vshDomainVcpuStateToString)
(vshDomainEventToString, vshDomainEventDetailToString): Change
switch to enum lookup.
(vshDomainBlockJobToString, vshDomainJobToString): New functions.
(cmdVcpuinfo, cmdBlockJob, cmdDomjobinfo, cmdEvent): Update
callers.
* tools/virsh-network.c (vshNetworkEventToString): Change switch
to enum lookup.
* tools/virsh-pool.c (vshStoragePoolStateToString): New function.
(cmdPoolList, cmdPoolInfo): Update callers.
* tools/virsh-volume.c (vshVolumeTypeToString): Change switch to
enum lookup.
(cmdVolInfo, cmdVolList): Update callers.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-02-21 19:55:06 +00:00
|
|
|
VIR_DOMAIN_NOSTATE_LAST,
|
|
|
|
N_("unknown"))
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
VIR_ENUM_DECL(virshDomainRunningReason)
|
|
|
|
VIR_ENUM_IMPL(virshDomainRunningReason,
|
virsh: use more compact VIR_ENUM_IMPL
Dan Berrange suggested that using VIR_ENUM_IMPL is more compact
than open-coding switch statements, and still just as forceful
at making us remember to update lists if we add enum values
in the future. Make this change throughout virsh.
Sure enough, doing this change caught that we missed at least
VIR_STORAGE_VOL_NETDIR.
* tools/virsh-domain-monitor.c (vshDomainIOErrorToString)
(vshDomainControlStateToString, vshDomainStateToString)
(vshDomainStateReasonToString): Change switch to enum lookup.
(cmdDomControl, cmdDominfo): Update caller.
* tools/virsh-domain.c (vshDomainVcpuStateToString)
(vshDomainEventToString, vshDomainEventDetailToString): Change
switch to enum lookup.
(vshDomainBlockJobToString, vshDomainJobToString): New functions.
(cmdVcpuinfo, cmdBlockJob, cmdDomjobinfo, cmdEvent): Update
callers.
* tools/virsh-network.c (vshNetworkEventToString): Change switch
to enum lookup.
* tools/virsh-pool.c (vshStoragePoolStateToString): New function.
(cmdPoolList, cmdPoolInfo): Update callers.
* tools/virsh-volume.c (vshVolumeTypeToString): Change switch to
enum lookup.
(cmdVolInfo, cmdVolList): Update callers.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-02-21 19:55:06 +00:00
|
|
|
VIR_DOMAIN_RUNNING_LAST,
|
2014-02-26 17:06:13 +00:00
|
|
|
N_("unknown"),
|
virsh: use more compact VIR_ENUM_IMPL
Dan Berrange suggested that using VIR_ENUM_IMPL is more compact
than open-coding switch statements, and still just as forceful
at making us remember to update lists if we add enum values
in the future. Make this change throughout virsh.
Sure enough, doing this change caught that we missed at least
VIR_STORAGE_VOL_NETDIR.
* tools/virsh-domain-monitor.c (vshDomainIOErrorToString)
(vshDomainControlStateToString, vshDomainStateToString)
(vshDomainStateReasonToString): Change switch to enum lookup.
(cmdDomControl, cmdDominfo): Update caller.
* tools/virsh-domain.c (vshDomainVcpuStateToString)
(vshDomainEventToString, vshDomainEventDetailToString): Change
switch to enum lookup.
(vshDomainBlockJobToString, vshDomainJobToString): New functions.
(cmdVcpuinfo, cmdBlockJob, cmdDomjobinfo, cmdEvent): Update
callers.
* tools/virsh-network.c (vshNetworkEventToString): Change switch
to enum lookup.
* tools/virsh-pool.c (vshStoragePoolStateToString): New function.
(cmdPoolList, cmdPoolInfo): Update callers.
* tools/virsh-volume.c (vshVolumeTypeToString): Change switch to
enum lookup.
(cmdVolInfo, cmdVolList): Update callers.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-02-21 19:55:06 +00:00
|
|
|
N_("booted"),
|
|
|
|
N_("migrated"),
|
|
|
|
N_("restored"),
|
|
|
|
N_("from snapshot"),
|
|
|
|
N_("unpaused"),
|
|
|
|
N_("migration canceled"),
|
|
|
|
N_("save canceled"),
|
|
|
|
N_("event wakeup"),
|
2016-01-05 11:08:37 +00:00
|
|
|
N_("crashed"),
|
|
|
|
N_("post-copy"))
|
virsh: use more compact VIR_ENUM_IMPL
Dan Berrange suggested that using VIR_ENUM_IMPL is more compact
than open-coding switch statements, and still just as forceful
at making us remember to update lists if we add enum values
in the future. Make this change throughout virsh.
Sure enough, doing this change caught that we missed at least
VIR_STORAGE_VOL_NETDIR.
* tools/virsh-domain-monitor.c (vshDomainIOErrorToString)
(vshDomainControlStateToString, vshDomainStateToString)
(vshDomainStateReasonToString): Change switch to enum lookup.
(cmdDomControl, cmdDominfo): Update caller.
* tools/virsh-domain.c (vshDomainVcpuStateToString)
(vshDomainEventToString, vshDomainEventDetailToString): Change
switch to enum lookup.
(vshDomainBlockJobToString, vshDomainJobToString): New functions.
(cmdVcpuinfo, cmdBlockJob, cmdDomjobinfo, cmdEvent): Update
callers.
* tools/virsh-network.c (vshNetworkEventToString): Change switch
to enum lookup.
* tools/virsh-pool.c (vshStoragePoolStateToString): New function.
(cmdPoolList, cmdPoolInfo): Update callers.
* tools/virsh-volume.c (vshVolumeTypeToString): Change switch to
enum lookup.
(cmdVolInfo, cmdVolList): Update callers.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-02-21 19:55:06 +00:00
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
VIR_ENUM_DECL(virshDomainBlockedReason)
|
|
|
|
VIR_ENUM_IMPL(virshDomainBlockedReason,
|
virsh: use more compact VIR_ENUM_IMPL
Dan Berrange suggested that using VIR_ENUM_IMPL is more compact
than open-coding switch statements, and still just as forceful
at making us remember to update lists if we add enum values
in the future. Make this change throughout virsh.
Sure enough, doing this change caught that we missed at least
VIR_STORAGE_VOL_NETDIR.
* tools/virsh-domain-monitor.c (vshDomainIOErrorToString)
(vshDomainControlStateToString, vshDomainStateToString)
(vshDomainStateReasonToString): Change switch to enum lookup.
(cmdDomControl, cmdDominfo): Update caller.
* tools/virsh-domain.c (vshDomainVcpuStateToString)
(vshDomainEventToString, vshDomainEventDetailToString): Change
switch to enum lookup.
(vshDomainBlockJobToString, vshDomainJobToString): New functions.
(cmdVcpuinfo, cmdBlockJob, cmdDomjobinfo, cmdEvent): Update
callers.
* tools/virsh-network.c (vshNetworkEventToString): Change switch
to enum lookup.
* tools/virsh-pool.c (vshStoragePoolStateToString): New function.
(cmdPoolList, cmdPoolInfo): Update callers.
* tools/virsh-volume.c (vshVolumeTypeToString): Change switch to
enum lookup.
(cmdVolInfo, cmdVolList): Update callers.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-02-21 19:55:06 +00:00
|
|
|
VIR_DOMAIN_BLOCKED_LAST,
|
|
|
|
N_("unknown"))
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
VIR_ENUM_DECL(virshDomainPausedReason)
|
|
|
|
VIR_ENUM_IMPL(virshDomainPausedReason,
|
virsh: use more compact VIR_ENUM_IMPL
Dan Berrange suggested that using VIR_ENUM_IMPL is more compact
than open-coding switch statements, and still just as forceful
at making us remember to update lists if we add enum values
in the future. Make this change throughout virsh.
Sure enough, doing this change caught that we missed at least
VIR_STORAGE_VOL_NETDIR.
* tools/virsh-domain-monitor.c (vshDomainIOErrorToString)
(vshDomainControlStateToString, vshDomainStateToString)
(vshDomainStateReasonToString): Change switch to enum lookup.
(cmdDomControl, cmdDominfo): Update caller.
* tools/virsh-domain.c (vshDomainVcpuStateToString)
(vshDomainEventToString, vshDomainEventDetailToString): Change
switch to enum lookup.
(vshDomainBlockJobToString, vshDomainJobToString): New functions.
(cmdVcpuinfo, cmdBlockJob, cmdDomjobinfo, cmdEvent): Update
callers.
* tools/virsh-network.c (vshNetworkEventToString): Change switch
to enum lookup.
* tools/virsh-pool.c (vshStoragePoolStateToString): New function.
(cmdPoolList, cmdPoolInfo): Update callers.
* tools/virsh-volume.c (vshVolumeTypeToString): Change switch to
enum lookup.
(cmdVolInfo, cmdVolList): Update callers.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-02-21 19:55:06 +00:00
|
|
|
VIR_DOMAIN_PAUSED_LAST,
|
|
|
|
N_("unknown"),
|
|
|
|
N_("user"),
|
|
|
|
N_("migrating"),
|
|
|
|
N_("saving"),
|
|
|
|
N_("dumping"),
|
|
|
|
N_("I/O error"),
|
|
|
|
N_("watchdog"),
|
|
|
|
N_("from snapshot"),
|
|
|
|
N_("shutting down"),
|
|
|
|
N_("creating snapshot"),
|
2015-02-16 14:17:00 +00:00
|
|
|
N_("crashed"),
|
2016-01-05 11:08:37 +00:00
|
|
|
N_("starting up"),
|
|
|
|
N_("post-copy"),
|
|
|
|
N_("post-copy failed"))
|
virsh: use more compact VIR_ENUM_IMPL
Dan Berrange suggested that using VIR_ENUM_IMPL is more compact
than open-coding switch statements, and still just as forceful
at making us remember to update lists if we add enum values
in the future. Make this change throughout virsh.
Sure enough, doing this change caught that we missed at least
VIR_STORAGE_VOL_NETDIR.
* tools/virsh-domain-monitor.c (vshDomainIOErrorToString)
(vshDomainControlStateToString, vshDomainStateToString)
(vshDomainStateReasonToString): Change switch to enum lookup.
(cmdDomControl, cmdDominfo): Update caller.
* tools/virsh-domain.c (vshDomainVcpuStateToString)
(vshDomainEventToString, vshDomainEventDetailToString): Change
switch to enum lookup.
(vshDomainBlockJobToString, vshDomainJobToString): New functions.
(cmdVcpuinfo, cmdBlockJob, cmdDomjobinfo, cmdEvent): Update
callers.
* tools/virsh-network.c (vshNetworkEventToString): Change switch
to enum lookup.
* tools/virsh-pool.c (vshStoragePoolStateToString): New function.
(cmdPoolList, cmdPoolInfo): Update callers.
* tools/virsh-volume.c (vshVolumeTypeToString): Change switch to
enum lookup.
(cmdVolInfo, cmdVolList): Update callers.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-02-21 19:55:06 +00:00
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
VIR_ENUM_DECL(virshDomainShutdownReason)
|
|
|
|
VIR_ENUM_IMPL(virshDomainShutdownReason,
|
virsh: use more compact VIR_ENUM_IMPL
Dan Berrange suggested that using VIR_ENUM_IMPL is more compact
than open-coding switch statements, and still just as forceful
at making us remember to update lists if we add enum values
in the future. Make this change throughout virsh.
Sure enough, doing this change caught that we missed at least
VIR_STORAGE_VOL_NETDIR.
* tools/virsh-domain-monitor.c (vshDomainIOErrorToString)
(vshDomainControlStateToString, vshDomainStateToString)
(vshDomainStateReasonToString): Change switch to enum lookup.
(cmdDomControl, cmdDominfo): Update caller.
* tools/virsh-domain.c (vshDomainVcpuStateToString)
(vshDomainEventToString, vshDomainEventDetailToString): Change
switch to enum lookup.
(vshDomainBlockJobToString, vshDomainJobToString): New functions.
(cmdVcpuinfo, cmdBlockJob, cmdDomjobinfo, cmdEvent): Update
callers.
* tools/virsh-network.c (vshNetworkEventToString): Change switch
to enum lookup.
* tools/virsh-pool.c (vshStoragePoolStateToString): New function.
(cmdPoolList, cmdPoolInfo): Update callers.
* tools/virsh-volume.c (vshVolumeTypeToString): Change switch to
enum lookup.
(cmdVolInfo, cmdVolList): Update callers.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-02-21 19:55:06 +00:00
|
|
|
VIR_DOMAIN_SHUTDOWN_LAST,
|
|
|
|
N_("unknown"),
|
|
|
|
N_("user"))
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
VIR_ENUM_DECL(virshDomainShutoffReason)
|
|
|
|
VIR_ENUM_IMPL(virshDomainShutoffReason,
|
virsh: use more compact VIR_ENUM_IMPL
Dan Berrange suggested that using VIR_ENUM_IMPL is more compact
than open-coding switch statements, and still just as forceful
at making us remember to update lists if we add enum values
in the future. Make this change throughout virsh.
Sure enough, doing this change caught that we missed at least
VIR_STORAGE_VOL_NETDIR.
* tools/virsh-domain-monitor.c (vshDomainIOErrorToString)
(vshDomainControlStateToString, vshDomainStateToString)
(vshDomainStateReasonToString): Change switch to enum lookup.
(cmdDomControl, cmdDominfo): Update caller.
* tools/virsh-domain.c (vshDomainVcpuStateToString)
(vshDomainEventToString, vshDomainEventDetailToString): Change
switch to enum lookup.
(vshDomainBlockJobToString, vshDomainJobToString): New functions.
(cmdVcpuinfo, cmdBlockJob, cmdDomjobinfo, cmdEvent): Update
callers.
* tools/virsh-network.c (vshNetworkEventToString): Change switch
to enum lookup.
* tools/virsh-pool.c (vshStoragePoolStateToString): New function.
(cmdPoolList, cmdPoolInfo): Update callers.
* tools/virsh-volume.c (vshVolumeTypeToString): Change switch to
enum lookup.
(cmdVolInfo, cmdVolList): Update callers.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-02-21 19:55:06 +00:00
|
|
|
VIR_DOMAIN_SHUTOFF_LAST,
|
|
|
|
N_("unknown"),
|
|
|
|
N_("shutdown"),
|
|
|
|
N_("destroyed"),
|
|
|
|
N_("crashed"),
|
|
|
|
N_("migrated"),
|
|
|
|
N_("saved"),
|
|
|
|
N_("failed"),
|
|
|
|
N_("from snapshot"))
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
VIR_ENUM_DECL(virshDomainCrashedReason)
|
|
|
|
VIR_ENUM_IMPL(virshDomainCrashedReason,
|
virsh: use more compact VIR_ENUM_IMPL
Dan Berrange suggested that using VIR_ENUM_IMPL is more compact
than open-coding switch statements, and still just as forceful
at making us remember to update lists if we add enum values
in the future. Make this change throughout virsh.
Sure enough, doing this change caught that we missed at least
VIR_STORAGE_VOL_NETDIR.
* tools/virsh-domain-monitor.c (vshDomainIOErrorToString)
(vshDomainControlStateToString, vshDomainStateToString)
(vshDomainStateReasonToString): Change switch to enum lookup.
(cmdDomControl, cmdDominfo): Update caller.
* tools/virsh-domain.c (vshDomainVcpuStateToString)
(vshDomainEventToString, vshDomainEventDetailToString): Change
switch to enum lookup.
(vshDomainBlockJobToString, vshDomainJobToString): New functions.
(cmdVcpuinfo, cmdBlockJob, cmdDomjobinfo, cmdEvent): Update
callers.
* tools/virsh-network.c (vshNetworkEventToString): Change switch
to enum lookup.
* tools/virsh-pool.c (vshStoragePoolStateToString): New function.
(cmdPoolList, cmdPoolInfo): Update callers.
* tools/virsh-volume.c (vshVolumeTypeToString): Change switch to
enum lookup.
(cmdVolInfo, cmdVolList): Update callers.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-02-21 19:55:06 +00:00
|
|
|
VIR_DOMAIN_CRASHED_LAST,
|
|
|
|
N_("unknown"),
|
|
|
|
N_("panicked"))
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
VIR_ENUM_DECL(virshDomainPMSuspendedReason)
|
|
|
|
VIR_ENUM_IMPL(virshDomainPMSuspendedReason,
|
virsh: use more compact VIR_ENUM_IMPL
Dan Berrange suggested that using VIR_ENUM_IMPL is more compact
than open-coding switch statements, and still just as forceful
at making us remember to update lists if we add enum values
in the future. Make this change throughout virsh.
Sure enough, doing this change caught that we missed at least
VIR_STORAGE_VOL_NETDIR.
* tools/virsh-domain-monitor.c (vshDomainIOErrorToString)
(vshDomainControlStateToString, vshDomainStateToString)
(vshDomainStateReasonToString): Change switch to enum lookup.
(cmdDomControl, cmdDominfo): Update caller.
* tools/virsh-domain.c (vshDomainVcpuStateToString)
(vshDomainEventToString, vshDomainEventDetailToString): Change
switch to enum lookup.
(vshDomainBlockJobToString, vshDomainJobToString): New functions.
(cmdVcpuinfo, cmdBlockJob, cmdDomjobinfo, cmdEvent): Update
callers.
* tools/virsh-network.c (vshNetworkEventToString): Change switch
to enum lookup.
* tools/virsh-pool.c (vshStoragePoolStateToString): New function.
(cmdPoolList, cmdPoolInfo): Update callers.
* tools/virsh-volume.c (vshVolumeTypeToString): Change switch to
enum lookup.
(cmdVolInfo, cmdVolList): Update callers.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-02-21 19:55:06 +00:00
|
|
|
VIR_DOMAIN_PMSUSPENDED_LAST,
|
|
|
|
N_("unknown"))
|
|
|
|
|
2012-07-24 08:24:50 +00:00
|
|
|
static const char *
|
2015-06-15 16:53:58 +00:00
|
|
|
virshDomainStateReasonToString(int state, int reason)
|
2012-07-24 08:24:50 +00:00
|
|
|
{
|
2014-02-25 06:28:25 +00:00
|
|
|
const char *str = NULL;
|
2012-07-24 08:24:50 +00:00
|
|
|
switch ((virDomainState) state) {
|
|
|
|
case VIR_DOMAIN_NOSTATE:
|
2015-06-15 16:53:58 +00:00
|
|
|
str = virshDomainNostateReasonTypeToString(reason);
|
2012-07-24 08:24:50 +00:00
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_RUNNING:
|
2015-06-15 16:53:58 +00:00
|
|
|
str = virshDomainRunningReasonTypeToString(reason);
|
2012-07-24 08:24:50 +00:00
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_BLOCKED:
|
2015-06-15 16:53:58 +00:00
|
|
|
str = virshDomainBlockedReasonTypeToString(reason);
|
2012-07-24 08:24:50 +00:00
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_PAUSED:
|
2015-06-15 16:53:58 +00:00
|
|
|
str = virshDomainPausedReasonTypeToString(reason);
|
2012-07-24 08:24:50 +00:00
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_SHUTDOWN:
|
2015-06-15 16:53:58 +00:00
|
|
|
str = virshDomainShutdownReasonTypeToString(reason);
|
2012-07-24 08:24:50 +00:00
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_SHUTOFF:
|
2015-06-15 16:53:58 +00:00
|
|
|
str = virshDomainShutoffReasonTypeToString(reason);
|
2012-07-24 08:24:50 +00:00
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_CRASHED:
|
2015-06-15 16:53:58 +00:00
|
|
|
str = virshDomainCrashedReasonTypeToString(reason);
|
2012-07-24 08:24:50 +00:00
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_PMSUSPENDED:
|
2015-06-15 16:53:58 +00:00
|
|
|
str = virshDomainPMSuspendedReasonTypeToString(reason);
|
2012-07-24 08:24:50 +00:00
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_LAST:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
virsh: use more compact VIR_ENUM_IMPL
Dan Berrange suggested that using VIR_ENUM_IMPL is more compact
than open-coding switch statements, and still just as forceful
at making us remember to update lists if we add enum values
in the future. Make this change throughout virsh.
Sure enough, doing this change caught that we missed at least
VIR_STORAGE_VOL_NETDIR.
* tools/virsh-domain-monitor.c (vshDomainIOErrorToString)
(vshDomainControlStateToString, vshDomainStateToString)
(vshDomainStateReasonToString): Change switch to enum lookup.
(cmdDomControl, cmdDominfo): Update caller.
* tools/virsh-domain.c (vshDomainVcpuStateToString)
(vshDomainEventToString, vshDomainEventDetailToString): Change
switch to enum lookup.
(vshDomainBlockJobToString, vshDomainJobToString): New functions.
(cmdVcpuinfo, cmdBlockJob, cmdDomjobinfo, cmdEvent): Update
callers.
* tools/virsh-network.c (vshNetworkEventToString): Change switch
to enum lookup.
* tools/virsh-pool.c (vshStoragePoolStateToString): New function.
(cmdPoolList, cmdPoolInfo): Update callers.
* tools/virsh-volume.c (vshVolumeTypeToString): Change switch to
enum lookup.
(cmdVolInfo, cmdVolList): Update callers.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-02-21 19:55:06 +00:00
|
|
|
return str ? _(str) : _("unknown");
|
2012-07-24 08:24:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* "dommemstat" command
|
|
|
|
*/
|
|
|
|
static const vshCmdInfo info_dommemstat[] = {
|
2013-02-07 15:25:10 +00:00
|
|
|
{.name = "help",
|
|
|
|
.data = N_("get memory statistics for a domain")
|
|
|
|
},
|
|
|
|
{.name = "desc",
|
|
|
|
.data = N_("Get memory statistics for a running domain.")
|
|
|
|
},
|
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const vshCmdOptDef opts_dommemstat[] = {
|
2016-01-09 13:36:24 +00:00
|
|
|
VIRSH_COMMON_OPT_DOMAIN_FULL,
|
2013-07-08 17:19:43 +00:00
|
|
|
{.name = "period",
|
2015-05-15 16:14:40 +00:00
|
|
|
.type = VSH_OT_INT,
|
2013-07-08 17:19:43 +00:00
|
|
|
.flags = VSH_OFLAG_REQ_OPT,
|
|
|
|
.help = N_("period in seconds to set collection")
|
|
|
|
},
|
2016-01-09 13:36:26 +00:00
|
|
|
VIRSH_COMMON_OPT_CONFIG(N_("affect next boot")),
|
2016-01-09 13:36:27 +00:00
|
|
|
VIRSH_COMMON_OPT_LIVE(N_("affect running domain")),
|
2016-01-09 13:36:28 +00:00
|
|
|
VIRSH_COMMON_OPT_CURRENT(N_("affect current domain")),
|
2013-01-14 13:03:21 +00:00
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static bool
|
|
|
|
cmdDomMemStat(vshControl *ctl, const vshCmd *cmd)
|
|
|
|
{
|
|
|
|
virDomainPtr dom;
|
|
|
|
const char *name;
|
2014-09-16 13:19:47 +00:00
|
|
|
virDomainMemoryStatStruct stats[VIR_DOMAIN_MEMORY_STAT_NR];
|
Convert 'int i' to 'size_t i' in tools/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
unsigned int nr_stats;
|
|
|
|
size_t i;
|
2014-11-17 23:39:48 +00:00
|
|
|
bool ret = false;
|
2013-07-08 17:19:43 +00:00
|
|
|
int rv = 0;
|
|
|
|
int period = -1;
|
|
|
|
bool config = vshCommandOptBool(cmd, "config");
|
|
|
|
bool live = vshCommandOptBool(cmd, "live");
|
|
|
|
bool current = vshCommandOptBool(cmd, "current");
|
|
|
|
unsigned int flags = VIR_DOMAIN_AFFECT_CURRENT;
|
|
|
|
|
|
|
|
VSH_EXCLUSIVE_OPTIONS_VAR(current, live);
|
|
|
|
VSH_EXCLUSIVE_OPTIONS_VAR(current, config);
|
|
|
|
if (config)
|
|
|
|
flags |= VIR_DOMAIN_AFFECT_CONFIG;
|
|
|
|
if (live)
|
|
|
|
flags |= VIR_DOMAIN_AFFECT_LIVE;
|
2012-07-24 08:24:50 +00:00
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
if (!(dom = virshCommandOptDomain(ctl, cmd, &name)))
|
2012-07-24 08:24:50 +00:00
|
|
|
return false;
|
|
|
|
|
2013-07-08 17:19:43 +00:00
|
|
|
/* If none of the options were specified and we're active
|
|
|
|
* then be sure to allow active modification */
|
|
|
|
if (!current && !live && !config && virDomainIsActive(dom) == 1)
|
|
|
|
flags |= VIR_DOMAIN_AFFECT_LIVE;
|
|
|
|
|
|
|
|
/* Providing a period will adjust the balloon driver collection period.
|
|
|
|
* This is not really an unsigned long, but it
|
|
|
|
*/
|
2015-06-02 09:17:29 +00:00
|
|
|
if ((rv = vshCommandOptInt(ctl, cmd, "period", &period)) < 0)
|
2013-07-08 17:19:43 +00:00
|
|
|
goto cleanup;
|
|
|
|
if (rv > 0) {
|
|
|
|
if (period < 0) {
|
|
|
|
vshError(ctl, _("Invalid collection period value '%d'"), period);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virDomainSetMemoryStatsPeriod(dom, period, flags) < 0) {
|
|
|
|
vshError(ctl, "%s",
|
|
|
|
_("Unable to change balloon collection period."));
|
|
|
|
} else {
|
|
|
|
ret = true;
|
|
|
|
}
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2012-07-24 08:24:50 +00:00
|
|
|
nr_stats = virDomainMemoryStats(dom, stats, VIR_DOMAIN_MEMORY_STAT_NR, 0);
|
|
|
|
if (nr_stats == -1) {
|
|
|
|
vshError(ctl, _("Failed to get memory statistics for domain %s"), name);
|
2013-07-08 17:19:43 +00:00
|
|
|
goto cleanup;
|
2012-07-24 08:24:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < nr_stats; i++) {
|
|
|
|
if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_SWAP_IN)
|
|
|
|
vshPrint(ctl, "swap_in %llu\n", stats[i].val);
|
|
|
|
if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_SWAP_OUT)
|
|
|
|
vshPrint(ctl, "swap_out %llu\n", stats[i].val);
|
|
|
|
if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_MAJOR_FAULT)
|
|
|
|
vshPrint(ctl, "major_fault %llu\n", stats[i].val);
|
|
|
|
if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_MINOR_FAULT)
|
|
|
|
vshPrint(ctl, "minor_fault %llu\n", stats[i].val);
|
|
|
|
if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_UNUSED)
|
|
|
|
vshPrint(ctl, "unused %llu\n", stats[i].val);
|
|
|
|
if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_AVAILABLE)
|
|
|
|
vshPrint(ctl, "available %llu\n", stats[i].val);
|
2016-06-01 17:07:06 +00:00
|
|
|
if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_USABLE)
|
|
|
|
vshPrint(ctl, "usable %llu\n", stats[i].val);
|
2012-07-24 08:24:50 +00:00
|
|
|
if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_ACTUAL_BALLOON)
|
|
|
|
vshPrint(ctl, "actual %llu\n", stats[i].val);
|
|
|
|
if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_RSS)
|
|
|
|
vshPrint(ctl, "rss %llu\n", stats[i].val);
|
2016-06-01 17:07:07 +00:00
|
|
|
if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_LAST_UPDATE)
|
|
|
|
vshPrint(ctl, "last_update %llu\n", stats[i].val);
|
2012-07-24 08:24:50 +00:00
|
|
|
}
|
|
|
|
|
2013-07-08 17:19:43 +00:00
|
|
|
ret = true;
|
2014-03-25 06:53:59 +00:00
|
|
|
cleanup:
|
2017-04-11 10:16:52 +00:00
|
|
|
virshDomainFree(dom);
|
2013-07-08 17:19:43 +00:00
|
|
|
return ret;
|
2012-07-24 08:24:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* "domblkinfo" command
|
|
|
|
*/
|
|
|
|
static const vshCmdInfo info_domblkinfo[] = {
|
2013-02-07 15:25:10 +00:00
|
|
|
{.name = "help",
|
|
|
|
.data = N_("domain block device size information")
|
|
|
|
},
|
|
|
|
{.name = "desc",
|
|
|
|
.data = N_("Get block device size info for a domain.")
|
|
|
|
},
|
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const vshCmdOptDef opts_domblkinfo[] = {
|
2016-01-09 13:36:24 +00:00
|
|
|
VIRSH_COMMON_OPT_DOMAIN_FULL,
|
2013-01-14 13:03:21 +00:00
|
|
|
{.name = "device",
|
|
|
|
.type = VSH_OT_DATA,
|
|
|
|
.flags = VSH_OFLAG_REQ,
|
|
|
|
.help = N_("block device")
|
|
|
|
},
|
2017-05-01 22:35:55 +00:00
|
|
|
{.name = "human",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("Human readable output")
|
|
|
|
},
|
2013-01-14 13:03:21 +00:00
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static bool
|
|
|
|
cmdDomblkinfo(vshControl *ctl, const vshCmd *cmd)
|
|
|
|
{
|
|
|
|
virDomainBlockInfo info;
|
|
|
|
virDomainPtr dom;
|
2013-01-14 14:09:41 +00:00
|
|
|
bool ret = false;
|
2017-05-01 22:35:55 +00:00
|
|
|
bool human = false;
|
2012-07-24 08:24:50 +00:00
|
|
|
const char *device = NULL;
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
|
2012-07-24 08:24:50 +00:00
|
|
|
return false;
|
|
|
|
|
2013-01-14 14:09:41 +00:00
|
|
|
if (vshCommandOptStringReq(ctl, cmd, "device", &device) < 0)
|
|
|
|
goto cleanup;
|
2012-07-24 08:24:50 +00:00
|
|
|
|
2013-01-14 14:09:41 +00:00
|
|
|
if (virDomainGetBlockInfo(dom, device, &info, 0) < 0)
|
|
|
|
goto cleanup;
|
2012-07-24 08:24:50 +00:00
|
|
|
|
2017-05-01 22:35:55 +00:00
|
|
|
human = vshCommandOptBool(cmd, "human");
|
|
|
|
|
|
|
|
if (!human) {
|
|
|
|
vshPrint(ctl, "%-15s %llu\n", _("Capacity:"), info.capacity);
|
|
|
|
vshPrint(ctl, "%-15s %llu\n", _("Allocation:"), info.allocation);
|
|
|
|
vshPrint(ctl, "%-15s %llu\n", _("Physical:"), info.physical);
|
|
|
|
} else {
|
|
|
|
double val;
|
|
|
|
const char *unit;
|
|
|
|
|
|
|
|
val = vshPrettyCapacity(info.capacity, &unit);
|
|
|
|
vshPrint(ctl, "%-15s %-.3lf %s\n", _("Capacity:"), val, unit);
|
|
|
|
val = vshPrettyCapacity(info.allocation, &unit);
|
|
|
|
vshPrint(ctl, "%-15s %-.3lf %s\n", _("Allocation:"), val, unit);
|
|
|
|
val = vshPrettyCapacity(info.physical, &unit);
|
|
|
|
vshPrint(ctl, "%-15s %-.3lf %s\n", _("Physical:"), val, unit);
|
|
|
|
}
|
2012-07-24 08:24:50 +00:00
|
|
|
|
2013-01-14 14:09:41 +00:00
|
|
|
ret = true;
|
|
|
|
|
2014-03-25 06:53:59 +00:00
|
|
|
cleanup:
|
2017-04-11 10:16:52 +00:00
|
|
|
virshDomainFree(dom);
|
2012-07-24 08:24:50 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* "domblklist" command
|
|
|
|
*/
|
|
|
|
static const vshCmdInfo info_domblklist[] = {
|
2013-02-07 15:25:10 +00:00
|
|
|
{.name = "help",
|
|
|
|
.data = N_("list all domain blocks")
|
|
|
|
},
|
|
|
|
{.name = "desc",
|
|
|
|
.data = N_("Get the summary of block devices for a domain.")
|
|
|
|
},
|
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const vshCmdOptDef opts_domblklist[] = {
|
2016-01-09 13:36:24 +00:00
|
|
|
VIRSH_COMMON_OPT_DOMAIN_FULL,
|
2013-01-14 13:03:21 +00:00
|
|
|
{.name = "inactive",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("get inactive rather than running configuration")
|
|
|
|
},
|
|
|
|
{.name = "details",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("additionally display the type and device value")
|
|
|
|
},
|
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static bool
|
|
|
|
cmdDomblklist(vshControl *ctl, const vshCmd *cmd)
|
|
|
|
{
|
|
|
|
bool ret = false;
|
|
|
|
unsigned int flags = 0;
|
|
|
|
xmlDocPtr xmldoc = NULL;
|
|
|
|
xmlXPathContextPtr ctxt = NULL;
|
|
|
|
int ndisks;
|
|
|
|
xmlNodePtr *disks = NULL;
|
Convert 'int i' to 'size_t i' in tools/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2012-07-24 08:24:50 +00:00
|
|
|
bool details = false;
|
2015-09-02 13:44:41 +00:00
|
|
|
char *type = NULL;
|
|
|
|
char *device = NULL;
|
|
|
|
char *target = NULL;
|
|
|
|
char *source = NULL;
|
2012-07-24 08:24:50 +00:00
|
|
|
|
|
|
|
if (vshCommandOptBool(cmd, "inactive"))
|
|
|
|
flags |= VIR_DOMAIN_XML_INACTIVE;
|
|
|
|
|
|
|
|
details = vshCommandOptBool(cmd, "details");
|
|
|
|
|
2017-04-11 15:33:53 +00:00
|
|
|
if (virshDomainGetXML(ctl, cmd, flags, &xmldoc, &ctxt) < 0)
|
2012-07-24 08:24:50 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ndisks = virXPathNodeSet("./devices/disk", ctxt, &disks);
|
|
|
|
if (ndisks < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (details)
|
2014-02-26 10:54:25 +00:00
|
|
|
vshPrintExtra(ctl, "%-10s %-10s %-10s %s\n", _("Type"),
|
|
|
|
_("Device"), _("Target"), _("Source"));
|
2012-07-24 08:24:50 +00:00
|
|
|
else
|
2014-02-26 10:54:25 +00:00
|
|
|
vshPrintExtra(ctl, "%-10s %s\n", _("Target"), _("Source"));
|
2012-07-24 08:24:50 +00:00
|
|
|
|
2014-02-26 10:54:25 +00:00
|
|
|
vshPrintExtra(ctl, "------------------------------------------------\n");
|
2012-07-24 08:24:50 +00:00
|
|
|
|
|
|
|
for (i = 0; i < ndisks; i++) {
|
|
|
|
ctxt->node = disks[i];
|
|
|
|
|
|
|
|
if (details) {
|
|
|
|
type = virXPathString("string(./@type)", ctxt);
|
|
|
|
device = virXPathString("string(./@device)", ctxt);
|
2014-01-13 14:42:35 +00:00
|
|
|
if (!type || !device) {
|
|
|
|
vshPrint(ctl, "unable to query block list details");
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2012-07-24 08:24:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
target = virXPathString("string(./target/@dev)", ctxt);
|
|
|
|
if (!target) {
|
|
|
|
vshError(ctl, "unable to query block list");
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
source = virXPathString("string(./source/@file"
|
|
|
|
"|./source/@dev"
|
|
|
|
"|./source/@dir"
|
2015-02-26 16:22:17 +00:00
|
|
|
"|./source/@name"
|
|
|
|
"|./source/@volume)", ctxt);
|
2012-07-24 08:24:50 +00:00
|
|
|
if (details) {
|
|
|
|
vshPrint(ctl, "%-10s %-10s %-10s %s\n", type, device,
|
|
|
|
target, source ? source : "-");
|
|
|
|
} else {
|
|
|
|
vshPrint(ctl, "%-10s %s\n", target, source ? source : "-");
|
|
|
|
}
|
|
|
|
|
|
|
|
VIR_FREE(source);
|
2015-09-02 13:44:41 +00:00
|
|
|
VIR_FREE(target);
|
|
|
|
VIR_FREE(device);
|
|
|
|
VIR_FREE(type);
|
2012-07-24 08:24:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = true;
|
|
|
|
|
2014-03-25 06:53:59 +00:00
|
|
|
cleanup:
|
2015-09-02 13:44:41 +00:00
|
|
|
VIR_FREE(source);
|
|
|
|
VIR_FREE(target);
|
|
|
|
VIR_FREE(device);
|
|
|
|
VIR_FREE(type);
|
2012-07-24 08:24:50 +00:00
|
|
|
VIR_FREE(disks);
|
|
|
|
xmlXPathFreeContext(ctxt);
|
2015-09-02 13:44:41 +00:00
|
|
|
xmlFreeDoc(xmldoc);
|
2012-07-24 08:24:50 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* "domiflist" command
|
|
|
|
*/
|
|
|
|
static const vshCmdInfo info_domiflist[] = {
|
|
|
|
{"help", N_("list all domain virtual interfaces")},
|
|
|
|
{"desc", N_("Get the summary of virtual interfaces for a domain.")},
|
|
|
|
{NULL, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
static const vshCmdOptDef opts_domiflist[] = {
|
2016-01-09 13:36:24 +00:00
|
|
|
VIRSH_COMMON_OPT_DOMAIN_FULL,
|
2013-01-14 13:03:21 +00:00
|
|
|
{.name = "inactive",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("get inactive rather than running configuration")
|
|
|
|
},
|
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static bool
|
|
|
|
cmdDomiflist(vshControl *ctl, const vshCmd *cmd)
|
|
|
|
{
|
|
|
|
bool ret = false;
|
|
|
|
unsigned int flags = 0;
|
|
|
|
xmlDocPtr xmldoc = NULL;
|
|
|
|
xmlXPathContextPtr ctxt = NULL;
|
|
|
|
int ninterfaces;
|
|
|
|
xmlNodePtr *interfaces = NULL;
|
Convert 'int i' to 'size_t i' in tools/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2012-07-24 08:24:50 +00:00
|
|
|
|
|
|
|
if (vshCommandOptBool(cmd, "inactive"))
|
|
|
|
flags |= VIR_DOMAIN_XML_INACTIVE;
|
|
|
|
|
2017-04-11 15:33:53 +00:00
|
|
|
if (virshDomainGetXML(ctl, cmd, flags, &xmldoc, &ctxt) < 0)
|
2012-07-24 08:24:50 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ninterfaces = virXPathNodeSet("./devices/interface", ctxt, &interfaces);
|
|
|
|
if (ninterfaces < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2014-02-26 10:54:25 +00:00
|
|
|
vshPrintExtra(ctl, "%-10s %-10s %-10s %-11s %s\n", _("Interface"),
|
|
|
|
_("Type"), _("Source"), _("Model"), _("MAC"));
|
|
|
|
vshPrintExtra(ctl, "-------------------------------------------------------\n");
|
2012-07-24 08:24:50 +00:00
|
|
|
|
|
|
|
for (i = 0; i < ninterfaces; i++) {
|
|
|
|
char *type = NULL;
|
|
|
|
char *source = NULL;
|
|
|
|
char *target = NULL;
|
|
|
|
char *model = NULL;
|
|
|
|
char *mac = NULL;
|
|
|
|
|
|
|
|
ctxt->node = interfaces[i];
|
|
|
|
type = virXPathString("string(./@type)", ctxt);
|
|
|
|
|
|
|
|
source = virXPathString("string(./source/@bridge"
|
|
|
|
"|./source/@dev"
|
|
|
|
"|./source/@network"
|
|
|
|
"|./source/@name)", ctxt);
|
|
|
|
|
|
|
|
target = virXPathString("string(./target/@dev)", ctxt);
|
|
|
|
model = virXPathString("string(./model/@type)", ctxt);
|
|
|
|
mac = virXPathString("string(./mac/@address)", ctxt);
|
|
|
|
|
|
|
|
vshPrint(ctl, "%-10s %-10s %-10s %-11s %-10s\n",
|
|
|
|
target ? target : "-",
|
|
|
|
type,
|
|
|
|
source ? source : "-",
|
|
|
|
model ? model : "-",
|
|
|
|
mac ? mac : "-");
|
|
|
|
|
|
|
|
VIR_FREE(type);
|
|
|
|
VIR_FREE(source);
|
|
|
|
VIR_FREE(target);
|
|
|
|
VIR_FREE(model);
|
|
|
|
VIR_FREE(mac);
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = true;
|
|
|
|
|
2014-03-25 06:53:59 +00:00
|
|
|
cleanup:
|
2012-07-24 08:24:50 +00:00
|
|
|
VIR_FREE(interfaces);
|
|
|
|
xmlFreeDoc(xmldoc);
|
|
|
|
xmlXPathFreeContext(ctxt);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* "domif-getlink" command
|
|
|
|
*/
|
|
|
|
static const vshCmdInfo info_domif_getlink[] = {
|
2013-02-07 15:25:10 +00:00
|
|
|
{.name = "help",
|
|
|
|
.data = N_("get link state of a virtual interface")
|
|
|
|
},
|
|
|
|
{.name = "desc",
|
|
|
|
.data = N_("Get link state of a domain's virtual interface.")
|
|
|
|
},
|
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const vshCmdOptDef opts_domif_getlink[] = {
|
2016-01-09 13:36:24 +00:00
|
|
|
VIRSH_COMMON_OPT_DOMAIN_FULL,
|
2013-01-14 13:03:21 +00:00
|
|
|
{.name = "interface",
|
|
|
|
.type = VSH_OT_DATA,
|
|
|
|
.flags = VSH_OFLAG_REQ,
|
|
|
|
.help = N_("interface device (MAC Address)")
|
|
|
|
},
|
|
|
|
{.name = "persistent",
|
|
|
|
.type = VSH_OT_ALIAS,
|
|
|
|
.help = "config"
|
|
|
|
},
|
2016-01-09 13:36:26 +00:00
|
|
|
VIRSH_COMMON_OPT_CONFIG(N_("Get persistent interface state")),
|
2013-01-14 13:03:21 +00:00
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static bool
|
|
|
|
cmdDomIfGetLink(vshControl *ctl, const vshCmd *cmd)
|
|
|
|
{
|
|
|
|
const char *iface = NULL;
|
|
|
|
char *state = NULL;
|
2013-03-26 09:15:32 +00:00
|
|
|
char *xpath = NULL;
|
2012-07-24 08:24:50 +00:00
|
|
|
virMacAddr macaddr;
|
2013-03-26 09:15:32 +00:00
|
|
|
char macstr[VIR_MAC_STRING_BUFLEN] = "";
|
2012-07-24 08:24:50 +00:00
|
|
|
xmlDocPtr xml = NULL;
|
|
|
|
xmlXPathContextPtr ctxt = NULL;
|
2013-03-26 09:15:32 +00:00
|
|
|
xmlNodePtr *interfaces = NULL;
|
|
|
|
int ninterfaces;
|
|
|
|
unsigned int flags = 0;
|
|
|
|
bool ret = false;
|
2012-07-24 08:24:50 +00:00
|
|
|
|
2013-03-26 09:15:32 +00:00
|
|
|
if (vshCommandOptStringReq(ctl, cmd, "interface", &iface) < 0)
|
2012-07-24 08:24:50 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
if (vshCommandOptBool(cmd, "config"))
|
|
|
|
flags = VIR_DOMAIN_XML_INACTIVE;
|
|
|
|
|
2017-04-11 15:33:53 +00:00
|
|
|
if (virshDomainGetXML(ctl, cmd, flags, &xml, &ctxt) < 0)
|
2012-07-24 08:24:50 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2013-03-26 09:15:32 +00:00
|
|
|
/* normalize the mac addr */
|
|
|
|
if (virMacAddrParse(iface, &macaddr) == 0)
|
|
|
|
virMacAddrFormat(&macaddr, macstr);
|
|
|
|
|
|
|
|
if (virAsprintf(&xpath, "/domain/devices/interface[(mac/@address = '%s') or "
|
|
|
|
" (target/@dev = '%s')]",
|
2013-07-04 10:20:45 +00:00
|
|
|
macstr, iface) < 0)
|
2012-07-24 08:24:50 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2013-03-26 09:15:32 +00:00
|
|
|
if ((ninterfaces = virXPathNodeSet(xpath, ctxt, &interfaces)) < 0) {
|
|
|
|
vshError(ctl, _("Failed to extract interface information"));
|
|
|
|
goto cleanup;
|
2012-07-24 08:24:50 +00:00
|
|
|
}
|
|
|
|
|
2013-03-26 09:15:32 +00:00
|
|
|
if (ninterfaces != 1) {
|
|
|
|
if (macstr[0])
|
|
|
|
vshError(ctl, _("Interface (mac: %s) not found."), macstr);
|
|
|
|
else
|
|
|
|
vshError(ctl, _("Interface (dev: %s) not found."), iface);
|
2012-07-24 08:24:50 +00:00
|
|
|
|
2013-03-26 09:15:32 +00:00
|
|
|
goto cleanup;
|
2012-07-24 08:24:50 +00:00
|
|
|
}
|
|
|
|
|
2013-03-26 09:15:32 +00:00
|
|
|
ctxt->node = interfaces[0];
|
2012-07-24 08:24:50 +00:00
|
|
|
|
2013-03-26 09:15:32 +00:00
|
|
|
if ((state = virXPathString("string(./link/@state)", ctxt)))
|
|
|
|
vshPrint(ctl, "%s %s", iface, state);
|
|
|
|
else
|
2015-02-24 16:25:55 +00:00
|
|
|
vshPrint(ctl, "%s up", iface);
|
2012-07-24 08:24:50 +00:00
|
|
|
|
|
|
|
ret = true;
|
2013-03-26 09:15:32 +00:00
|
|
|
|
2014-03-25 06:53:59 +00:00
|
|
|
cleanup:
|
2013-03-26 09:15:32 +00:00
|
|
|
VIR_FREE(state);
|
|
|
|
VIR_FREE(interfaces);
|
|
|
|
VIR_FREE(xpath);
|
2012-07-24 08:24:50 +00:00
|
|
|
xmlXPathFreeContext(ctxt);
|
|
|
|
xmlFreeDoc(xml);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* "domcontrol" command
|
|
|
|
*/
|
|
|
|
static const vshCmdInfo info_domcontrol[] = {
|
2013-02-07 15:25:10 +00:00
|
|
|
{.name = "help",
|
|
|
|
.data = N_("domain control interface state")
|
|
|
|
},
|
|
|
|
{.name = "desc",
|
|
|
|
.data = N_("Returns state of a control interface to the domain.")
|
|
|
|
},
|
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const vshCmdOptDef opts_domcontrol[] = {
|
2016-01-09 13:36:24 +00:00
|
|
|
VIRSH_COMMON_OPT_DOMAIN_FULL,
|
2013-01-14 13:03:21 +00:00
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static bool
|
|
|
|
cmdDomControl(vshControl *ctl, const vshCmd *cmd)
|
|
|
|
{
|
|
|
|
virDomainPtr dom;
|
|
|
|
bool ret = true;
|
|
|
|
virDomainControlInfo info;
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
|
2012-07-24 08:24:50 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
if (virDomainGetControlInfo(dom, &info, 0) < 0) {
|
|
|
|
ret = false;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (info.state != VIR_DOMAIN_CONTROL_OK &&
|
|
|
|
info.state != VIR_DOMAIN_CONTROL_ERROR) {
|
|
|
|
vshPrint(ctl, "%s (%0.3fs)\n",
|
2015-06-15 16:53:58 +00:00
|
|
|
virshDomainControlStateToString(info.state),
|
2012-07-24 08:24:50 +00:00
|
|
|
info.stateTime / 1000.0);
|
2015-02-19 10:53:42 +00:00
|
|
|
} else if (info.state == VIR_DOMAIN_CONTROL_ERROR && info.details > 0) {
|
|
|
|
vshPrint(ctl, "%s: %s\n",
|
2015-06-15 16:53:58 +00:00
|
|
|
virshDomainControlStateToString(info.state),
|
|
|
|
virshDomainControlErrorReasonToString(info.details));
|
2012-07-24 08:24:50 +00:00
|
|
|
} else {
|
|
|
|
vshPrint(ctl, "%s\n",
|
2015-06-15 16:53:58 +00:00
|
|
|
virshDomainControlStateToString(info.state));
|
2012-07-24 08:24:50 +00:00
|
|
|
}
|
|
|
|
|
2014-03-25 06:53:59 +00:00
|
|
|
cleanup:
|
2017-04-11 10:16:52 +00:00
|
|
|
virshDomainFree(dom);
|
2012-07-24 08:24:50 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* "domblkstat" command
|
|
|
|
*/
|
|
|
|
static const vshCmdInfo info_domblkstat[] = {
|
2013-02-07 15:25:10 +00:00
|
|
|
{.name = "help",
|
|
|
|
.data = N_("get device block stats for a domain")
|
|
|
|
},
|
|
|
|
{.name = "desc",
|
|
|
|
.data = N_("Get device block stats for a running domain. See man page or "
|
|
|
|
"use --human for explanation of fields")
|
|
|
|
},
|
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const vshCmdOptDef opts_domblkstat[] = {
|
2016-01-09 13:36:24 +00:00
|
|
|
VIRSH_COMMON_OPT_DOMAIN_FULL,
|
2013-01-14 13:03:21 +00:00
|
|
|
{.name = "device",
|
2014-12-11 02:46:15 +00:00
|
|
|
.type = VSH_OT_STRING,
|
2014-02-14 17:49:04 +00:00
|
|
|
.flags = VSH_OFLAG_EMPTY_OK,
|
2013-01-14 13:03:21 +00:00
|
|
|
.help = N_("block device")
|
|
|
|
},
|
|
|
|
{.name = "human",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("print a more human readable output")
|
|
|
|
},
|
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct _domblkstat_sequence {
|
|
|
|
const char *field; /* field name */
|
|
|
|
const char *legacy; /* legacy name from previous releases */
|
|
|
|
const char *human; /* human-friendly explanation */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* sequence of values for output to honor legacy format from previous
|
|
|
|
* versions */
|
|
|
|
static const struct _domblkstat_sequence domblkstat_output[] = {
|
|
|
|
{ VIR_DOMAIN_BLOCK_STATS_READ_REQ, "rd_req",
|
|
|
|
N_("number of read operations:") }, /* 0 */
|
|
|
|
{ VIR_DOMAIN_BLOCK_STATS_READ_BYTES, "rd_bytes",
|
|
|
|
N_("number of bytes read:") }, /* 1 */
|
|
|
|
{ VIR_DOMAIN_BLOCK_STATS_WRITE_REQ, "wr_req",
|
|
|
|
N_("number of write operations:") }, /* 2 */
|
|
|
|
{ VIR_DOMAIN_BLOCK_STATS_WRITE_BYTES, "wr_bytes",
|
|
|
|
N_("number of bytes written:") }, /* 3 */
|
|
|
|
{ VIR_DOMAIN_BLOCK_STATS_ERRS, "errs",
|
|
|
|
N_("error count:") }, /* 4 */
|
|
|
|
{ VIR_DOMAIN_BLOCK_STATS_FLUSH_REQ, NULL,
|
|
|
|
N_("number of flush operations:") }, /* 5 */
|
|
|
|
{ VIR_DOMAIN_BLOCK_STATS_READ_TOTAL_TIMES, NULL,
|
|
|
|
N_("total duration of reads (ns):") }, /* 6 */
|
|
|
|
{ VIR_DOMAIN_BLOCK_STATS_WRITE_TOTAL_TIMES, NULL,
|
|
|
|
N_("total duration of writes (ns):") }, /* 7 */
|
|
|
|
{ VIR_DOMAIN_BLOCK_STATS_FLUSH_TOTAL_TIMES, NULL,
|
|
|
|
N_("total duration of flushes (ns):") }, /* 8 */
|
|
|
|
{ NULL, NULL, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
#define DOMBLKSTAT_LEGACY_PRINT(ID, VALUE) \
|
|
|
|
if (VALUE >= 0) \
|
|
|
|
vshPrint(ctl, "%s %-*s %lld\n", device, \
|
|
|
|
human ? 31 : 0, \
|
|
|
|
human ? _(domblkstat_output[ID].human) \
|
|
|
|
: domblkstat_output[ID].legacy, \
|
|
|
|
VALUE);
|
|
|
|
|
|
|
|
static bool
|
|
|
|
cmdDomblkstat(vshControl *ctl, const vshCmd *cmd)
|
|
|
|
{
|
|
|
|
virDomainPtr dom;
|
|
|
|
const char *name = NULL, *device = NULL;
|
2014-09-16 13:19:46 +00:00
|
|
|
virDomainBlockStatsStruct stats;
|
2012-07-24 08:24:50 +00:00
|
|
|
virTypedParameterPtr params = NULL;
|
|
|
|
virTypedParameterPtr par = NULL;
|
|
|
|
char *value = NULL;
|
|
|
|
const char *field = NULL;
|
|
|
|
int rc, nparams = 0;
|
Convert 'int i' to 'size_t i' in tools/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2012-07-24 08:24:50 +00:00
|
|
|
bool ret = false;
|
|
|
|
bool human = vshCommandOptBool(cmd, "human"); /* human readable output */
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
if (!(dom = virshCommandOptDomain(ctl, cmd, &name)))
|
2012-07-24 08:24:50 +00:00
|
|
|
return false;
|
|
|
|
|
2014-02-14 17:49:04 +00:00
|
|
|
/* device argument is optional now. if it's missing, supply empty
|
|
|
|
string to denote 'all devices'. A NULL device arg would violate
|
|
|
|
API contract.
|
|
|
|
*/
|
2013-01-14 14:09:41 +00:00
|
|
|
if (vshCommandOptStringReq(ctl, cmd, "device", &device) < 0)
|
2012-07-24 08:24:50 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2014-02-14 17:49:04 +00:00
|
|
|
if (!device)
|
|
|
|
device = "";
|
|
|
|
|
2012-07-24 08:24:50 +00:00
|
|
|
rc = virDomainBlockStatsFlags(dom, device, NULL, &nparams, 0);
|
|
|
|
|
|
|
|
/* It might fail when virDomainBlockStatsFlags is not
|
|
|
|
* supported on older libvirt, fallback to use virDomainBlockStats
|
|
|
|
* then.
|
|
|
|
*/
|
|
|
|
if (rc < 0) {
|
|
|
|
/* try older API if newer is not supported */
|
|
|
|
if (last_error->code != VIR_ERR_NO_SUPPORT)
|
|
|
|
goto cleanup;
|
|
|
|
|
2012-07-25 11:41:49 +00:00
|
|
|
vshResetLibvirtError();
|
2012-07-24 08:24:50 +00:00
|
|
|
|
|
|
|
if (virDomainBlockStats(dom, device, &stats,
|
|
|
|
sizeof(stats)) == -1) {
|
|
|
|
vshError(ctl, _("Failed to get block stats %s %s"),
|
|
|
|
name, device);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* human friendly output */
|
|
|
|
if (human) {
|
|
|
|
vshPrint(ctl, N_("Device: %s\n"), device);
|
|
|
|
device = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
DOMBLKSTAT_LEGACY_PRINT(0, stats.rd_req);
|
|
|
|
DOMBLKSTAT_LEGACY_PRINT(1, stats.rd_bytes);
|
|
|
|
DOMBLKSTAT_LEGACY_PRINT(2, stats.wr_req);
|
|
|
|
DOMBLKSTAT_LEGACY_PRINT(3, stats.wr_bytes);
|
|
|
|
DOMBLKSTAT_LEGACY_PRINT(4, stats.errs);
|
|
|
|
} else {
|
|
|
|
params = vshCalloc(ctl, nparams, sizeof(*params));
|
|
|
|
|
|
|
|
if (virDomainBlockStatsFlags(dom, device, params, &nparams, 0) < 0) {
|
2014-02-28 09:06:27 +00:00
|
|
|
vshError(ctl, _("Failed to get block stats for domain '%s' device '%s'"), name, device);
|
2012-07-24 08:24:50 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set for prettier output */
|
|
|
|
if (human) {
|
|
|
|
vshPrint(ctl, N_("Device: %s\n"), device);
|
|
|
|
device = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
/* at first print all known values in desired order */
|
|
|
|
for (i = 0; domblkstat_output[i].field != NULL; i++) {
|
2013-01-15 23:08:05 +00:00
|
|
|
if (!(par = virTypedParamsGet(params, nparams,
|
|
|
|
domblkstat_output[i].field)))
|
2012-07-24 08:24:50 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
value = vshGetTypedParamValue(ctl, par);
|
|
|
|
|
|
|
|
/* to print other not supported fields, mark the already printed */
|
|
|
|
par->field[0] = '\0'; /* set the name to empty string */
|
|
|
|
|
|
|
|
/* translate into human readable or legacy spelling */
|
|
|
|
field = NULL;
|
|
|
|
if (human)
|
|
|
|
field = _(domblkstat_output[i].human);
|
|
|
|
else
|
|
|
|
field = domblkstat_output[i].legacy;
|
|
|
|
|
|
|
|
/* use the provided spelling if no translation is available */
|
|
|
|
if (!field)
|
|
|
|
field = domblkstat_output[i].field;
|
|
|
|
|
|
|
|
vshPrint(ctl, "%s %-*s %s\n", device,
|
|
|
|
human ? 31 : 0, field, value);
|
|
|
|
|
|
|
|
VIR_FREE(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* go through the fields again, for remaining fields */
|
|
|
|
for (i = 0; i < nparams; i++) {
|
|
|
|
if (!*params[i].field)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
value = vshGetTypedParamValue(ctl, params+i);
|
|
|
|
vshPrint(ctl, "%s %s %s\n", device, params[i].field, value);
|
|
|
|
VIR_FREE(value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = true;
|
|
|
|
|
2014-03-25 06:53:59 +00:00
|
|
|
cleanup:
|
2012-07-24 08:24:50 +00:00
|
|
|
VIR_FREE(params);
|
2017-04-11 10:16:52 +00:00
|
|
|
virshDomainFree(dom);
|
2012-07-24 08:24:50 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#undef DOMBLKSTAT_LEGACY_PRINT
|
|
|
|
|
|
|
|
/*
|
|
|
|
* "domifstat" command
|
|
|
|
*/
|
|
|
|
static const vshCmdInfo info_domifstat[] = {
|
2013-02-07 15:25:10 +00:00
|
|
|
{.name = "help",
|
|
|
|
.data = N_("get network interface stats for a domain")
|
|
|
|
},
|
|
|
|
{.name = "desc",
|
|
|
|
.data = N_("Get network interface stats for a running domain.")
|
|
|
|
},
|
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const vshCmdOptDef opts_domifstat[] = {
|
2016-01-09 13:36:24 +00:00
|
|
|
VIRSH_COMMON_OPT_DOMAIN_FULL,
|
2013-01-14 13:03:21 +00:00
|
|
|
{.name = "interface",
|
|
|
|
.type = VSH_OT_DATA,
|
|
|
|
.flags = VSH_OFLAG_REQ,
|
|
|
|
.help = N_("interface device")
|
|
|
|
},
|
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static bool
|
|
|
|
cmdDomIfstat(vshControl *ctl, const vshCmd *cmd)
|
|
|
|
{
|
|
|
|
virDomainPtr dom;
|
|
|
|
const char *name = NULL, *device = NULL;
|
2014-09-16 13:19:45 +00:00
|
|
|
virDomainInterfaceStatsStruct stats;
|
2013-01-14 14:09:41 +00:00
|
|
|
bool ret = false;
|
2012-07-24 08:24:50 +00:00
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
if (!(dom = virshCommandOptDomain(ctl, cmd, &name)))
|
2012-07-24 08:24:50 +00:00
|
|
|
return false;
|
|
|
|
|
2013-01-14 14:09:41 +00:00
|
|
|
if (vshCommandOptStringReq(ctl, cmd, "interface", &device) < 0)
|
|
|
|
goto cleanup;
|
2012-07-24 08:24:50 +00:00
|
|
|
|
|
|
|
if (virDomainInterfaceStats(dom, device, &stats, sizeof(stats)) == -1) {
|
|
|
|
vshError(ctl, _("Failed to get interface stats %s %s"), name, device);
|
2013-01-14 14:09:41 +00:00
|
|
|
goto cleanup;
|
2012-07-24 08:24:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (stats.rx_bytes >= 0)
|
|
|
|
vshPrint(ctl, "%s rx_bytes %lld\n", device, stats.rx_bytes);
|
|
|
|
|
|
|
|
if (stats.rx_packets >= 0)
|
|
|
|
vshPrint(ctl, "%s rx_packets %lld\n", device, stats.rx_packets);
|
|
|
|
|
|
|
|
if (stats.rx_errs >= 0)
|
|
|
|
vshPrint(ctl, "%s rx_errs %lld\n", device, stats.rx_errs);
|
|
|
|
|
|
|
|
if (stats.rx_drop >= 0)
|
|
|
|
vshPrint(ctl, "%s rx_drop %lld\n", device, stats.rx_drop);
|
|
|
|
|
|
|
|
if (stats.tx_bytes >= 0)
|
|
|
|
vshPrint(ctl, "%s tx_bytes %lld\n", device, stats.tx_bytes);
|
|
|
|
|
|
|
|
if (stats.tx_packets >= 0)
|
|
|
|
vshPrint(ctl, "%s tx_packets %lld\n", device, stats.tx_packets);
|
|
|
|
|
|
|
|
if (stats.tx_errs >= 0)
|
|
|
|
vshPrint(ctl, "%s tx_errs %lld\n", device, stats.tx_errs);
|
|
|
|
|
|
|
|
if (stats.tx_drop >= 0)
|
|
|
|
vshPrint(ctl, "%s tx_drop %lld\n", device, stats.tx_drop);
|
|
|
|
|
2013-01-14 14:09:41 +00:00
|
|
|
ret = true;
|
|
|
|
|
2014-03-25 06:53:59 +00:00
|
|
|
cleanup:
|
2017-04-11 10:16:52 +00:00
|
|
|
virshDomainFree(dom);
|
2013-01-14 14:09:41 +00:00
|
|
|
return ret;
|
2012-07-24 08:24:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* "domblkerror" command
|
|
|
|
*/
|
|
|
|
static const vshCmdInfo info_domblkerror[] = {
|
2013-02-07 15:25:10 +00:00
|
|
|
{.name = "help",
|
|
|
|
.data = N_("Show errors on block devices")
|
|
|
|
},
|
|
|
|
{.name = "desc",
|
|
|
|
.data = N_("Show block device errors")
|
|
|
|
},
|
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const vshCmdOptDef opts_domblkerror[] = {
|
2016-01-09 13:36:24 +00:00
|
|
|
VIRSH_COMMON_OPT_DOMAIN_FULL,
|
2013-01-14 13:03:21 +00:00
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static bool
|
|
|
|
cmdDomBlkError(vshControl *ctl, const vshCmd *cmd)
|
|
|
|
{
|
|
|
|
virDomainPtr dom;
|
|
|
|
virDomainDiskErrorPtr disks = NULL;
|
|
|
|
unsigned int ndisks;
|
Convert 'int i' to 'size_t i' in tools/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2012-07-24 08:24:50 +00:00
|
|
|
int count;
|
|
|
|
bool ret = false;
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
|
2012-07-24 08:24:50 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
if ((count = virDomainGetDiskErrors(dom, NULL, 0, 0)) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
ndisks = count;
|
|
|
|
|
|
|
|
if (ndisks) {
|
|
|
|
if (VIR_ALLOC_N(disks, ndisks) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if ((count = virDomainGetDiskErrors(dom, disks, ndisks, 0)) == -1)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (count == 0) {
|
|
|
|
vshPrint(ctl, _("No errors found\n"));
|
|
|
|
} else {
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
vshPrint(ctl, "%s: %s\n",
|
|
|
|
disks[i].disk,
|
2015-06-15 16:53:58 +00:00
|
|
|
virshDomainIOErrorToString(disks[i].error));
|
2012-07-24 08:24:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = true;
|
|
|
|
|
2014-03-25 06:53:59 +00:00
|
|
|
cleanup:
|
2012-07-24 08:24:50 +00:00
|
|
|
VIR_FREE(disks);
|
2017-04-11 10:16:52 +00:00
|
|
|
virshDomainFree(dom);
|
2012-07-24 08:24:50 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* "dominfo" command
|
|
|
|
*/
|
|
|
|
static const vshCmdInfo info_dominfo[] = {
|
2013-02-07 15:25:10 +00:00
|
|
|
{.name = "help",
|
|
|
|
.data = N_("domain information")
|
|
|
|
},
|
|
|
|
{.name = "desc",
|
|
|
|
.data = N_("Returns basic information about the domain.")
|
|
|
|
},
|
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const vshCmdOptDef opts_dominfo[] = {
|
2016-01-09 13:36:24 +00:00
|
|
|
VIRSH_COMMON_OPT_DOMAIN_FULL,
|
2013-01-14 13:03:21 +00:00
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static bool
|
|
|
|
cmdDominfo(vshControl *ctl, const vshCmd *cmd)
|
|
|
|
{
|
|
|
|
virDomainInfo info;
|
|
|
|
virDomainPtr dom;
|
|
|
|
virSecurityModel secmodel;
|
|
|
|
virSecurityLabelPtr seclabel;
|
|
|
|
int persistent = 0;
|
|
|
|
bool ret = true;
|
|
|
|
int autostart;
|
|
|
|
unsigned int id;
|
|
|
|
char *str, uuid[VIR_UUID_STRING_BUFLEN];
|
|
|
|
int has_managed_save = 0;
|
2015-06-15 16:53:58 +00:00
|
|
|
virshControlPtr priv = ctl->privData;
|
2012-07-24 08:24:50 +00:00
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
|
2012-07-24 08:24:50 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
id = virDomainGetID(dom);
|
|
|
|
if (id == ((unsigned int)-1))
|
|
|
|
vshPrint(ctl, "%-15s %s\n", _("Id:"), "-");
|
|
|
|
else
|
|
|
|
vshPrint(ctl, "%-15s %d\n", _("Id:"), id);
|
|
|
|
vshPrint(ctl, "%-15s %s\n", _("Name:"), virDomainGetName(dom));
|
|
|
|
|
2014-03-17 09:38:38 +00:00
|
|
|
if (virDomainGetUUIDString(dom, &uuid[0]) == 0)
|
2012-07-24 08:24:50 +00:00
|
|
|
vshPrint(ctl, "%-15s %s\n", _("UUID:"), uuid);
|
|
|
|
|
|
|
|
if ((str = virDomainGetOSType(dom))) {
|
|
|
|
vshPrint(ctl, "%-15s %s\n", _("OS Type:"), str);
|
|
|
|
VIR_FREE(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virDomainGetInfo(dom, &info) == 0) {
|
|
|
|
vshPrint(ctl, "%-15s %s\n", _("State:"),
|
2015-06-15 16:53:58 +00:00
|
|
|
virshDomainStateToString(info.state));
|
2012-07-24 08:24:50 +00:00
|
|
|
|
|
|
|
vshPrint(ctl, "%-15s %d\n", _("CPU(s):"), info.nrVirtCpu);
|
|
|
|
|
|
|
|
if (info.cpuTime != 0) {
|
|
|
|
double cpuUsed = info.cpuTime;
|
|
|
|
|
|
|
|
cpuUsed /= 1000000000.0;
|
|
|
|
|
|
|
|
vshPrint(ctl, "%-15s %.1lfs\n", _("CPU time:"), cpuUsed);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (info.maxMem != UINT_MAX)
|
|
|
|
vshPrint(ctl, "%-15s %lu KiB\n", _("Max memory:"),
|
|
|
|
info.maxMem);
|
|
|
|
else
|
|
|
|
vshPrint(ctl, "%-15s %s\n", _("Max memory:"),
|
|
|
|
_("no limit"));
|
|
|
|
|
|
|
|
vshPrint(ctl, "%-15s %lu KiB\n", _("Used memory:"),
|
|
|
|
info.memory);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
ret = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check and display whether the domain is persistent or not */
|
|
|
|
persistent = virDomainIsPersistent(dom);
|
|
|
|
vshDebug(ctl, VSH_ERR_DEBUG, "Domain persistent flag value: %d\n",
|
|
|
|
persistent);
|
|
|
|
if (persistent < 0)
|
|
|
|
vshPrint(ctl, "%-15s %s\n", _("Persistent:"), _("unknown"));
|
|
|
|
else
|
|
|
|
vshPrint(ctl, "%-15s %s\n", _("Persistent:"), persistent ? _("yes") : _("no"));
|
|
|
|
|
|
|
|
/* Check and display whether the domain autostarts or not */
|
|
|
|
if (!virDomainGetAutostart(dom, &autostart)) {
|
|
|
|
vshPrint(ctl, "%-15s %s\n", _("Autostart:"),
|
2012-10-17 09:23:12 +00:00
|
|
|
autostart ? _("enable") : _("disable"));
|
2012-07-24 08:24:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
has_managed_save = virDomainHasManagedSaveImage(dom, 0);
|
|
|
|
if (has_managed_save < 0)
|
|
|
|
vshPrint(ctl, "%-15s %s\n", _("Managed save:"), _("unknown"));
|
|
|
|
else
|
|
|
|
vshPrint(ctl, "%-15s %s\n", _("Managed save:"),
|
|
|
|
has_managed_save ? _("yes") : _("no"));
|
|
|
|
|
|
|
|
/* Security model and label information */
|
|
|
|
memset(&secmodel, 0, sizeof(secmodel));
|
2015-06-15 16:53:58 +00:00
|
|
|
if (virNodeGetSecurityModel(priv->conn, &secmodel) == -1) {
|
2012-07-24 08:24:50 +00:00
|
|
|
if (last_error->code != VIR_ERR_NO_SUPPORT) {
|
2017-04-11 10:16:52 +00:00
|
|
|
virshDomainFree(dom);
|
2012-07-24 08:24:50 +00:00
|
|
|
return false;
|
|
|
|
} else {
|
2012-07-25 11:41:49 +00:00
|
|
|
vshResetLibvirtError();
|
2012-07-24 08:24:50 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* Only print something if a security model is active */
|
|
|
|
if (secmodel.model[0] != '\0') {
|
|
|
|
vshPrint(ctl, "%-15s %s\n", _("Security model:"), secmodel.model);
|
|
|
|
vshPrint(ctl, "%-15s %s\n", _("Security DOI:"), secmodel.doi);
|
|
|
|
|
|
|
|
/* Security labels are only valid for active domains */
|
|
|
|
if (VIR_ALLOC(seclabel) < 0) {
|
2017-04-11 10:16:52 +00:00
|
|
|
virshDomainFree(dom);
|
2012-07-24 08:24:50 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virDomainGetSecurityLabel(dom, seclabel) == -1) {
|
2017-04-11 10:16:52 +00:00
|
|
|
virshDomainFree(dom);
|
2012-07-24 08:24:50 +00:00
|
|
|
VIR_FREE(seclabel);
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
if (seclabel->label[0] != '\0')
|
|
|
|
vshPrint(ctl, "%-15s %s (%s)\n", _("Security label:"),
|
|
|
|
seclabel->label, seclabel->enforcing ? "enforcing" : "permissive");
|
|
|
|
}
|
|
|
|
|
|
|
|
VIR_FREE(seclabel);
|
|
|
|
}
|
|
|
|
}
|
2017-04-11 10:16:52 +00:00
|
|
|
virshDomainFree(dom);
|
2012-07-24 08:24:50 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* "domstate" command
|
|
|
|
*/
|
|
|
|
static const vshCmdInfo info_domstate[] = {
|
2013-02-07 15:25:10 +00:00
|
|
|
{.name = "help",
|
|
|
|
.data = N_("domain state")
|
|
|
|
},
|
|
|
|
{.name = "desc",
|
|
|
|
.data = N_("Returns state about a domain.")
|
|
|
|
},
|
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const vshCmdOptDef opts_domstate[] = {
|
2016-01-09 13:36:24 +00:00
|
|
|
VIRSH_COMMON_OPT_DOMAIN_FULL,
|
2013-01-14 13:03:21 +00:00
|
|
|
{.name = "reason",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("also print reason for the state")
|
|
|
|
},
|
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static bool
|
|
|
|
cmdDomstate(vshControl *ctl, const vshCmd *cmd)
|
|
|
|
{
|
|
|
|
virDomainPtr dom;
|
|
|
|
bool ret = true;
|
|
|
|
bool showReason = vshCommandOptBool(cmd, "reason");
|
|
|
|
int state, reason;
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
|
2012-07-24 08:24:50 +00:00
|
|
|
return false;
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
if ((state = virshDomainState(ctl, dom, &reason)) < 0) {
|
2012-07-24 08:24:50 +00:00
|
|
|
ret = false;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (showReason) {
|
|
|
|
vshPrint(ctl, "%s (%s)\n",
|
2015-06-15 16:53:58 +00:00
|
|
|
virshDomainStateToString(state),
|
|
|
|
virshDomainStateReasonToString(state, reason));
|
2012-07-24 08:24:50 +00:00
|
|
|
} else {
|
|
|
|
vshPrint(ctl, "%s\n",
|
2015-06-15 16:53:58 +00:00
|
|
|
virshDomainStateToString(state));
|
2012-07-24 08:24:50 +00:00
|
|
|
}
|
|
|
|
|
2014-03-25 06:53:59 +00:00
|
|
|
cleanup:
|
2017-04-11 10:16:52 +00:00
|
|
|
virshDomainFree(dom);
|
2012-07-24 08:24:50 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2014-04-02 16:50:12 +00:00
|
|
|
/*
|
|
|
|
* "domtime" command
|
|
|
|
*/
|
|
|
|
static const vshCmdInfo info_domtime[] = {
|
|
|
|
{.name = "help",
|
|
|
|
.data = N_("domain time")
|
|
|
|
},
|
|
|
|
{.name = "desc",
|
|
|
|
.data = N_("Gets or sets the domain's system time")
|
|
|
|
},
|
|
|
|
{.name = NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
static const vshCmdOptDef opts_domtime[] = {
|
2016-01-09 13:36:24 +00:00
|
|
|
VIRSH_COMMON_OPT_DOMAIN_FULL,
|
2014-04-02 16:50:12 +00:00
|
|
|
{.name = "now",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("set to the time of the host running virsh")
|
|
|
|
},
|
|
|
|
{.name = "pretty",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("print domain's time in human readable form")
|
|
|
|
},
|
|
|
|
{.name = "sync",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("instead of setting given time, synchronize from domain's RTC"),
|
|
|
|
},
|
|
|
|
{.name = "time",
|
|
|
|
.type = VSH_OT_INT,
|
|
|
|
.help = N_("time to set")
|
|
|
|
},
|
|
|
|
{.name = NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
static bool
|
|
|
|
cmdDomTime(vshControl *ctl, const vshCmd *cmd)
|
|
|
|
{
|
|
|
|
virDomainPtr dom;
|
|
|
|
bool ret = false;
|
|
|
|
bool now = vshCommandOptBool(cmd, "now");
|
|
|
|
bool pretty = vshCommandOptBool(cmd, "pretty");
|
2014-05-19 23:02:42 +00:00
|
|
|
bool rtcSync = vshCommandOptBool(cmd, "sync");
|
2014-04-02 16:50:12 +00:00
|
|
|
long long seconds = 0;
|
|
|
|
unsigned int nseconds = 0;
|
|
|
|
unsigned int flags = 0;
|
|
|
|
bool doSet = false;
|
|
|
|
int rv;
|
|
|
|
|
|
|
|
VSH_EXCLUSIVE_OPTIONS("time", "now");
|
|
|
|
VSH_EXCLUSIVE_OPTIONS("time", "sync");
|
|
|
|
VSH_EXCLUSIVE_OPTIONS("now", "sync");
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
|
2014-04-02 16:50:12 +00:00
|
|
|
return false;
|
|
|
|
|
2015-06-02 09:17:28 +00:00
|
|
|
rv = vshCommandOptLongLong(ctl, cmd, "time", &seconds);
|
2014-04-02 16:50:12 +00:00
|
|
|
|
|
|
|
if (rv < 0) {
|
|
|
|
/* invalid integer format */
|
|
|
|
goto cleanup;
|
|
|
|
} else if (rv > 0) {
|
|
|
|
/* valid integer to set */
|
|
|
|
doSet = true;
|
|
|
|
}
|
|
|
|
|
2014-05-19 23:02:42 +00:00
|
|
|
if (doSet || now || rtcSync) {
|
2014-04-02 16:50:12 +00:00
|
|
|
if (now && ((seconds = time(NULL)) == (time_t) -1)) {
|
|
|
|
vshError(ctl, _("Unable to get current time"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2014-05-19 23:02:42 +00:00
|
|
|
if (rtcSync)
|
2014-04-02 16:50:12 +00:00
|
|
|
flags |= VIR_DOMAIN_TIME_SYNC;
|
|
|
|
|
|
|
|
if (virDomainSetTime(dom, seconds, nseconds, flags) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
if (virDomainGetTime(dom, &seconds, &nseconds, flags) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (pretty) {
|
|
|
|
char timestr[100];
|
|
|
|
time_t cur_time = seconds;
|
|
|
|
struct tm time_info;
|
|
|
|
|
|
|
|
if (!gmtime_r(&cur_time, &time_info)) {
|
|
|
|
vshError(ctl, _("Unable to format time"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", &time_info);
|
|
|
|
|
|
|
|
vshPrint(ctl, _("Time: %s"), timestr);
|
|
|
|
} else {
|
|
|
|
vshPrint(ctl, _("Time: %lld"), seconds);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = true;
|
|
|
|
cleanup:
|
2017-04-11 10:16:52 +00:00
|
|
|
virshDomainFree(dom);
|
2014-04-02 16:50:12 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2012-07-24 08:24:50 +00:00
|
|
|
/*
|
|
|
|
* "list" command
|
|
|
|
*/
|
|
|
|
static const vshCmdInfo info_list[] = {
|
2013-02-07 15:25:10 +00:00
|
|
|
{.name = "help",
|
|
|
|
.data = N_("list domains")
|
|
|
|
},
|
|
|
|
{.name = "desc",
|
|
|
|
.data = N_("Returns list of domains.")
|
|
|
|
},
|
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* compare domains, pack NULLed ones at the end*/
|
|
|
|
static int
|
2015-06-15 16:53:58 +00:00
|
|
|
virshDomainSorter(const void *a, const void *b)
|
2012-07-24 08:24:50 +00:00
|
|
|
{
|
|
|
|
virDomainPtr *da = (virDomainPtr *) a;
|
|
|
|
virDomainPtr *db = (virDomainPtr *) b;
|
|
|
|
unsigned int ida;
|
|
|
|
unsigned int idb;
|
|
|
|
unsigned int inactive = (unsigned int) -1;
|
|
|
|
|
|
|
|
if (*da && !*db)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (!*da)
|
|
|
|
return *db != NULL;
|
|
|
|
|
|
|
|
ida = virDomainGetID(*da);
|
|
|
|
idb = virDomainGetID(*db);
|
|
|
|
|
|
|
|
if (ida == inactive && idb == inactive)
|
2012-08-14 07:21:44 +00:00
|
|
|
return vshStrcasecmp(virDomainGetName(*da), virDomainGetName(*db));
|
2012-07-24 08:24:50 +00:00
|
|
|
|
|
|
|
if (ida != inactive && idb != inactive) {
|
|
|
|
if (ida > idb)
|
|
|
|
return 1;
|
|
|
|
else if (ida < idb)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ida != inactive)
|
|
|
|
return -1;
|
|
|
|
else
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
struct virshDomainList {
|
2012-07-24 08:24:50 +00:00
|
|
|
virDomainPtr *domains;
|
|
|
|
size_t ndomains;
|
|
|
|
};
|
2015-06-15 16:53:58 +00:00
|
|
|
typedef struct virshDomainList *virshDomainListPtr;
|
2012-07-24 08:24:50 +00:00
|
|
|
|
|
|
|
static void
|
2015-06-15 16:53:58 +00:00
|
|
|
virshDomainListFree(virshDomainListPtr domlist)
|
2012-07-24 08:24:50 +00:00
|
|
|
{
|
Convert 'int i' to 'size_t i' in tools/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2012-07-24 08:24:50 +00:00
|
|
|
|
|
|
|
if (domlist && domlist->domains) {
|
|
|
|
for (i = 0; i < domlist->ndomains; i++) {
|
|
|
|
if (domlist->domains[i])
|
2017-04-11 10:16:52 +00:00
|
|
|
virshDomainFree(domlist->domains[i]);
|
2012-07-24 08:24:50 +00:00
|
|
|
}
|
|
|
|
VIR_FREE(domlist->domains);
|
|
|
|
}
|
|
|
|
VIR_FREE(domlist);
|
|
|
|
}
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
static virshDomainListPtr
|
|
|
|
virshDomainListCollect(vshControl *ctl, unsigned int flags)
|
2012-07-24 08:24:50 +00:00
|
|
|
{
|
2015-06-15 16:53:58 +00:00
|
|
|
virshDomainListPtr list = vshMalloc(ctl, sizeof(*list));
|
Convert 'int i' to 'size_t i' in tools/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2012-07-24 08:24:50 +00:00
|
|
|
int ret;
|
|
|
|
int *ids = NULL;
|
|
|
|
int nids = 0;
|
|
|
|
char **names = NULL;
|
|
|
|
int nnames = 0;
|
|
|
|
virDomainPtr dom;
|
|
|
|
bool success = false;
|
|
|
|
size_t deleted = 0;
|
|
|
|
int persistent;
|
|
|
|
int autostart;
|
|
|
|
int state;
|
|
|
|
int nsnap;
|
|
|
|
int mansave;
|
2015-06-15 16:53:58 +00:00
|
|
|
virshControlPtr priv = ctl->privData;
|
2012-07-24 08:24:50 +00:00
|
|
|
|
|
|
|
/* try the list with flags support (0.9.13 and later) */
|
2015-06-15 16:53:58 +00:00
|
|
|
if ((ret = virConnectListAllDomains(priv->conn, &list->domains,
|
2012-07-24 08:24:50 +00:00
|
|
|
flags)) >= 0) {
|
|
|
|
list->ndomains = ret;
|
|
|
|
goto finished;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check if the command is actually supported */
|
|
|
|
if (last_error && last_error->code == VIR_ERR_NO_SUPPORT) {
|
2012-07-25 11:41:49 +00:00
|
|
|
vshResetLibvirtError();
|
2012-07-24 08:24:50 +00:00
|
|
|
goto fallback;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (last_error && last_error->code == VIR_ERR_INVALID_ARG) {
|
|
|
|
/* try the new API again but mask non-guaranteed flags */
|
|
|
|
unsigned int newflags = flags & (VIR_CONNECT_LIST_DOMAINS_ACTIVE |
|
|
|
|
VIR_CONNECT_LIST_DOMAINS_INACTIVE);
|
|
|
|
|
2012-07-25 11:41:49 +00:00
|
|
|
vshResetLibvirtError();
|
2015-06-15 16:53:58 +00:00
|
|
|
if ((ret = virConnectListAllDomains(priv->conn, &list->domains,
|
2012-07-24 08:24:50 +00:00
|
|
|
newflags)) >= 0) {
|
|
|
|
list->ndomains = ret;
|
|
|
|
goto filter;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* there was an error during the first or second call */
|
|
|
|
vshError(ctl, "%s", _("Failed to list domains"));
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
|
2014-03-25 06:53:59 +00:00
|
|
|
fallback:
|
2012-07-24 08:24:50 +00:00
|
|
|
/* fall back to old method (0.9.12 and older) */
|
2012-07-26 09:24:30 +00:00
|
|
|
vshResetLibvirtError();
|
2012-07-24 08:24:50 +00:00
|
|
|
|
|
|
|
/* list active domains, if necessary */
|
2012-09-04 15:16:31 +00:00
|
|
|
if (!VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE) ||
|
|
|
|
VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_ACTIVE)) {
|
2015-06-15 16:53:58 +00:00
|
|
|
if ((nids = virConnectNumOfDomains(priv->conn)) < 0) {
|
2012-07-24 08:24:50 +00:00
|
|
|
vshError(ctl, "%s", _("Failed to list active domains"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nids) {
|
|
|
|
ids = vshMalloc(ctl, sizeof(int) * nids);
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
if ((nids = virConnectListDomains(priv->conn, ids, nids)) < 0) {
|
2012-07-24 08:24:50 +00:00
|
|
|
vshError(ctl, "%s", _("Failed to list active domains"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-04 15:16:31 +00:00
|
|
|
if (!VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE) ||
|
|
|
|
VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_INACTIVE)) {
|
2015-06-15 16:53:58 +00:00
|
|
|
if ((nnames = virConnectNumOfDefinedDomains(priv->conn)) < 0) {
|
2012-07-24 08:24:50 +00:00
|
|
|
vshError(ctl, "%s", _("Failed to list inactive domains"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nnames) {
|
|
|
|
names = vshMalloc(ctl, sizeof(char *) * nnames);
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
if ((nnames = virConnectListDefinedDomains(priv->conn, names,
|
2012-07-24 08:24:50 +00:00
|
|
|
nnames)) < 0) {
|
|
|
|
vshError(ctl, "%s", _("Failed to list inactive domains"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
list->domains = vshMalloc(ctl, sizeof(virDomainPtr) * (nids + nnames));
|
|
|
|
list->ndomains = 0;
|
|
|
|
|
|
|
|
/* get active domains */
|
|
|
|
for (i = 0; i < nids; i++) {
|
2015-06-15 16:53:58 +00:00
|
|
|
if (!(dom = virDomainLookupByID(priv->conn, ids[i])))
|
2012-07-24 08:24:50 +00:00
|
|
|
continue;
|
|
|
|
list->domains[list->ndomains++] = dom;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* get inactive domains */
|
|
|
|
for (i = 0; i < nnames; i++) {
|
2015-06-15 16:53:58 +00:00
|
|
|
if (!(dom = virDomainLookupByName(priv->conn, names[i])))
|
2012-07-24 08:24:50 +00:00
|
|
|
continue;
|
|
|
|
list->domains[list->ndomains++] = dom;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* truncate domains that weren't found */
|
|
|
|
deleted = (nids + nnames) - list->ndomains;
|
|
|
|
|
2014-03-25 06:53:59 +00:00
|
|
|
filter:
|
2012-07-24 08:24:50 +00:00
|
|
|
/* filter list the list if the list was acquired by fallback means */
|
|
|
|
for (i = 0; i < list->ndomains; i++) {
|
|
|
|
dom = list->domains[i];
|
|
|
|
|
|
|
|
/* persistence filter */
|
2012-09-04 15:16:31 +00:00
|
|
|
if (VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT)) {
|
2012-07-24 08:24:50 +00:00
|
|
|
if ((persistent = virDomainIsPersistent(dom)) < 0) {
|
|
|
|
vshError(ctl, "%s", _("Failed to get domain persistence info"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2012-09-04 15:16:31 +00:00
|
|
|
if (!((VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_PERSISTENT) && persistent) ||
|
|
|
|
(VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_TRANSIENT) && !persistent)))
|
2012-07-24 08:24:50 +00:00
|
|
|
goto remove_entry;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* domain state filter */
|
2012-09-04 15:16:31 +00:00
|
|
|
if (VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE)) {
|
2012-07-24 08:24:50 +00:00
|
|
|
if (virDomainGetState(dom, &state, NULL, 0) < 0) {
|
|
|
|
vshError(ctl, "%s", _("Failed to get domain state"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2012-09-04 15:16:31 +00:00
|
|
|
if (!((VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_RUNNING) &&
|
2012-07-24 08:24:50 +00:00
|
|
|
state == VIR_DOMAIN_RUNNING) ||
|
2012-09-04 15:16:31 +00:00
|
|
|
(VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_PAUSED) &&
|
2012-07-24 08:24:50 +00:00
|
|
|
state == VIR_DOMAIN_PAUSED) ||
|
2012-09-04 15:16:31 +00:00
|
|
|
(VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_SHUTOFF) &&
|
2012-07-24 08:24:50 +00:00
|
|
|
state == VIR_DOMAIN_SHUTOFF) ||
|
2012-09-04 15:16:31 +00:00
|
|
|
(VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_OTHER) &&
|
2012-07-24 08:24:50 +00:00
|
|
|
(state != VIR_DOMAIN_RUNNING &&
|
|
|
|
state != VIR_DOMAIN_PAUSED &&
|
|
|
|
state != VIR_DOMAIN_SHUTOFF))))
|
|
|
|
goto remove_entry;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* autostart filter */
|
2012-09-04 15:16:31 +00:00
|
|
|
if (VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_AUTOSTART)) {
|
2012-07-24 08:24:50 +00:00
|
|
|
if (virDomainGetAutostart(dom, &autostart) < 0) {
|
|
|
|
vshError(ctl, "%s", _("Failed to get domain autostart state"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2012-09-04 15:16:31 +00:00
|
|
|
if (!((VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_AUTOSTART) && autostart) ||
|
|
|
|
(VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART) && !autostart)))
|
2012-07-24 08:24:50 +00:00
|
|
|
goto remove_entry;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* managed save filter */
|
2012-09-04 15:16:31 +00:00
|
|
|
if (VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_MANAGEDSAVE)) {
|
2012-07-24 08:24:50 +00:00
|
|
|
if ((mansave = virDomainHasManagedSaveImage(dom, 0)) < 0) {
|
|
|
|
vshError(ctl, "%s",
|
|
|
|
_("Failed to check for managed save image"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2012-09-04 15:16:31 +00:00
|
|
|
if (!((VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE) && mansave) ||
|
|
|
|
(VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE) && !mansave)))
|
2012-07-24 08:24:50 +00:00
|
|
|
goto remove_entry;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* snapshot filter */
|
2012-09-04 15:16:31 +00:00
|
|
|
if (VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_SNAPSHOT)) {
|
2012-07-24 08:24:50 +00:00
|
|
|
if ((nsnap = virDomainSnapshotNum(dom, 0)) < 0) {
|
|
|
|
vshError(ctl, "%s", _("Failed to get snapshot count"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2012-09-04 15:16:31 +00:00
|
|
|
if (!((VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT) && nsnap > 0) ||
|
|
|
|
(VSH_MATCH(VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT) && nsnap == 0)))
|
2012-07-24 08:24:50 +00:00
|
|
|
goto remove_entry;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* the domain matched all filters, it may stay */
|
|
|
|
continue;
|
|
|
|
|
2014-03-25 06:53:59 +00:00
|
|
|
remove_entry:
|
2012-07-24 08:24:50 +00:00
|
|
|
/* the domain has to be removed as it failed one of the filters */
|
2017-04-11 10:16:52 +00:00
|
|
|
virshDomainFree(list->domains[i]);
|
2012-07-24 08:24:50 +00:00
|
|
|
list->domains[i] = NULL;
|
|
|
|
deleted++;
|
|
|
|
}
|
|
|
|
|
2014-03-25 06:53:59 +00:00
|
|
|
finished:
|
2012-07-24 08:24:50 +00:00
|
|
|
/* sort the list */
|
|
|
|
if (list->domains && list->ndomains)
|
|
|
|
qsort(list->domains, list->ndomains, sizeof(*list->domains),
|
2015-06-15 16:53:58 +00:00
|
|
|
virshDomainSorter);
|
2012-07-24 08:24:50 +00:00
|
|
|
|
|
|
|
/* truncate the list if filter simulation deleted entries */
|
|
|
|
if (deleted)
|
|
|
|
VIR_SHRINK_N(list->domains, list->ndomains, deleted);
|
|
|
|
|
|
|
|
success = true;
|
|
|
|
|
2014-03-25 06:53:59 +00:00
|
|
|
cleanup:
|
2013-07-11 14:28:44 +00:00
|
|
|
for (i = 0; nnames != -1 && i < nnames; i++)
|
2012-07-24 08:24:50 +00:00
|
|
|
VIR_FREE(names[i]);
|
|
|
|
|
|
|
|
if (!success) {
|
2015-06-15 16:53:58 +00:00
|
|
|
virshDomainListFree(list);
|
2012-07-24 08:24:50 +00:00
|
|
|
list = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
VIR_FREE(names);
|
|
|
|
VIR_FREE(ids);
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const vshCmdOptDef opts_list[] = {
|
2013-01-14 13:03:21 +00:00
|
|
|
{.name = "inactive",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list inactive domains")
|
|
|
|
},
|
|
|
|
{.name = "all",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list inactive & active domains")
|
|
|
|
},
|
|
|
|
{.name = "transient",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list transient domains")
|
|
|
|
},
|
|
|
|
{.name = "persistent",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list persistent domains")
|
|
|
|
},
|
|
|
|
{.name = "with-snapshot",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list domains with existing snapshot")
|
|
|
|
},
|
|
|
|
{.name = "without-snapshot",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list domains without a snapshot")
|
|
|
|
},
|
|
|
|
{.name = "state-running",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list domains in running state")
|
|
|
|
},
|
|
|
|
{.name = "state-paused",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list domains in paused state")
|
|
|
|
},
|
|
|
|
{.name = "state-shutoff",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list domains in shutoff state")
|
|
|
|
},
|
|
|
|
{.name = "state-other",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list domains in other states")
|
|
|
|
},
|
|
|
|
{.name = "autostart",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list domains with autostart enabled")
|
|
|
|
},
|
|
|
|
{.name = "no-autostart",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list domains with autostart disabled")
|
|
|
|
},
|
|
|
|
{.name = "with-managed-save",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list domains with managed save state")
|
|
|
|
},
|
|
|
|
{.name = "without-managed-save",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list domains without managed save")
|
|
|
|
},
|
|
|
|
{.name = "uuid",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list uuid's only")
|
|
|
|
},
|
|
|
|
{.name = "name",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list domain names only")
|
|
|
|
},
|
|
|
|
{.name = "table",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list table (default)")
|
|
|
|
},
|
|
|
|
{.name = "managed-save",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("mark inactive domains with managed save state")
|
|
|
|
},
|
|
|
|
{.name = "title",
|
|
|
|
.type = VSH_OT_BOOL,
|
2014-03-27 06:10:57 +00:00
|
|
|
.help = N_("show domain title")
|
2013-01-14 13:03:21 +00:00
|
|
|
},
|
|
|
|
{.name = NULL}
|
2012-07-24 08:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#define FILTER(NAME, FLAG) \
|
|
|
|
if (vshCommandOptBool(cmd, NAME)) \
|
|
|
|
flags |= (FLAG)
|
|
|
|
static bool
|
2013-05-27 10:08:00 +00:00
|
|
|
cmdList(vshControl *ctl, const vshCmd *cmd)
|
2012-07-24 08:24:50 +00:00
|
|
|
{
|
|
|
|
bool managed = vshCommandOptBool(cmd, "managed-save");
|
|
|
|
bool optTitle = vshCommandOptBool(cmd, "title");
|
|
|
|
bool optTable = vshCommandOptBool(cmd, "table");
|
|
|
|
bool optUUID = vshCommandOptBool(cmd, "uuid");
|
|
|
|
bool optName = vshCommandOptBool(cmd, "name");
|
Convert 'int i' to 'size_t i' in tools/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2012-07-24 08:24:50 +00:00
|
|
|
char *title;
|
|
|
|
char uuid[VIR_UUID_STRING_BUFLEN];
|
|
|
|
int state;
|
|
|
|
bool ret = false;
|
2015-06-15 16:53:58 +00:00
|
|
|
virshDomainListPtr list = NULL;
|
2012-07-24 08:24:50 +00:00
|
|
|
virDomainPtr dom;
|
|
|
|
char id_buf[INT_BUFSIZE_BOUND(unsigned int)];
|
|
|
|
unsigned int id;
|
|
|
|
unsigned int flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE;
|
|
|
|
|
|
|
|
/* construct filter flags */
|
2015-11-30 10:08:40 +00:00
|
|
|
if (vshCommandOptBool(cmd, "inactive") ||
|
|
|
|
vshCommandOptBool(cmd, "state-shutoff"))
|
2012-07-24 08:24:50 +00:00
|
|
|
flags = VIR_CONNECT_LIST_DOMAINS_INACTIVE;
|
|
|
|
|
|
|
|
if (vshCommandOptBool(cmd, "all"))
|
|
|
|
flags = VIR_CONNECT_LIST_DOMAINS_INACTIVE |
|
|
|
|
VIR_CONNECT_LIST_DOMAINS_ACTIVE;
|
|
|
|
|
|
|
|
FILTER("persistent", VIR_CONNECT_LIST_DOMAINS_PERSISTENT);
|
|
|
|
FILTER("transient", VIR_CONNECT_LIST_DOMAINS_TRANSIENT);
|
|
|
|
|
|
|
|
FILTER("with-managed-save", VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE);
|
|
|
|
FILTER("without-managed-save", VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE);
|
|
|
|
|
|
|
|
FILTER("autostart", VIR_CONNECT_LIST_DOMAINS_AUTOSTART);
|
|
|
|
FILTER("no-autostart", VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART);
|
|
|
|
|
|
|
|
FILTER("with-snapshot", VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT);
|
|
|
|
FILTER("without-snapshot", VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT);
|
|
|
|
|
|
|
|
FILTER("state-running", VIR_CONNECT_LIST_DOMAINS_RUNNING);
|
|
|
|
FILTER("state-paused", VIR_CONNECT_LIST_DOMAINS_PAUSED);
|
|
|
|
FILTER("state-shutoff", VIR_CONNECT_LIST_DOMAINS_SHUTOFF);
|
|
|
|
FILTER("state-other", VIR_CONNECT_LIST_DOMAINS_OTHER);
|
|
|
|
|
2016-07-09 10:06:55 +00:00
|
|
|
VSH_EXCLUSIVE_OPTIONS("table", "name");
|
|
|
|
VSH_EXCLUSIVE_OPTIONS("table", "uuid");
|
2012-07-24 08:24:50 +00:00
|
|
|
|
|
|
|
if (!optUUID && !optName)
|
|
|
|
optTable = true;
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
if (!(list = virshDomainListCollect(ctl, flags)))
|
2012-07-24 08:24:50 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
/* print table header in legacy mode */
|
|
|
|
if (optTable) {
|
|
|
|
if (optTitle)
|
|
|
|
vshPrintExtra(ctl, " %-5s %-30s %-10s %-20s\n%s\n",
|
|
|
|
_("Id"), _("Name"), _("State"), _("Title"),
|
|
|
|
"-----------------------------------------"
|
|
|
|
"-----------------------------------------");
|
|
|
|
else
|
|
|
|
vshPrintExtra(ctl, " %-5s %-30s %s\n%s\n",
|
|
|
|
_("Id"), _("Name"), _("State"),
|
|
|
|
"-----------------------------------------"
|
|
|
|
"-----------");
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < list->ndomains; i++) {
|
|
|
|
dom = list->domains[i];
|
|
|
|
id = virDomainGetID(dom);
|
|
|
|
if (id != (unsigned int) -1)
|
|
|
|
snprintf(id_buf, sizeof(id_buf), "%d", id);
|
|
|
|
else
|
|
|
|
ignore_value(virStrcpyStatic(id_buf, "-"));
|
|
|
|
|
2016-01-20 14:44:45 +00:00
|
|
|
if (optTable) {
|
|
|
|
state = virshDomainState(ctl, dom, NULL);
|
2014-10-30 13:39:04 +00:00
|
|
|
|
2016-01-20 14:44:45 +00:00
|
|
|
/* Domain could've been removed in the meantime */
|
|
|
|
if (state < 0)
|
|
|
|
continue;
|
2014-10-30 13:39:04 +00:00
|
|
|
|
2016-01-20 14:44:45 +00:00
|
|
|
if (managed && state == VIR_DOMAIN_SHUTOFF &&
|
|
|
|
virDomainHasManagedSaveImage(dom, 0) > 0)
|
|
|
|
state = -2;
|
2012-07-24 08:24:50 +00:00
|
|
|
|
|
|
|
if (optTitle) {
|
2015-06-15 16:53:58 +00:00
|
|
|
if (!(title = virshGetDomainDescription(ctl, dom, true, 0)))
|
2012-07-24 08:24:50 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
vshPrint(ctl, " %-5s %-30s %-10s %-20s\n", id_buf,
|
|
|
|
virDomainGetName(dom),
|
2015-06-15 16:53:58 +00:00
|
|
|
state == -2 ? _("saved")
|
|
|
|
: virshDomainStateToString(state),
|
2012-07-24 08:24:50 +00:00
|
|
|
title);
|
|
|
|
|
|
|
|
VIR_FREE(title);
|
|
|
|
} else {
|
|
|
|
vshPrint(ctl, " %-5s %-30s %s\n", id_buf,
|
|
|
|
virDomainGetName(dom),
|
2015-06-15 16:53:58 +00:00
|
|
|
state == -2 ? _("saved")
|
|
|
|
: virshDomainStateToString(state));
|
2012-07-24 08:24:50 +00:00
|
|
|
}
|
2016-07-09 10:06:55 +00:00
|
|
|
} else if (optUUID && optName) {
|
|
|
|
if (virDomainGetUUIDString(dom, uuid) < 0) {
|
|
|
|
vshError(ctl, "%s", _("Failed to get domain's UUID"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
vshPrint(ctl, "%-36s %-30s\n", uuid, virDomainGetName(dom));
|
2012-07-24 08:24:50 +00:00
|
|
|
} else if (optUUID) {
|
|
|
|
if (virDomainGetUUIDString(dom, uuid) < 0) {
|
|
|
|
vshError(ctl, "%s", _("Failed to get domain's UUID"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
vshPrint(ctl, "%s\n", uuid);
|
|
|
|
} else if (optName) {
|
|
|
|
vshPrint(ctl, "%s\n", virDomainGetName(dom));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = true;
|
2014-03-25 06:53:59 +00:00
|
|
|
cleanup:
|
2015-06-15 16:53:58 +00:00
|
|
|
virshDomainListFree(list);
|
2012-07-24 08:24:50 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#undef FILTER
|
2012-07-23 07:19:04 +00:00
|
|
|
|
2014-08-26 13:55:14 +00:00
|
|
|
/*
|
|
|
|
* "domstats" command
|
|
|
|
*/
|
|
|
|
static const vshCmdInfo info_domstats[] = {
|
|
|
|
{.name = "help",
|
|
|
|
.data = N_("get statistics about one or multiple domains")
|
|
|
|
},
|
|
|
|
{.name = "desc",
|
|
|
|
.data = N_("Gets statistics about one or more (or all) domains")
|
|
|
|
},
|
|
|
|
{.name = NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
static const vshCmdOptDef opts_domstats[] = {
|
|
|
|
{.name = "state",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("report domain state"),
|
|
|
|
},
|
2014-09-15 08:48:10 +00:00
|
|
|
{.name = "cpu-total",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("report domain physical cpu usage"),
|
|
|
|
},
|
|
|
|
{.name = "balloon",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("report domain balloon statistics"),
|
|
|
|
},
|
|
|
|
{.name = "vcpu",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("report domain virtual cpu information"),
|
|
|
|
},
|
|
|
|
{.name = "interface",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("report domain network interface information"),
|
|
|
|
},
|
|
|
|
{.name = "block",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("report domain block device statistics"),
|
|
|
|
},
|
2016-03-28 13:30:33 +00:00
|
|
|
{.name = "perf",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("report domain perf event statistics"),
|
|
|
|
},
|
2014-08-26 13:55:14 +00:00
|
|
|
{.name = "list-active",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list only active domains"),
|
|
|
|
},
|
|
|
|
{.name = "list-inactive",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list only inactive domains"),
|
|
|
|
},
|
|
|
|
{.name = "list-persistent",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list only persistent domains"),
|
|
|
|
},
|
|
|
|
{.name = "list-transient",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list only transient domains"),
|
|
|
|
},
|
|
|
|
{.name = "list-running",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list only running domains"),
|
|
|
|
},
|
|
|
|
{.name = "list-paused",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list only paused domains"),
|
|
|
|
},
|
|
|
|
{.name = "list-shutoff",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list only shutoff domains"),
|
|
|
|
},
|
|
|
|
{.name = "list-other",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("list only domains in other states"),
|
|
|
|
},
|
|
|
|
{.name = "raw",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("do not pretty-print the fields"),
|
|
|
|
},
|
|
|
|
{.name = "enforce",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("enforce requested stats parameters"),
|
|
|
|
},
|
getstats: add new flag for block backing chain
This patch introduces access to allocation information about
a backing chain of a live domain. While querying storage
volumes for read-only disks could provide some of the details,
we do NOT want to read() a file while qemu is writing it.
Also, there is one case where we have to rely on qemu: when
doing a block commit into a backing file, where that file is
stored in qcow2 format on a host block device, we want to know
the current highest write offset into that image, in order to
know if the disk must be resized larger. qemu-img does not
(currently) show this information, and none of the earlier
block APIs were extensible enough to expose it. But
virDomainListGetStats is perfect for the job!
We don't need a new group of statistics, as the existing block
group is sufficient. On the other hand, as existing libvirt
releases already report 1:1 mapping of block.count to <disk>
devices, changing the array size could confuse older clients;
and even with newer clients, the time and memory taken to
report additional statistics is not always necessary (backing
files are generally read-only except for block-commit, so while
read statistics may change, sizing statistics will not). So
the choice here is to add a new flag that only newer callers
will pass, when they are prepared for the additional information.
This patch introduces the new API, but it will take more
patches to get it implemented for qemu.
* include/libvirt/libvirt-domain.h
(VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING): New flag.
* src/libvirt-domain.c (virConnectGetAllDomainStats): Document it,
and add a new field when it is in use.
* tools/virsh-domain-monitor.c (cmdDomstats): Use new flag.
* tools/virsh.pod (domstats): Document it.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-11-25 15:46:49 +00:00
|
|
|
{.name = "backing",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.help = N_("add backing chain information to block stats"),
|
|
|
|
},
|
2014-08-26 13:55:14 +00:00
|
|
|
{.name = "domain",
|
|
|
|
.type = VSH_OT_ARGV,
|
|
|
|
.flags = VSH_OFLAG_NONE,
|
|
|
|
.help = N_("list of domains to get stats for"),
|
|
|
|
},
|
|
|
|
{.name = NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static bool
|
2015-06-15 16:53:58 +00:00
|
|
|
virshDomainStatsPrintRecord(vshControl *ctl ATTRIBUTE_UNUSED,
|
|
|
|
virDomainStatsRecordPtr record,
|
|
|
|
bool raw ATTRIBUTE_UNUSED)
|
2014-08-26 13:55:14 +00:00
|
|
|
{
|
|
|
|
char *param;
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
vshPrint(ctl, "Domain: '%s'\n", virDomainGetName(record->dom));
|
|
|
|
|
|
|
|
/* XXX: Implement pretty-printing */
|
|
|
|
|
|
|
|
for (i = 0; i < record->nparams; i++) {
|
|
|
|
if (!(param = vshGetTypedParamValue(ctl, record->params + i)))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
vshPrint(ctl, " %s=%s\n", record->params[i].field, param);
|
|
|
|
|
|
|
|
VIR_FREE(param);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
cmdDomstats(vshControl *ctl, const vshCmd *cmd)
|
|
|
|
{
|
|
|
|
unsigned int stats = 0;
|
|
|
|
virDomainPtr *domlist = NULL;
|
|
|
|
virDomainPtr dom;
|
|
|
|
size_t ndoms = 0;
|
|
|
|
virDomainStatsRecordPtr *records = NULL;
|
|
|
|
virDomainStatsRecordPtr *next;
|
|
|
|
bool raw = vshCommandOptBool(cmd, "raw");
|
|
|
|
int flags = 0;
|
|
|
|
const vshCmdOpt *opt = NULL;
|
|
|
|
bool ret = false;
|
2015-06-15 16:53:58 +00:00
|
|
|
virshControlPtr priv = ctl->privData;
|
2014-08-26 13:55:14 +00:00
|
|
|
|
|
|
|
if (vshCommandOptBool(cmd, "state"))
|
|
|
|
stats |= VIR_DOMAIN_STATS_STATE;
|
|
|
|
|
2014-09-15 08:48:10 +00:00
|
|
|
if (vshCommandOptBool(cmd, "cpu-total"))
|
|
|
|
stats |= VIR_DOMAIN_STATS_CPU_TOTAL;
|
|
|
|
|
|
|
|
if (vshCommandOptBool(cmd, "balloon"))
|
|
|
|
stats |= VIR_DOMAIN_STATS_BALLOON;
|
|
|
|
|
|
|
|
if (vshCommandOptBool(cmd, "vcpu"))
|
|
|
|
stats |= VIR_DOMAIN_STATS_VCPU;
|
|
|
|
|
|
|
|
if (vshCommandOptBool(cmd, "interface"))
|
|
|
|
stats |= VIR_DOMAIN_STATS_INTERFACE;
|
|
|
|
|
|
|
|
if (vshCommandOptBool(cmd, "block"))
|
|
|
|
stats |= VIR_DOMAIN_STATS_BLOCK;
|
|
|
|
|
2016-03-28 13:30:33 +00:00
|
|
|
if (vshCommandOptBool(cmd, "perf"))
|
|
|
|
stats |= VIR_DOMAIN_STATS_PERF;
|
|
|
|
|
2014-08-26 13:55:14 +00:00
|
|
|
if (vshCommandOptBool(cmd, "list-active"))
|
|
|
|
flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE;
|
|
|
|
|
|
|
|
if (vshCommandOptBool(cmd, "list-inactive"))
|
|
|
|
flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_INACTIVE;
|
|
|
|
|
|
|
|
if (vshCommandOptBool(cmd, "list-persistent"))
|
|
|
|
flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT;
|
|
|
|
|
|
|
|
if (vshCommandOptBool(cmd, "list-transient"))
|
|
|
|
flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_TRANSIENT;
|
|
|
|
|
|
|
|
if (vshCommandOptBool(cmd, "list-running"))
|
|
|
|
flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_RUNNING;
|
|
|
|
|
|
|
|
if (vshCommandOptBool(cmd, "list-paused"))
|
|
|
|
flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_PAUSED;
|
|
|
|
|
|
|
|
if (vshCommandOptBool(cmd, "list-shutoff"))
|
|
|
|
flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_SHUTOFF;
|
|
|
|
|
|
|
|
if (vshCommandOptBool(cmd, "list-other"))
|
|
|
|
flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_OTHER;
|
|
|
|
|
|
|
|
if (vshCommandOptBool(cmd, "enforce"))
|
|
|
|
flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS;
|
|
|
|
|
getstats: add new flag for block backing chain
This patch introduces access to allocation information about
a backing chain of a live domain. While querying storage
volumes for read-only disks could provide some of the details,
we do NOT want to read() a file while qemu is writing it.
Also, there is one case where we have to rely on qemu: when
doing a block commit into a backing file, where that file is
stored in qcow2 format on a host block device, we want to know
the current highest write offset into that image, in order to
know if the disk must be resized larger. qemu-img does not
(currently) show this information, and none of the earlier
block APIs were extensible enough to expose it. But
virDomainListGetStats is perfect for the job!
We don't need a new group of statistics, as the existing block
group is sufficient. On the other hand, as existing libvirt
releases already report 1:1 mapping of block.count to <disk>
devices, changing the array size could confuse older clients;
and even with newer clients, the time and memory taken to
report additional statistics is not always necessary (backing
files are generally read-only except for block-commit, so while
read statistics may change, sizing statistics will not). So
the choice here is to add a new flag that only newer callers
will pass, when they are prepared for the additional information.
This patch introduces the new API, but it will take more
patches to get it implemented for qemu.
* include/libvirt/libvirt-domain.h
(VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING): New flag.
* src/libvirt-domain.c (virConnectGetAllDomainStats): Document it,
and add a new field when it is in use.
* tools/virsh-domain-monitor.c (cmdDomstats): Use new flag.
* tools/virsh.pod (domstats): Document it.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-11-25 15:46:49 +00:00
|
|
|
if (vshCommandOptBool(cmd, "backing"))
|
|
|
|
flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING;
|
|
|
|
|
2014-08-26 13:55:14 +00:00
|
|
|
if (vshCommandOptBool(cmd, "domain")) {
|
|
|
|
if (VIR_ALLOC_N(domlist, 1) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
ndoms = 1;
|
|
|
|
|
2015-06-02 09:17:28 +00:00
|
|
|
while ((opt = vshCommandOptArgv(ctl, cmd, opt))) {
|
2015-06-15 16:53:58 +00:00
|
|
|
if (!(dom = virshLookupDomainBy(ctl, opt->data,
|
|
|
|
VIRSH_BYID |
|
|
|
|
VIRSH_BYUUID | VIRSH_BYNAME)))
|
2014-08-26 13:55:14 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (VIR_INSERT_ELEMENT(domlist, ndoms - 1, ndoms, dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virDomainListGetStats(domlist,
|
|
|
|
stats,
|
|
|
|
&records,
|
|
|
|
flags) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
} else {
|
2015-06-15 16:53:58 +00:00
|
|
|
if ((virConnectGetAllDomainStats(priv->conn,
|
2014-08-26 13:55:14 +00:00
|
|
|
stats,
|
|
|
|
&records,
|
|
|
|
flags)) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2017-02-10 15:04:42 +00:00
|
|
|
next = records;
|
|
|
|
while (*next) {
|
2015-06-15 16:53:58 +00:00
|
|
|
if (!virshDomainStatsPrintRecord(ctl, *next, raw))
|
2014-08-26 13:55:14 +00:00
|
|
|
goto cleanup;
|
2017-02-10 15:04:42 +00:00
|
|
|
|
|
|
|
if (*(++next))
|
|
|
|
vshPrint(ctl, "\n");
|
2014-08-26 13:55:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = true;
|
|
|
|
cleanup:
|
|
|
|
virDomainStatsRecordListFree(records);
|
2015-04-29 09:54:58 +00:00
|
|
|
virObjectListFree(domlist);
|
2014-08-26 13:55:14 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-01-25 18:38:49 +00:00
|
|
|
/* "domifaddr" command
|
|
|
|
*/
|
|
|
|
static const vshCmdInfo info_domifaddr[] = {
|
|
|
|
{"help", N_("Get network interfaces' addresses for a running domain")},
|
|
|
|
{"desc", N_("Get network interfaces' addresses for a running domain")},
|
|
|
|
{NULL, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
static const vshCmdOptDef opts_domifaddr[] = {
|
2016-01-09 13:36:24 +00:00
|
|
|
VIRSH_COMMON_OPT_DOMAIN_FULL,
|
2015-01-25 18:38:49 +00:00
|
|
|
{.name = "interface",
|
|
|
|
.type = VSH_OT_STRING,
|
|
|
|
.flags = VSH_OFLAG_NONE,
|
|
|
|
.help = N_("network interface name")},
|
|
|
|
{.name = "full",
|
|
|
|
.type = VSH_OT_BOOL,
|
|
|
|
.flags = VSH_OFLAG_NONE,
|
|
|
|
.help = N_("display full fields")},
|
|
|
|
{.name = "source",
|
|
|
|
.type = VSH_OT_STRING,
|
|
|
|
.flags = VSH_OFLAG_NONE,
|
|
|
|
.help = N_("address source: 'lease' or 'agent'")},
|
|
|
|
{.name = NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
static bool
|
|
|
|
cmdDomIfAddr(vshControl *ctl, const vshCmd *cmd)
|
|
|
|
{
|
|
|
|
virDomainPtr dom = NULL;
|
2015-03-28 20:04:27 +00:00
|
|
|
const char *ifacestr = NULL;
|
2015-01-25 18:38:49 +00:00
|
|
|
virDomainInterfacePtr *ifaces = NULL;
|
|
|
|
size_t i, j;
|
|
|
|
int ifaces_count = 0;
|
|
|
|
bool ret = false;
|
|
|
|
bool full = vshCommandOptBool(cmd, "full");
|
|
|
|
const char *sourcestr = NULL;
|
|
|
|
int source = VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE;
|
|
|
|
|
2015-06-15 16:53:58 +00:00
|
|
|
if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
|
2015-01-25 18:38:49 +00:00
|
|
|
return false;
|
|
|
|
|
2015-12-03 12:42:35 +00:00
|
|
|
if (vshCommandOptStringReq(ctl, cmd, "interface", &ifacestr) < 0)
|
2015-01-25 18:38:49 +00:00
|
|
|
goto cleanup;
|
2015-12-03 12:42:35 +00:00
|
|
|
if (vshCommandOptStringReq(ctl, cmd, "source", &sourcestr) < 0)
|
2015-01-25 18:38:49 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (sourcestr) {
|
|
|
|
if (STREQ(sourcestr, "lease")) {
|
|
|
|
source = VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE;
|
|
|
|
} else if (STREQ(sourcestr, "agent")) {
|
|
|
|
source = VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT;
|
|
|
|
} else {
|
|
|
|
vshError(ctl, _("Unknown data source '%s'"), sourcestr);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((ifaces_count = virDomainInterfaceAddresses(dom, &ifaces, source, 0)) < 0) {
|
|
|
|
vshError(ctl, _("Failed to query for interfaces addresses"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
vshPrintExtra(ctl, " %-10s %-20s %-8s %s\n%s%s\n", _("Name"),
|
|
|
|
_("MAC address"), _("Protocol"), _("Address"),
|
|
|
|
_("-------------------------------------------------"),
|
|
|
|
_("------------------------------"));
|
|
|
|
|
|
|
|
for (i = 0; i < ifaces_count; i++) {
|
|
|
|
virDomainInterfacePtr iface = ifaces[i];
|
2015-03-17 16:34:22 +00:00
|
|
|
char *ip_addr_str = NULL;
|
2015-01-25 18:38:49 +00:00
|
|
|
const char *type = NULL;
|
|
|
|
|
2015-03-28 20:04:27 +00:00
|
|
|
if (ifacestr && STRNEQ(ifacestr, iface->name))
|
2015-01-25 18:38:49 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
/* When the interface has no IP address */
|
|
|
|
if (!iface->naddrs) {
|
2015-04-03 09:41:03 +00:00
|
|
|
vshPrint(ctl, " %-10s %-17s %-12s %s\n",
|
|
|
|
iface->name,
|
|
|
|
iface->hwaddr ? iface->hwaddr : "N/A", "N/A", "N/A");
|
2015-01-25 18:38:49 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (j = 0; j < iface->naddrs; j++) {
|
|
|
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
|
|
|
|
|
switch (iface->addrs[j].type) {
|
|
|
|
case VIR_IP_ADDR_TYPE_IPV4:
|
|
|
|
type = "ipv4";
|
|
|
|
break;
|
|
|
|
case VIR_IP_ADDR_TYPE_IPV6:
|
|
|
|
type = "ipv6";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
virBufferAsprintf(&buf, "%-12s %s/%d",
|
|
|
|
type, iface->addrs[j].addr,
|
|
|
|
iface->addrs[j].prefix);
|
|
|
|
|
|
|
|
if (virBufferError(&buf)) {
|
|
|
|
virBufferFreeAndReset(&buf);
|
|
|
|
virReportOOMError();
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ip_addr_str = virBufferContentAndReset(&buf);
|
|
|
|
|
|
|
|
if (!ip_addr_str)
|
2015-03-17 16:34:22 +00:00
|
|
|
ip_addr_str = vshStrdup(ctl, "");
|
2015-01-25 18:38:49 +00:00
|
|
|
|
|
|
|
/* Don't repeat interface name */
|
|
|
|
if (full || !j)
|
2015-04-03 09:41:03 +00:00
|
|
|
vshPrint(ctl, " %-10s %-17s %s\n",
|
|
|
|
iface->name,
|
|
|
|
iface->hwaddr ? iface->hwaddr : "", ip_addr_str);
|
2015-01-25 18:38:49 +00:00
|
|
|
else
|
2015-04-03 09:41:03 +00:00
|
|
|
vshPrint(ctl, " %-10s %-17s %s\n",
|
|
|
|
"-", "-", ip_addr_str);
|
2015-01-25 18:38:49 +00:00
|
|
|
|
|
|
|
virBufferFreeAndReset(&buf);
|
2015-03-17 16:34:22 +00:00
|
|
|
VIR_FREE(ip_addr_str);
|
2015-01-25 18:38:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = true;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (ifaces && ifaces_count > 0) {
|
|
|
|
for (i = 0; i < ifaces_count; i++)
|
|
|
|
virDomainInterfaceFree(ifaces[i]);
|
|
|
|
}
|
|
|
|
VIR_FREE(ifaces);
|
|
|
|
|
2017-04-11 10:16:52 +00:00
|
|
|
virshDomainFree(dom);
|
2015-01-25 18:38:49 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2012-08-20 13:46:38 +00:00
|
|
|
const vshCmdDef domMonitoringCmds[] = {
|
2013-02-07 15:25:10 +00:00
|
|
|
{.name = "domblkerror",
|
|
|
|
.handler = cmdDomBlkError,
|
|
|
|
.opts = opts_domblkerror,
|
|
|
|
.info = info_domblkerror,
|
|
|
|
.flags = 0
|
|
|
|
},
|
|
|
|
{.name = "domblkinfo",
|
|
|
|
.handler = cmdDomblkinfo,
|
|
|
|
.opts = opts_domblkinfo,
|
|
|
|
.info = info_domblkinfo,
|
|
|
|
.flags = 0
|
|
|
|
},
|
|
|
|
{.name = "domblklist",
|
|
|
|
.handler = cmdDomblklist,
|
|
|
|
.opts = opts_domblklist,
|
|
|
|
.info = info_domblklist,
|
|
|
|
.flags = 0
|
|
|
|
},
|
|
|
|
{.name = "domblkstat",
|
|
|
|
.handler = cmdDomblkstat,
|
|
|
|
.opts = opts_domblkstat,
|
|
|
|
.info = info_domblkstat,
|
|
|
|
.flags = 0
|
|
|
|
},
|
|
|
|
{.name = "domcontrol",
|
|
|
|
.handler = cmdDomControl,
|
|
|
|
.opts = opts_domcontrol,
|
|
|
|
.info = info_domcontrol,
|
|
|
|
.flags = 0
|
|
|
|
},
|
|
|
|
{.name = "domif-getlink",
|
|
|
|
.handler = cmdDomIfGetLink,
|
|
|
|
.opts = opts_domif_getlink,
|
|
|
|
.info = info_domif_getlink,
|
|
|
|
.flags = 0
|
|
|
|
},
|
2015-01-25 18:38:49 +00:00
|
|
|
{.name = "domifaddr",
|
|
|
|
.handler = cmdDomIfAddr,
|
|
|
|
.opts = opts_domifaddr,
|
|
|
|
.info = info_domifaddr,
|
|
|
|
.flags = 0
|
|
|
|
},
|
2013-02-07 15:25:10 +00:00
|
|
|
{.name = "domiflist",
|
|
|
|
.handler = cmdDomiflist,
|
|
|
|
.opts = opts_domiflist,
|
|
|
|
.info = info_domiflist,
|
|
|
|
.flags = 0
|
|
|
|
},
|
|
|
|
{.name = "domifstat",
|
|
|
|
.handler = cmdDomIfstat,
|
|
|
|
.opts = opts_domifstat,
|
|
|
|
.info = info_domifstat,
|
|
|
|
.flags = 0
|
|
|
|
},
|
|
|
|
{.name = "dominfo",
|
|
|
|
.handler = cmdDominfo,
|
|
|
|
.opts = opts_dominfo,
|
|
|
|
.info = info_dominfo,
|
|
|
|
.flags = 0
|
|
|
|
},
|
|
|
|
{.name = "dommemstat",
|
|
|
|
.handler = cmdDomMemStat,
|
|
|
|
.opts = opts_dommemstat,
|
|
|
|
.info = info_dommemstat,
|
|
|
|
.flags = 0
|
|
|
|
},
|
|
|
|
{.name = "domstate",
|
|
|
|
.handler = cmdDomstate,
|
|
|
|
.opts = opts_domstate,
|
|
|
|
.info = info_domstate,
|
|
|
|
.flags = 0
|
|
|
|
},
|
2014-08-26 13:55:14 +00:00
|
|
|
{.name = "domstats",
|
|
|
|
.handler = cmdDomstats,
|
|
|
|
.opts = opts_domstats,
|
|
|
|
.info = info_domstats,
|
|
|
|
.flags = 0
|
|
|
|
},
|
2014-04-02 16:50:12 +00:00
|
|
|
{.name = "domtime",
|
|
|
|
.handler = cmdDomTime,
|
|
|
|
.opts = opts_domtime,
|
|
|
|
.info = info_domtime,
|
|
|
|
.flags = 0
|
|
|
|
},
|
2013-02-07 15:25:10 +00:00
|
|
|
{.name = "list",
|
|
|
|
.handler = cmdList,
|
|
|
|
.opts = opts_list,
|
|
|
|
.info = info_list,
|
|
|
|
.flags = 0
|
|
|
|
},
|
|
|
|
{.name = NULL}
|
2012-07-23 07:19:04 +00:00
|
|
|
};
|