On Thu, Jun 09, 2011 at 12:10:11PM -0500, Adam Litke wrote: > Define three new virsh commands: > * blockpull: Perform incremental block pull > * blockpull: Start/stop full device block pull > * blockpullinfo: Retrieve progress info for full device block pull > > Share print_job_progress() with the migration code. > > * tools/virsh.c: implement the new commands > > Signed-off-by: Adam Litke <agl@xxxxxxxxxx> > --- > tools/virsh.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- > 1 files changed, 130 insertions(+), 4 deletions(-) > > diff --git a/tools/virsh.c b/tools/virsh.c > index 123781f..81c2e71 100644 > --- a/tools/virsh.c > +++ b/tools/virsh.c > @@ -4095,7 +4095,8 @@ out_sig: > } > > static void > -print_job_progress(unsigned long long remaining, unsigned long long total) > +print_job_progress(const char *label, unsigned long long remaining, > + unsigned long long total) > { > int progress; > > @@ -4115,7 +4116,7 @@ print_job_progress(unsigned long long remaining, unsigned long long total) > } > } > > - fprintf(stderr, "\rMigration: [%3d %%]", progress); > + fprintf(stderr, "\r%s: [%3d %%]", label, progress); > } > > static bool > @@ -4202,7 +4203,7 @@ repoll: > functionReturn = true; > if (verbose) { > /* print [100 %] */ > - print_job_progress(0, 1); > + print_job_progress("Migration", 0, 1); > } > } else > functionReturn = false; > @@ -4241,7 +4242,8 @@ repoll: > pthread_sigmask(SIG_SETMASK, &oldsigmask, NULL); > #endif > if (ret == 0) > - print_job_progress(jobinfo.dataRemaining, jobinfo.dataTotal); > + print_job_progress("Migration", jobinfo.dataRemaining, > + jobinfo.dataTotal); > } > } > > @@ -4344,6 +4346,127 @@ done: > return ret; > } > > +typedef enum { > + VSH_CMD_BLOCK_PULL_ONE = 0, > + VSH_CMD_BLOCK_PULL_ALL = 1, > + VSH_CMD_BLOCK_PULL_ABORT = 2, > + VSH_CMD_BLOCK_PULL_INFO = 3 > +} VSH_CMD_BLOCK_PULL_MODE; > + > +static int > +blockPullImpl(vshControl *ctl, const vshCmd *cmd, > + virDomainBlockPullInfoPtr info, int mode) > +{ > + virDomainPtr dom; > + const char *name, *path; > + int ret = -1; > + > + if (!vshConnectionUsability(ctl, ctl->conn)) > + return false; > + > + if (!(dom = vshCommandOptDomain(ctl, cmd, &name))) > + return false; > + > + if (vshCommandOptString(cmd, "path", &path) < 0) > + return false; > + > + if (mode == VSH_CMD_BLOCK_PULL_ONE) > + ret = virDomainBlockPull(dom, path, info, 0); > + else if (mode == VSH_CMD_BLOCK_PULL_ALL) > + ret = virDomainBlockPullAll(dom, path, 0); > + else if (mode == VSH_CMD_BLOCK_PULL_ABORT) > + ret = virDomainBlockPullAbort(dom, path, 0); > + else if (mode == VSH_CMD_BLOCK_PULL_INFO) > + ret = virDomainGetBlockPullInfo(dom, path, info, 0); > + > + virDomainFree(dom); > + return ret; > +} > + > +/* > + * "blockpull" command > + */ > +static const vshCmdInfo info_block_pull[] = { > + {"help", N_("Iteratively populate a disk from its backing image.")}, > + {"desc", N_("Iteratively populate a disk from its backing image.")}, > + {NULL, NULL} > +}; > + > +static const vshCmdOptDef opts_block_pull[] = { > + {"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")}, > + {NULL, 0, 0, NULL} > +}; > + > +static bool > +cmdBlockPull(vshControl *ctl, const vshCmd *cmd) > +{ > + virDomainBlockPullInfo info; > + > + if (blockPullImpl(ctl, cmd, &info, VSH_CMD_BLOCK_PULL_ONE) != 0) > + return false; > + print_job_progress("Block pull", info.end - info.cur, info.end); > + return true; > +} > + > +/* > + * "blockpullall" command > + */ > +static const vshCmdInfo info_block_pull_all[] = { > + {"help", N_("Start or stop populating a disk from its backing image.")}, > + {"desc", N_("Start or stop populating a disk from its backing image.")}, > + {NULL, NULL} > +}; > + > +static const vshCmdOptDef opts_block_pull_all[] = { > + {"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 current operation")}, > + {NULL, 0, 0, NULL} > +}; > + > +static bool > +cmdBlockPullAll(vshControl *ctl, const vshCmd *cmd) > +{ > + int mode; > + > + if (vshCommandOptBool (cmd, "abort")) > + mode = VSH_CMD_BLOCK_PULL_ABORT; > + else > + mode = VSH_CMD_BLOCK_PULL_ALL; > + > + if (blockPullImpl(ctl, cmd, NULL, mode) != 0) > + return false; > + return true; > +} In constrast to the API, I think it might be worth merging this command with "blockpull", just having a '--all' flag for it. > +/* > + * "blockpullinfo" command > + */ > +static const vshCmdInfo info_block_pull_info[] = { > + {"help", N_("Check progress of an active block pull operation.")}, > + {"desc", N_("Check progress of an active block pull operation.")}, > + {NULL, NULL} > +}; > + > +static const vshCmdOptDef opts_block_pull_info[] = { > + {"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")}, > + {NULL, 0, 0, NULL} > +}; > + > +static bool > +cmdBlockPullInfo(vshControl *ctl, const vshCmd *cmd) > +{ > + virDomainBlockPullInfo info; > + > + if (blockPullImpl(ctl, cmd, &info, VSH_CMD_BLOCK_PULL_INFO) != 0) > + return false; > + print_job_progress("Block pull", info.end - info.cur, info.end); > + return true; > +} > + > + > /* > * "net-autostart" command > */ > @@ -11093,6 +11216,9 @@ static const vshCmdDef domManagementCmds[] = { > info_attach_interface, 0}, > {"autostart", cmdAutostart, opts_autostart, info_autostart, 0}, > {"blkiotune", cmdBlkiotune, opts_blkiotune, info_blkiotune, 0}, > + {"blockpull", cmdBlockPull, opts_block_pull, info_block_pull, 0}, > + {"blockpullall", cmdBlockPullAll, opts_block_pull_all, info_block_pull_all, 0}, > + {"blockpullinfo", cmdBlockPullInfo, opts_block_pull_info, info_block_pull_info, 0}, > #ifndef WIN32 > {"console", cmdConsole, opts_console, info_console, 0}, > #endif Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list