The current output of 'blockjob [--info]' is a single line designed for human consumption; it's not very nice for machine parsing. Furthermore, I have plans to modify the line in response to the new flag for controlling bandwidth units. Solve that by adding a --raw parameter, which outputs information closer to the C struct. $ virsh blockjob testvm1 vda --raw type=Block Copy bandwidth=1 cur=197120 end=197120 The information is indented, because I'd like for a later patch to add a mode that iterates over all the vm's disks with status for each; in that mode, each block name would be listed unindented before information (if any) about that block. Now that we have a raw mode, we can guarantee that it won't change format over time. Any app that cares about parsing the output can try --raw, and if it fails, know that it was talking to an older virsh and fall back to parsing the human-readable format which had not changed until now; meanwhile, when not using --raw, we have freed future virsh to change the output to whatever makes sense. My first change to human mode: this command now guarantees a line is printed on successful use of the API, even when the API did not find a current block job (consistent with the rest of virsh). Bonus: https://bugzilla.redhat.com/show_bug.cgi?id=1135441 complained that this message was confusing: $ virsh blockjob test1 hda --async --bandwidth 10 error: conflict between --abort, --info, and --bandwidth modes even though the man page already documents that --async implies abort mode, all because '--abort' wasn't present in the command line. Since I'm adding another case where options are tied to or imply a mode, I changed that error to: error: conflict between abort, info, and bandwidth modes * tools/virsh-domain.c (cmdBlockJob): Add --raw parameter; tweak error wording. * tools/virsh.pod (blockjob): Document it. Signed-off-by: Eric Blake <eblake@xxxxxxxxxx> --- tools/virsh-domain.c | 31 +++++++++++++++++++++++-------- tools/virsh.pod | 19 ++++++++++++------- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index d1297ad..b95e971 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -2038,16 +2038,20 @@ static const vshCmdOptDef opts_block_job[] = { }, {.name = "async", .type = VSH_OT_BOOL, - .help = N_("don't wait for --abort to complete") + .help = N_("implies --abort; request but don't wait for job end") }, {.name = "pivot", .type = VSH_OT_BOOL, - .help = N_("conclude and pivot a copy job") + .help = N_("implies --abort; conclude and pivot a copy job") }, {.name = "info", .type = VSH_OT_BOOL, .help = N_("get active job information for the specified disk") }, + {.name = "raw", + .type = VSH_OT_BOOL, + .help = N_("implies --info; output details rather than human summary") + }, {.name = "bandwidth", .type = VSH_OT_DATA, .help = N_("set the Bandwidth limit in MiB/s") @@ -2077,10 +2081,11 @@ cmdBlockJob(vshControl *ctl, const vshCmd *cmd) virDomainBlockJobInfo info; bool ret = false; int rc; + bool raw = vshCommandOptBool(cmd, "raw"); bool abortMode = (vshCommandOptBool(cmd, "abort") || vshCommandOptBool(cmd, "async") || vshCommandOptBool(cmd, "pivot")); - bool infoMode = vshCommandOptBool(cmd, "info"); + bool infoMode = vshCommandOptBool(cmd, "info") || raw; bool bandwidth = vshCommandOptBool(cmd, "bandwidth"); virDomainPtr dom = NULL; const char *path; @@ -2088,7 +2093,7 @@ cmdBlockJob(vshControl *ctl, const vshCmd *cmd) if (abortMode + infoMode + bandwidth > 1) { vshError(ctl, "%s", - _("conflict between --abort, --info, and --bandwidth modes")); + _("conflict between abort, info, and bandwidth modes")); return false; } @@ -2109,14 +2114,24 @@ cmdBlockJob(vshControl *ctl, const vshCmd *cmd) if (rc < 0) goto cleanup; if (rc == 0) { + if (!raw) + vshPrint(ctl, _("No current block job for %s"), path); ret = true; goto cleanup; } - vshPrintJobProgress(vshDomainBlockJobToString(info.type), - info.end - info.cur, info.end); - if (info.bandwidth != 0) - vshPrint(ctl, _(" Bandwidth limit: %lu MiB/s\n"), info.bandwidth); + if (raw) { + vshPrint(ctl, _(" type=%s\n bandwidth=%lu\n cur=%llu\n end=%llu\n"), + vshDomainBlockJobTypeToString(info.type), + info.bandwidth, info.cur, info.end); + } else { + vshPrintJobProgress(vshDomainBlockJobToString(info.type), + info.end - info.cur, info.end); + if (info.bandwidth != 0) + vshPrint(ctl, _(" Bandwidth limit: %lu MiB/s"), + info.bandwidth); + vshPrint(ctl, "\n"); + } ret = true; cleanup: if (dom) diff --git a/tools/virsh.pod b/tools/virsh.pod index ea9267e..3f1bf7e 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -1013,24 +1013,29 @@ exclusive. If no flag is specified, behavior is different depending on hypervisor. =item B<blockjob> I<domain> I<path> { [I<--abort>] [I<--async>] [I<--pivot>] | -[I<--info>] | [I<bandwidth>] } +[I<--info>] [I<--raw>] | [I<bandwidth>] } -Manage active block operations. There are three modes: I<--info>, -I<bandwidth>, and I<--abort>; I<--info> is default except that I<--async> -or I<--pivot> implies I<--abort>. +Manage active block operations. There are three mutually-exclusive modes: +I<--info>, I<bandwidth>, and I<--abort>. I<--async> and I<--pivot> imply +abort mode; I<--raw> implies info mode; and if no mode was given, I<--info> +mode is assumed. I<path> specifies fully-qualified path of the disk; it corresponds to a unique target name (<target dev='name'/>) or source file (<source file='name'/>) for one of the disk devices attached to I<domain> (see also B<domblklist> for listing these names). -If I<--abort> is specified, the active job on the specified disk will +In I<--abort> mode, the active job on the specified disk will be aborted. If I<--async> is also specified, this command will return immediately, rather than waiting for the cancellation to complete. If I<--pivot> is specified, this requests that an active copy or active commit job be pivoted over to the new image. -If I<--info> is specified, the active job information on the specified -disk will be printed. + +In I<--info> mode, the active job information on the specified +disk will be printed. By default, the output is a single human-readable +summary line; this format may change in future versions. Adding +I<--raw> lists each field of the struct, in a stable format. + I<bandwidth> can be used to set bandwidth limit for the active job. Specifying a negative value is interpreted as an unsigned long long value or essentially unlimited. The hypervisor can choose whether to -- 1.9.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list