Add "domstats" command that excercises both of the new APIs depending if you specify a domain list or not. The output is printed as a key=value list of the returned parameters. --- tools/virsh-domain-monitor.c | 191 +++++++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 34 ++++++++ 2 files changed, 225 insertions(+) diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c index 8bd58ad..b152256 100644 --- a/tools/virsh-domain-monitor.c +++ b/tools/virsh-domain-monitor.c @@ -1954,6 +1954,191 @@ cmdList(vshControl *ctl, const vshCmd *cmd) } #undef FILTER +/* + * "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"), + }, + {.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"), + }, + {.name = "domains", + .type = VSH_OT_ARGV, + .flags = VSH_OFLAG_NONE, + .help = N_("list of domains to get stats for"), + }, + {.name = NULL} +}; + + +static bool +vshDomainStatsPrintRecord(vshControl *ctl ATTRIBUTE_UNUSED, + virDomainStatsRecordPtr record, + bool raw ATTRIBUTE_UNUSED) +{ + 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); + } + + vshPrint(ctl, "\n"); + 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; + + VSH_EXCLUSIVE_OPTIONS("domains", "list-active"); + VSH_EXCLUSIVE_OPTIONS("domains", "list-inactive"); + VSH_EXCLUSIVE_OPTIONS("domains", "list-persistent"); + VSH_EXCLUSIVE_OPTIONS("domains", "list-transient"); + VSH_EXCLUSIVE_OPTIONS("domains", "list-running"); + VSH_EXCLUSIVE_OPTIONS("domains", "list-paused"); + VSH_EXCLUSIVE_OPTIONS("domains", "list-shutoff"); + VSH_EXCLUSIVE_OPTIONS("domains", "list-other"); + + if (vshCommandOptBool(cmd, "state")) + stats |= VIR_DOMAIN_STATS_STATE; + + 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; + + if (vshCommandOptBool(cmd, "domains")) { + if (VIR_ALLOC_N(domlist, 1) < 0) + goto cleanup; + ndoms = 1; + + while ((opt = vshCommandOptArgv(cmd, opt))) { + if (!(dom = vshLookupDomainBy(ctl, opt->data, + VSH_BYID | VSH_BYUUID | VSH_BYNAME))) + goto cleanup; + + if (VIR_INSERT_ELEMENT(domlist, ndoms - 1, ndoms, dom) < 0) + goto cleanup; + } + + if (virDomainListGetStats(domlist, + stats, + &records, + flags) < 0) + goto cleanup; + } else { + if ((virConnectGetAllDomainStats(ctl->conn, + stats, + &records, + flags)) < 0) + goto cleanup; + } + + for (next = records; *next; next++) { + if (!vshDomainStatsPrintRecord(ctl, *next, raw)) + goto cleanup; + } + + ret = true; + cleanup: + virDomainStatsRecordListFree(records); + virDomainListFree(domlist); + + return ret; +} + const vshCmdDef domMonitoringCmds[] = { {.name = "domblkerror", .handler = cmdDomBlkError, @@ -2021,6 +2206,12 @@ const vshCmdDef domMonitoringCmds[] = { .info = info_domstate, .flags = 0 }, + {.name = "domstats", + .handler = cmdDomstats, + .opts = opts_domstats, + .info = info_domstats, + .flags = 0 + }, {.name = "domtime", .handler = cmdDomTime, .opts = opts_domtime, diff --git a/tools/virsh.pod b/tools/virsh.pod index e0dfd13..b08c938 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -813,6 +813,40 @@ that require a block device name (such as I<domblkinfo> or I<snapshot-create> for disk snapshots) will accept either target or unique source names printed by this command. +=item B<domstats> [[I<--list-active>] [I<--list-inactive>] +[I<--list-persistent>] [I<--list-transient>] [I<--list-running>] +[I<--list-paused>] [I<--list-shutoff>] [I<--list-other>]] | [I<domains>] +[I<--raw>] [I<--enforce>] [I<--state>] + +Get statistics for multiple or all domains. Without any argument this +command prints all available statistics for all domains. + +The list of domains to gather stats for can be either limited by listing +the domains as a space separated list, or by specifying one of the +filtering flags I<--list-*>. (The approaches can't be combined.) + +By default some of the returned fields may be converted to more +human friendly values by a set of pretty-printers. To suppress this +behavior use the I<--raw> flag. + +The individual statistics groups are selectable via specific flags. By +default all supported statistics groups are returned. Supported +statistics groups flags are: I<--state>. + +Selecting a specific statistics groups doesn't guarantee that the +daemon supports the selected group of stats. Flag I<--enforce> +forces the command to fail if the daemon doesn't support the +selected group. + + $ tools/virsh domstats --state dom1 dom2 + Domain: 'dom1' + state.state=shut off + state.reason=unknown + + Domain: 'dom2' + state.state=running + state.reason=booted + =item B<domiflist> I<domain> [I<--inactive>] Print a table showing the brief information of all virtual interfaces -- 2.0.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list