mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
Show migration progress.
Show migration progress if `migrate --verbose'.
This commit is contained in:
parent
8e6d9860cd
commit
d183e9d1e8
@ -3413,6 +3413,7 @@ static const vshCmdOptDef opts_migrate[] = {
|
|||||||
{"suspend", VSH_OT_BOOL, 0, N_("do not restart the domain on the destination host")},
|
{"suspend", VSH_OT_BOOL, 0, N_("do not restart the domain on the destination host")},
|
||||||
{"copy-storage-all", VSH_OT_BOOL, 0, N_("migration with non-shared storage with full disk copy")},
|
{"copy-storage-all", VSH_OT_BOOL, 0, N_("migration with non-shared storage with full disk copy")},
|
||||||
{"copy-storage-inc", VSH_OT_BOOL, 0, N_("migration with non-shared storage with incremental copy (same base image shared between source and destination)")},
|
{"copy-storage-inc", VSH_OT_BOOL, 0, N_("migration with non-shared storage with incremental copy (same base image shared between source and destination)")},
|
||||||
|
{"verbose", VSH_OT_BOOL, 0, N_("display the progress of migration")},
|
||||||
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
|
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
|
||||||
{"desturi", VSH_OT_DATA, VSH_OFLAG_REQ, N_("connection URI of the destination host as seen from the client(normal migration) or source(p2p migration)")},
|
{"desturi", VSH_OT_DATA, VSH_OFLAG_REQ, N_("connection URI of the destination host as seen from the client(normal migration) or source(p2p migration)")},
|
||||||
{"migrateuri", VSH_OT_DATA, 0, N_("migration URI, usually can be omitted")},
|
{"migrateuri", VSH_OT_DATA, 0, N_("migration URI, usually can be omitted")},
|
||||||
@ -3515,6 +3516,30 @@ out_sig:
|
|||||||
ignore_value(safewrite(data->writefd, &ret, sizeof(ret)));
|
ignore_value(safewrite(data->writefd, &ret, sizeof(ret)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_job_progress(unsigned long long remaining, unsigned long long total)
|
||||||
|
{
|
||||||
|
int progress;
|
||||||
|
|
||||||
|
if (total == 0)
|
||||||
|
/* migration has not been started */
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (remaining == 0) {
|
||||||
|
/* migration has completed */
|
||||||
|
progress = 100;
|
||||||
|
} else {
|
||||||
|
/* use float to avoid overflow */
|
||||||
|
progress = (int)(100.0 - remaining * 100.0 / total);
|
||||||
|
if (progress >= 100) {
|
||||||
|
/* migration has not completed, do not print [100 %] */
|
||||||
|
progress = 99;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "\rMigration: [%3d %%]", progress);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cmdMigrate (vshControl *ctl, const vshCmd *cmd)
|
cmdMigrate (vshControl *ctl, const vshCmd *cmd)
|
||||||
{
|
{
|
||||||
@ -3526,12 +3551,18 @@ cmdMigrate (vshControl *ctl, const vshCmd *cmd)
|
|||||||
char retchar;
|
char retchar;
|
||||||
struct sigaction sig_action;
|
struct sigaction sig_action;
|
||||||
struct sigaction old_sig_action;
|
struct sigaction old_sig_action;
|
||||||
|
virDomainJobInfo jobinfo;
|
||||||
|
bool verbose = false;
|
||||||
|
sigset_t sigmask, oldsigmask;
|
||||||
|
|
||||||
vshCtrlData data;
|
vshCtrlData data;
|
||||||
|
|
||||||
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
|
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
if (vshCommandOptBool (cmd, "verbose"))
|
||||||
|
verbose = true;
|
||||||
|
|
||||||
if (pipe(p) < 0)
|
if (pipe(p) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
@ -3554,18 +3585,28 @@ cmdMigrate (vshControl *ctl, const vshCmd *cmd)
|
|||||||
pollfd.fd = p[0];
|
pollfd.fd = p[0];
|
||||||
pollfd.events = POLLIN;
|
pollfd.events = POLLIN;
|
||||||
pollfd.revents = 0;
|
pollfd.revents = 0;
|
||||||
|
sigemptyset(&sigmask);
|
||||||
|
sigaddset(&sigmask, SIGINT);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
repoll:
|
repoll:
|
||||||
ret = poll(&pollfd, 1, -1);
|
ret = poll(&pollfd, 1, 500);
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
if (saferead(p[0], &retchar, sizeof(retchar)) > 0) {
|
if (saferead(p[0], &retchar, sizeof(retchar)) > 0) {
|
||||||
if (retchar == '0')
|
if (retchar == '0') {
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
else
|
if (verbose) {
|
||||||
|
/* print [100 %] */
|
||||||
|
print_job_progress(0, 1);
|
||||||
|
}
|
||||||
|
} else
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
} else
|
} else
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
} else if (ret < 0) {
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
if (errno == EINTR) {
|
if (errno == EINTR) {
|
||||||
if (intCaught) {
|
if (intCaught) {
|
||||||
virDomainAbortJob(dom);
|
virDomainAbortJob(dom);
|
||||||
@ -3574,9 +3615,16 @@ repoll:
|
|||||||
} else
|
} else
|
||||||
goto repoll;
|
goto repoll;
|
||||||
}
|
}
|
||||||
} else {
|
break;
|
||||||
/* timed out */
|
}
|
||||||
ret = FALSE;
|
|
||||||
|
if (verbose) {
|
||||||
|
pthread_sigmask(SIG_BLOCK, &sigmask, &oldsigmask);
|
||||||
|
ret = virDomainGetJobInfo(dom, &jobinfo);
|
||||||
|
pthread_sigmask(SIG_SETMASK, &oldsigmask, NULL);
|
||||||
|
if (ret == 0)
|
||||||
|
print_job_progress(jobinfo.dataRemaining, jobinfo.dataTotal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sigaction(SIGINT, &old_sig_action, NULL);
|
sigaction(SIGINT, &old_sig_action, NULL);
|
||||||
|
@ -489,7 +489,8 @@ type attribute for the <domain> element of XML.
|
|||||||
|
|
||||||
=item B<migrate> optional I<--live> I<--p2p> I<--direct> I<--tunnelled>
|
=item B<migrate> optional I<--live> I<--p2p> I<--direct> I<--tunnelled>
|
||||||
I<--persistent> I<--undefinesource> I<--suspend> I<--copy-storage-all>
|
I<--persistent> I<--undefinesource> I<--suspend> I<--copy-storage-all>
|
||||||
I<--copy-storage-inc> I<domain-id> I<desturi> I<migrateuri> I<dname>
|
I<--copy-storage-inc> I<--verbose> I<domain-id> I<desturi> I<migrateuri>
|
||||||
|
I<dname>
|
||||||
|
|
||||||
Migrate domain to another host. Add I<--live> for live migration; I<--p2p>
|
Migrate domain to another host. Add I<--live> for live migration; I<--p2p>
|
||||||
for peer-2-peer migration; I<--direct> for direct migration; or I<--tunnelled>
|
for peer-2-peer migration; I<--direct> for direct migration; or I<--tunnelled>
|
||||||
@ -499,6 +500,7 @@ and I<--suspend> leaves the domain paused on the destination host.
|
|||||||
I<--copy-storage-all> indicates migration with non-shared storage with full
|
I<--copy-storage-all> indicates migration with non-shared storage with full
|
||||||
disk copy, I<--copy-storage-inc> indicates migration with non-shared storage
|
disk copy, I<--copy-storage-inc> indicates migration with non-shared storage
|
||||||
with incremental copy (same base image shared between source and destination).
|
with incremental copy (same base image shared between source and destination).
|
||||||
|
I<--verbose> displays the progress of migration.
|
||||||
|
|
||||||
The I<desturi> is the connection URI of the destination host, and
|
The I<desturi> is the connection URI of the destination host, and
|
||||||
I<migrateuri> is the migration URI, which usually can be omitted.
|
I<migrateuri> is the migration URI, which usually can be omitted.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user