* virDomainBlockJobAbort:
* @dom: pointer to domain object
* @disk: path to the block device, or device shorthand
- * @flags: extra flags; not used yet, so callers should always pass 0
+ * @flags: bitwise-OR of virDomainBlockJobAbortFlags
*
* Cancel the active block job on the given disk.
*
* can be found by calling virDomainGetXMLDesc() and inspecting
* elements within //domain/devices/disk.
*
+ * By default, this function performs a synchronous operation and the caller
+ * may assume that the operation has completed when 0 is returned. However,
+ * BlockJob operations may take a long time to cancel, and during this time
+ * further domain interactions may be unresponsive. To avoid this problem,
+ * pass VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC in the @flags argument to enable
+ * asynchronous behavior, returning as soon as possible. When the job has
+ * been canceled, a BlockJob event will be emitted, with status
+ * VIR_DOMAIN_BLOCK_JOB_CANCELED (even if the ABORT_ASYNC flag was not
+ * used); it is also possible to poll virDomainBlockJobInfo() to see if
+ * the job cancellation is still pending.
+ *
* Returns -1 in case of failure, 0 when successful.
*/
int virDomainBlockJobAbort(virDomainPtr dom, const char *disk,
const char *name, *path;
unsigned long bandwidth = 0;
int ret = -1;
+ unsigned int flags = 0;
if (!vshConnectionUsability(ctl, ctl->conn))
goto cleanup;
}
if (mode == VSH_CMD_BLOCK_JOB_ABORT) {
- ret = virDomainBlockJobAbort(dom, path, 0);
+ if (vshCommandOptBool(cmd, "async"))
+ flags |= VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC;
+ ret = virDomainBlockJobAbort(dom, path, flags);
} else if (mode == VSH_CMD_BLOCK_JOB_INFO) {
ret = virDomainGetBlockJobInfo(dom, path, info, 0);
} else if (mode == VSH_CMD_BLOCK_JOB_SPEED) {
}
/*
- * "blockjobinfo" command
+ * "blockjob" command
*/
static const vshCmdInfo info_block_job[] = {
- {"help", N_("Manage active block operations.")},
- {"desc", N_("Manage active block operations.")},
+ {"help", N_("Manage active block operations")},
+ {"desc", N_("Query, adjust speed, or cancel active block operations.")},
{NULL, NULL}
};
static const vshCmdOptDef opts_block_job[] = {
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
{"path", VSH_OT_DATA, VSH_OFLAG_REQ, N_("Fully-qualified path of disk")},
- {"abort", VSH_OT_BOOL, VSH_OFLAG_NONE, N_("Abort the active job on the specified disk")},
- {"info", VSH_OT_BOOL, VSH_OFLAG_NONE, N_("Get active job information for the specified disk")},
- {"bandwidth", VSH_OT_DATA, VSH_OFLAG_NONE, N_("Set the Bandwidth limit in MB/s")},
+ {"abort", VSH_OT_BOOL, VSH_OFLAG_NONE,
+ N_("Abort the active job on the specified disk")},
+ {"async", VSH_OT_BOOL, VSH_OFLAG_NONE,
+ N_("don't wait for --abort to complete")},
+ {"info", VSH_OT_BOOL, VSH_OFLAG_NONE,
+ N_("Get active job information for the specified disk")},
+ {"bandwidth", VSH_OT_DATA, VSH_OFLAG_NONE,
+ N_("Set the Bandwidth limit in MB/s")},
{NULL, 0, 0, NULL}
};
virDomainBlockJobInfo info;
const char *type;
int ret;
+ bool abortMode = (vshCommandOptBool(cmd, "abort") ||
+ vshCommandOptBool(cmd, "async"));
+ bool infoMode = vshCommandOptBool(cmd, "info");
+ bool bandwidth = vshCommandOptBool(cmd, "bandwidth");
- if (vshCommandOptBool (cmd, "abort")) {
- mode = VSH_CMD_BLOCK_JOB_ABORT;
- } else if (vshCommandOptBool (cmd, "info")) {
- mode = VSH_CMD_BLOCK_JOB_INFO;
- } else if (vshCommandOptBool (cmd, "bandwidth")) {
- mode = VSH_CMD_BLOCK_JOB_SPEED;
- } else {
+ if (abortMode + infoMode + bandwidth > 1) {
vshError(ctl, "%s",
- _("One of --abort, --info, or --bandwidth is required"));
+ _("conflict between --abort, --info, and --bandwidth modes"));
return false;
}
+ if (abortMode)
+ mode = VSH_CMD_BLOCK_JOB_ABORT;
+ else if (bandwidth)
+ mode = VSH_CMD_BLOCK_JOB_SPEED;
+ else
+ mode = VSH_CMD_BLOCK_JOB_INFO;
+
ret = blockJobImpl(ctl, cmd, &info, mode);
if (ret < 0)
return false;
return true;
if (info.type == VIR_DOMAIN_BLOCK_JOB_TYPE_PULL)
- type = "Block Pull";
+ type = _("Block Pull");
else
- type = "Unknown job";
+ type = _("Unknown job");
print_job_progress(type, info.end - info.cur, info.end);
if (info.bandwidth != 0)
- vshPrint(ctl, " Bandwidth limit: %lu MB/s\n", info.bandwidth);
+ vshPrint(ctl, _(" Bandwidth limit: %lu MB/s\n"), info.bandwidth);
return true;
}
{"autostart", cmdAutostart, opts_autostart, info_autostart, 0},
{"blkdeviotune", cmdBlkdeviotune, opts_blkdeviotune, info_blkdeviotune, 0},
{"blkiotune", cmdBlkiotune, opts_blkiotune, info_blkiotune, 0},
- {"blockpull", cmdBlockPull, opts_block_pull, info_block_pull, 0},
{"blockjob", cmdBlockJob, opts_block_job, info_block_job, 0},
+ {"blockpull", cmdBlockPull, opts_block_pull, info_block_pull, 0},
{"blockresize", cmdBlockResize, opts_block_resize, info_block_resize, 0},
{"change-media", cmdChangeMedia, opts_change_media, info_change_media, 0},
#ifndef WIN32
It pulls data for the entire disk in the background, the process of the
operation can be checked with B<blockjob>.
-I<path> specifies fully-qualified path of the disk.
+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).
I<bandwidth> specifies copying bandwidth limit in Mbps.
=item B<blkdeviotune> I<domain> I<device>
exclusive. If no flag is specified, behavior is different depending
on hypervisor.
-=item B<blockjob> I<domain> I<path> [I<--abort>] [I<--info>] [I<bandwidth>]
+=item B<blockjob> I<domain> I<path> { [I<--abort>] [I<--async>] |
+[I<--info>] | [I<bandwidth>] }
-Manage active block operations.
+Manage active block operations. There are three modes: I<--info>,
+I<bandwidth>, and I<--abort>; I<--info> is default except that I<--async>
+implies I<--abort>.
+
+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).
-I<path> specifies fully-qualified path of the disk.
If I<--abort> is specified, the active job on the specified disk will
-be aborted.
+be aborted. If I<--async> is also specified, this command will return
+immediately, rather than waiting for the cancelation to complete.
If I<--info> is specified, the active job information on the specified
disk will be printed.
I<bandwidth> can be used to set bandwidth limit for the active job.
=item B<blockresize> I<domain> I<path> I<size>
Resize a block device of domain while the domain is running, I<path>
-specifies the absolute path of the block device, I<size> is a scaled
-integer (see B<NOTES> above) which defaults to KiB (blocks of 1024 bytes)
-if there is no suffix. You must use a suffix of "B" to get bytes (note
-that for historical reasons, this differs from B<vol-resize> which
-defaults to bytes without a suffix).
+specifies the absolute path of the block device; 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).
+
+I<size> is a scaled integer (see B<NOTES> above) which defaults to KiB
+(blocks of 1024 bytes) if there is no suffix. You must use a suffix of
+"B" to get bytes (note that for historical reasons, this differs from
+B<vol-resize> which defaults to bytes without a suffix).
=item B<dominfo> I<domain-id>