提交 8e7829f7 编写于 作者: M Michal Privoznik

virsh: Move job watch code to a separate function

called vshWatchJob. This can be later used in other
job oriented commands like dump, save, managedsave
to report progress and allow user to cancel via ^C.
上级 6da91758
......@@ -395,6 +395,29 @@ static char *editWriteToTempFile (vshControl *ctl, const char *doc);
static int editFile (vshControl *ctl, const char *filename);
static char *editReadBackFile (vshControl *ctl, const char *filename);
/* Typedefs, function prototypes for job progress reporting.
* There are used by some long lingering commands like
* migrate, dump, save, managedsave.
*/
typedef struct __vshCtrlData {
vshControl *ctl;
const vshCmd *cmd;
int writefd;
} vshCtrlData;
typedef void (*jobWatchTimeoutFunc) (vshControl *ctl, virDomainPtr dom,
void *opaque);
static bool
vshWatchJob(vshControl *ctl,
virDomainPtr dom,
bool verbose,
int pipe_fd,
int timeout,
jobWatchTimeoutFunc timeout_func,
void *opaque,
const char *label);
static void *_vshMalloc(vshControl *ctl, size_t sz, const char *filename, int line);
#define vshMalloc(_ctl, _sz) _vshMalloc(_ctl, _sz, __FILE__, __LINE__)
......@@ -5881,12 +5904,6 @@ static const vshCmdOptDef opts_migrate[] = {
{NULL, 0, 0, NULL}
};
typedef struct __vshCtrlData {
vshControl *ctl;
const vshCmd *cmd;
int writefd;
} vshCtrlData;
static void
doMigrate (void *opaque)
{
......@@ -6019,75 +6036,46 @@ print_job_progress(const char *label, unsigned long long remaining,
fflush(stderr);
}
static void
vshMigrationTimeout(vshControl *ctl,
virDomainPtr dom,
void *opaque ATTRIBUTE_UNUSED)
{
vshDebug(ctl, VSH_ERR_DEBUG, "suspending the domain, "
"since migration timed out\n");
virDomainSuspend(dom);
}
static bool
cmdMigrate (vshControl *ctl, const vshCmd *cmd)
vshWatchJob(vshControl *ctl,
virDomainPtr dom,
bool verbose,
int pipe_fd,
int timeout,
jobWatchTimeoutFunc timeout_func,
void *opaque,
const char *label)
{
virDomainPtr dom = NULL;
int p[2] = {-1, -1};
int ret = -1;
bool functionReturn = false;
virThread workerThread;
struct pollfd pollfd;
char retchar;
struct sigaction sig_action;
struct sigaction old_sig_action;
virDomainJobInfo jobinfo;
bool verbose = false;
int timeout = 0;
struct pollfd pollfd;
struct timeval start, curr;
bool live_flag = false;
vshCtrlData data;
virDomainJobInfo jobinfo;
int ret = -1;
char retchar;
bool functionReturn = false;
sigset_t sigmask, oldsigmask;
sigemptyset(&sigmask);
sigaddset(&sigmask, SIGINT);
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
return false;
if (vshCommandOptBool (cmd, "verbose"))
verbose = true;
if (vshCommandOptBool (cmd, "live"))
live_flag = true;
if (vshCommandOptInt(cmd, "timeout", &timeout) > 0) {
if (! live_flag) {
vshError(ctl, "%s", _("migrate: Unexpected timeout for offline migration"));
goto cleanup;
}
if (timeout < 1) {
vshError(ctl, "%s", _("migrate: Invalid timeout"));
goto cleanup;
}
/* Ensure that we can multiply by 1000 without overflowing. */
if (timeout > INT_MAX / 1000) {
vshError(ctl, "%s", _("migrate: Timeout is too big"));
goto cleanup;
}
}
if (pipe(p) < 0)
goto cleanup;
data.ctl = ctl;
data.cmd = cmd;
data.writefd = p[1];
if (virThreadCreate(&workerThread,
true,
doMigrate,
&data) < 0)
goto cleanup;
intCaught = 0;
sig_action.sa_sigaction = vshCatchInt;
sig_action.sa_flags = SA_SIGINFO;
sigemptyset(&sig_action.sa_mask);
sigaction(SIGINT, &sig_action, &old_sig_action);
pollfd.fd = p[0];
pollfd.fd = pipe_fd;
pollfd.events = POLLIN;
pollfd.revents = 0;
......@@ -6096,18 +6084,16 @@ cmdMigrate (vshControl *ctl, const vshCmd *cmd)
repoll:
ret = poll(&pollfd, 1, 500);
if (ret > 0) {
if (saferead(p[0], &retchar, sizeof(retchar)) > 0) {
if (retchar == '0') {
functionReturn = true;
if (pollfd.revents & POLLIN &&
saferead(pipe_fd, &retchar, sizeof(retchar)) > 0 &&
retchar == '0') {
if (verbose) {
/* print [100 %] */
print_job_progress("Migration", 0, 1);
print_job_progress(label, 0, 1);
}
} else
functionReturn = false;
} else
functionReturn = false;
break;
break;
}
goto cleanup;
}
if (ret < 0) {
......@@ -6118,17 +6104,16 @@ repoll:
} else
goto repoll;
}
functionReturn = false;
break;
goto cleanup;
}
GETTIMEOFDAY(&curr);
if ( timeout && ((int)(curr.tv_sec - start.tv_sec) * 1000 + \
(int)(curr.tv_usec - start.tv_usec) / 1000) > timeout * 1000 ) {
/* suspend the domain when migration timeouts. */
vshDebug(ctl, VSH_ERR_DEBUG,
"suspend the domain when migration timeouts\n");
virDomainSuspend(dom);
vshDebug(ctl, VSH_ERR_DEBUG, "%s timeout", label);
if (timeout_func)
(timeout_func)(ctl, dom, opaque);
timeout = 0;
}
......@@ -6137,12 +6122,70 @@ repoll:
ret = virDomainGetJobInfo(dom, &jobinfo);
pthread_sigmask(SIG_SETMASK, &oldsigmask, NULL);
if (ret == 0)
print_job_progress("Migration", jobinfo.dataRemaining,
print_job_progress(label, jobinfo.dataRemaining,
jobinfo.dataTotal);
}
}
functionReturn = true;
cleanup:
sigaction(SIGINT, &old_sig_action, NULL);
return functionReturn;
}
static bool
cmdMigrate (vshControl *ctl, const vshCmd *cmd)
{
virDomainPtr dom = NULL;
int p[2] = {-1, -1};
virThread workerThread;
bool verbose = false;
bool functionReturn = false;
int timeout = 0;
bool live_flag = false;
vshCtrlData data;
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
return false;
if (vshCommandOptBool (cmd, "verbose"))
verbose = true;
if (vshCommandOptBool (cmd, "live"))
live_flag = true;
if (vshCommandOptInt(cmd, "timeout", &timeout) > 0) {
if (! live_flag) {
vshError(ctl, "%s", _("migrate: Unexpected timeout for offline migration"));
goto cleanup;
}
if (timeout < 1) {
vshError(ctl, "%s", _("migrate: Invalid timeout"));
goto cleanup;
}
/* Ensure that we can multiply by 1000 without overflowing. */
if (timeout > INT_MAX / 1000) {
vshError(ctl, "%s", _("migrate: Timeout is too big"));
goto cleanup;
}
}
if (pipe(p) < 0)
goto cleanup;
data.ctl = ctl;
data.cmd = cmd;
data.writefd = p[1];
if (virThreadCreate(&workerThread,
true,
doMigrate,
&data) < 0)
goto cleanup;
functionReturn = vshWatchJob(ctl, dom, verbose, p[0], timeout,
vshMigrationTimeout, NULL, _("Migration"));
virThreadJoin(&workerThread);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册