Unlike the pty monitor (which we know exists since we scrape its path from
stdout), we have no way of knowing that the unix monitor socket should exist/
be initialized. As a result, some of my KVM guests randomly fail to start on
F10 host.
Try to open the unix socket in a 3 second timeout loop. Ignore EACCES (path
does not exist if a first time run) and ECONNREFUSED (leftover socket from
a previous run hasn't been removed yet). Fixes things for me.
---
src/qemu_driver.c | 22 +++++++++++++++++++++-
1 files changed, 21 insertions(+), 1 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index e2b7acb..200718b 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -874,6 +874,8 @@ qemudOpenMonitorUnix(virConnectPtr conn,
{
struct sockaddr_un addr;
int monfd;
+ int timeout = 3; /* In seconds */
+ int ret, i;
if ((monfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
virReportSystemError(conn, errno,
@@ -885,10 +887,28 @@ qemudOpenMonitorUnix(virConnectPtr conn,
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, monitor, sizeof(addr.sun_path));
- if (connect(monfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ do {
+ ret = connect(monfd, (struct sockaddr *) &addr, sizeof(addr));
+
+ if (ret == 0)
+ break;
+
+ if (errno == EACCES || errno == ECONNREFUSED) {
+ /* EACCES : Socket may not have shown up yet
+ * ECONNREFUSED : Leftover socket hasn't been removed yet */
+ continue;
+ }
+
virReportSystemError(conn, errno, "%s",
_("failed to connect to monitor socket"));
goto error;
+
+ } while ((++i <= timeout*5) && (usleep(.2 * 1000000) <= 0));
+
+ if (ret != 0) {
+ virReportSystemError(conn, errno, "%s",
+ _("monitor socket did not show up."));
+ goto error;
}
if (qemudOpenMonitorCommon(conn, driver, vm, monfd, reconnect) < 0)
--
1.6.0.6