static int
-qemuMonitorOpenUnix(const char *monitor, pid_t cpid)
+qemuMonitorOpenUnix(const char *monitor,
+ pid_t cpid,
+ unsigned long long timeout)
{
struct sockaddr_un addr;
int monfd;
- virTimeBackOffVar timeout;
+ virTimeBackOffVar timebackoff;
int ret = -1;
if ((monfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
goto error;
}
- if (virTimeBackOffStart(&timeout, 1, 30*1000 /* ms */) < 0)
+ if (virTimeBackOffStart(&timebackoff, 1, timeout * 1000) < 0)
goto error;
- while (virTimeBackOffWait(&timeout)) {
+ while (virTimeBackOffWait(&timebackoff)) {
ret = connect(monfd, (struct sockaddr *) &addr, sizeof(addr));
if (ret == 0)
}
+#define QEMU_DEFAULT_MONITOR_WAIT 30
+
+/**
+ * qemuMonitorOpen:
+ * @vm: domain object
+ * @config: monitor configuration
+ * @json: enable JSON on the monitor
+ * @timeout: number of seconds to add to default timeout
+ * @cb: monitor event handles
+ * @opaque: opaque data for @cb
+ *
+ * Opens the monitor for running qemu. It may happen that it
+ * takes some time for qemu to create the monitor socket (e.g.
+ * because kernel is zeroing configured hugepages), therefore we
+ * wait up to default + timeout seconds for the monitor to show
+ * up after which a failure is claimed.
+ *
+ * Returns monitor object, NULL on error.
+ */
qemuMonitorPtr
qemuMonitorOpen(virDomainObjPtr vm,
virDomainChrSourceDefPtr config,
bool json,
+ unsigned long long timeout,
qemuMonitorCallbacksPtr cb,
void *opaque)
{
bool hasSendFD = false;
qemuMonitorPtr ret;
+ timeout += QEMU_DEFAULT_MONITOR_WAIT;
+
switch (config->type) {
case VIR_DOMAIN_CHR_TYPE_UNIX:
hasSendFD = true;
- if ((fd = qemuMonitorOpenUnix(config->data.nix.path, vm ? vm->pid : 0)) < 0)
+ if ((fd = qemuMonitorOpenUnix(config->data.nix.path,
+ vm ? vm->pid : 0,
+ timeout)) < 0)
return NULL;
break;
qemuDomainObjPrivatePtr priv = vm->privateData;
int ret = -1;
qemuMonitorPtr mon = NULL;
+ unsigned long long timeout = 0;
if (qemuSecuritySetDaemonSocketLabel(driver->securityManager, vm->def) < 0) {
VIR_ERROR(_("Failed to set security context for monitor for %s"),
return -1;
}
+ /* When using hugepages, kernel zeroes them out before
+ * handing them over to qemu. This can be very time
+ * consuming. Therefore, add a second to timeout for each
+ * 1GiB of guest RAM. */
+ timeout = vm->def->mem.total_memory / (1024 * 1024);
+
/* Hold an extra reference because we can't allow 'vm' to be
* deleted until the monitor gets its own reference. */
virObjectRef(vm);
mon = qemuMonitorOpen(vm,
priv->monConfig,
priv->monJSON,
+ timeout,
&monitorCallbacks,
driver);