From 1b745219c7507595d4a09c89aa6a331eaa039e31 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Thu, 22 Jan 2009 19:41:48 +0000 Subject: [PATCH] Remove use of non-reentrant POSIX apis --- ChangeLog | 17 +++++- configure.in | 2 +- proxy/libvirt_proxy.c | 3 - qemud/qemud.c | 23 ++++---- src/libvirt_private.syms | 1 + src/lxc_container.c | 9 +-- src/network_driver.c | 18 +++--- src/openvz_driver.c | 3 +- src/qemu_driver.c | 22 +++---- src/remote_internal.c | 15 ++--- src/storage_backend_fs.c | 7 ++- src/storage_driver.c | 14 ++--- src/uml_driver.c | 18 +++--- src/util.c | 37 ++++++++++++ src/util.h | 5 ++ src/xen_unified.c | 3 - src/xen_unified.h | 10 ++-- src/xend_internal.c | 123 +++++++++++++++++++++------------------ 18 files changed, 198 insertions(+), 132 deletions(-) diff --git a/ChangeLog b/ChangeLog index febf84989a..26186d2cc7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +Thu Jan 21 19:04:12 GMT 2009 Daniel P. Berrange + + Remove use of non-reentrant POSIX api calls + * configure.in: Check for strtok_r getmntent_r getgrnam_r getpwuid_r + * proxy/libvirt_proxy.c: Remove initialize of obsolete fields + * qemud/qemud.c: Use virGetUserDirectory instead of getpwuid() + * src/libvirt_private.syms, src/util.c, src/util.h: Add a generic + virGetUserDirectory call around getpwuid() + * src/lxc_container.c, src/storage_backend_fs.c: Use getmntent_r() + * src/network_driver.c, src/qemu_driver.c, src/storage_driver.c, + src/remote_internal.c, src/uml_driver.c: Use virGetUserDirectory() + * src/openvz_driver.c: Use strtok_r() + * src/xen_unified.c, src/xen_unified.h, src/xend_internal.c: + Replace gethostname() with getaddrinfo() + Thu Jan 22 20:17:35 +0100 2009 Jim Meyering xm_internal.c: fix locking bug: s/Lock/Unlock/ @@ -44,7 +59,7 @@ Thu Jan 22 09:51:29 PST 2009 John Levon tests/sexpr2xmldata/sexpr2xml-net-bridged.xml, tests/sexpr2xmldata/sexpr2xml-net-e1000.xml: update tests -Wed Jan 21 18:18:12 GMT 2009 Daniel P. Berrange +Thu Jan 22 18:18:12 GMT 2009 Daniel P. Berrange Missing test case fix up from Xen threadsafety changes * tests/sexpr2xmltest.c, tests/Makefile.am: Pass a real diff --git a/configure.in b/configure.in index 493ea28364..dab68358a7 100644 --- a/configure.in +++ b/configure.in @@ -75,7 +75,7 @@ dnl Availability of various common functions (non-fatal if missing). AC_CHECK_FUNCS([cfmakeraw regexec uname sched_getaffinity getuid getgid]) dnl Availability of various not common threadsafe functions -AC_CHECK_FUNCS([strerror_r]) +AC_CHECK_FUNCS([strerror_r strtok_r getmntent_r getgrnam_r getpwuid_r]) dnl Availability of various common headers (non-fatal if missing). AC_CHECK_HEADERS([pwd.h paths.h regex.h sys/syslimits.h sys/utsname.h sys/wait.h winsock2.h sched.h termios.h sys/poll.h syslog.h]) diff --git a/proxy/libvirt_proxy.c b/proxy/libvirt_proxy.c index 3b0dc42d95..f3d9edeacb 100644 --- a/proxy/libvirt_proxy.c +++ b/proxy/libvirt_proxy.c @@ -76,9 +76,6 @@ proxyInitXen(void) { priv->handle = -1; priv->xendConfigVersion = -1; - priv->type = -1; - priv->len = -1; - priv->addr = NULL; priv->xshandle = NULL; priv->proxy = -1; diff --git a/qemud/qemud.c b/qemud/qemud.c index 32902e8893..55f31d5ee1 100644 --- a/qemud/qemud.c +++ b/qemud/qemud.c @@ -718,20 +718,18 @@ static int qemudInitPaths(struct qemud_server *server, if (snprintf(server->logDir, PATH_MAX, "%s/log/libvirt/", LOCAL_STATE_DIR) >= PATH_MAX) goto snprintf_error; } else { - struct passwd *pw; + char *userdir = virGetUserDirectory(NULL, uid); - if (!(pw = getpwuid(uid))) { - VIR_ERROR(_("Failed to find user record for uid '%d': %s"), - uid, strerror(errno)); - return -1; - } - - if (snprintf(sockname, maxlen, "@%s/.libvirt/libvirt-sock", pw->pw_dir) >= maxlen) + if (snprintf(sockname, maxlen, "@%s/.libvirt/libvirt-sock", userdir) >= maxlen) { + VIR_FREE(userdir); goto snprintf_error; + } - if (snprintf(server->logDir, PATH_MAX, "%s/.libvirt/log", pw->pw_dir) >= PATH_MAX) + if (snprintf(server->logDir, PATH_MAX, "%s/.libvirt/log", userdir) >= PATH_MAX) { + VIR_FREE(userdir); goto snprintf_error; - + } + VIR_FREE(userdir); } /* !remote */ return 0; @@ -2486,8 +2484,9 @@ remoteReadConfigFile (struct qemud_server *server, const char *filename) if (getuid() != 0) { VIR_WARN0(_("Cannot set group when not running as root")); } else { - struct group *grp = getgrnam(unix_sock_group); - if (!grp) { + char buf[1024]; + struct group grpdata, *grp; + if (getgrnam_r(unix_sock_group, &grpdata, buf, sizeof(buf), &grp) != 0 || !grp) { VIR_ERROR(_("Failed to lookup group '%s'"), unix_sock_group); goto free_and_fail; } diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index efdbaeab3c..7b177063a8 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -310,6 +310,7 @@ virAsprintf; virRun; virSkipSpaces; virKillProcess; +virGetUserDirectory; # uuid.h diff --git a/src/lxc_container.c b/src/lxc_container.c index 03bd2b9ce5..3bf533c133 100644 --- a/src/lxc_container.c +++ b/src/lxc_container.c @@ -414,19 +414,20 @@ static int lxcContainerMountNewFS(virDomainDefPtr vmDef) static int lxcContainerUnmountOldFS(void) { - struct mntent *mntent; + struct mntent mntent; char **mounts = NULL; int nmounts = 0; FILE *procmnt; int i; + char mntbuf[1024]; if (!(procmnt = setmntent("/proc/mounts", "r"))) { virReportSystemError(NULL, errno, "%s", _("failed to read /proc/mounts")); return -1; } - while ((mntent = getmntent(procmnt)) != NULL) { - if (!STRPREFIX(mntent->mnt_dir, "/.oldroot")) + while (getmntent_r(procmnt, &mntent, mntbuf, sizeof(mntbuf)) != NULL) { + if (!STRPREFIX(mntent.mnt_dir, "/.oldroot")) continue; if (VIR_REALLOC_N(mounts, nmounts+1) < 0) { @@ -434,7 +435,7 @@ static int lxcContainerUnmountOldFS(void) lxcError(NULL, NULL, VIR_ERR_NO_MEMORY, NULL); return -1; } - if (!(mounts[nmounts++] = strdup(mntent->mnt_dir))) { + if (!(mounts[nmounts++] = strdup(mntent.mnt_dir))) { endmntent(procmnt); lxcError(NULL, NULL, VIR_ERR_NO_MEMORY, NULL); return -1; diff --git a/src/network_driver.c b/src/network_driver.c index 5d57663841..c546a2b969 100644 --- a/src/network_driver.c +++ b/src/network_driver.c @@ -195,7 +195,6 @@ networkAutostartConfigs(struct network_driver *driver) { static int networkStartup(void) { uid_t uid = geteuid(); - struct passwd *pw; char *base = NULL; int err; @@ -216,19 +215,22 @@ networkStartup(void) { if ((base = strdup (SYSCONF_DIR "/libvirt")) == NULL) goto out_of_memory; } else { - if (!(pw = getpwuid(uid))) { - networkLog(NETWORK_ERR, _("Failed to find user record for uid '%d': %s\n"), - uid, strerror(errno)); - goto out_of_memory; - } + char *userdir = virGetUserDirectory(NULL, uid); + + if (!userdir) + goto error; if (virAsprintf(&driverState->logDir, - "%s/.libvirt/qemu/log", pw->pw_dir) == -1) + "%s/.libvirt/qemu/log", userdir) == -1) { + VIR_FREE(userdir); goto out_of_memory; + } - if (virAsprintf(&base, "%s/.libvirt", pw->pw_dir) == -1) { + if (virAsprintf(&base, "%s/.libvirt", userdir) == -1) { + VIR_FREE(userdir); goto out_of_memory; } + VIR_FREE(userdir); } /* Configuration paths are either ~/.libvirt/qemu/... (session) or diff --git a/src/openvz_driver.c b/src/openvz_driver.c index 4e83bedd3c..d22ea396e4 100644 --- a/src/openvz_driver.c +++ b/src/openvz_driver.c @@ -448,11 +448,12 @@ openvzGenerateContainerVethName(int veid) if ( (ret = openvzReadConfigParam(veid, "NETIF", temp, sizeof(temp))) <= 0) { snprintf(temp, sizeof(temp), "eth0"); } else { + char *saveptr; char *s; int max = 0; /* get maximum interface number (actually, it is the last one) */ - for (s=strtok(temp, ";"); s; s=strtok(NULL, ";")) { + for (s=strtok_r(temp, ";", &saveptr); s; s=strtok_r(NULL, ";", &saveptr)) { int x; if (sscanf(s, "ifname=eth%d", &x) != 1) return NULL; diff --git a/src/qemu_driver.c b/src/qemu_driver.c index d61d7ba76e..3d9a0a25f2 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -382,7 +382,6 @@ next: static int qemudStartup(void) { uid_t uid = geteuid(); - struct passwd *pw; char *base = NULL; char driverConf[PATH_MAX]; @@ -421,27 +420,30 @@ qemudStartup(void) { "%s/run/libvirt/qemu/", LOCAL_STATE_DIR) == -1) goto out_of_memory; } else { - if (!(pw = getpwuid(uid))) { - qemudLog(QEMUD_ERR, _("Failed to find user record for uid '%d': %s\n"), - uid, strerror(errno)); + char *userdir = virGetUserDirectory(NULL, uid); + if (!userdir) goto error; - } if (virAsprintf(&qemu_driver->logDir, - "%s/.libvirt/qemu/log", pw->pw_dir) == -1) + "%s/.libvirt/qemu/log", userdir) == -1) { + VIR_FREE(userdir); goto out_of_memory; + } - if (virAsprintf(&base, "%s/.libvirt", pw->pw_dir) == -1) + if (virAsprintf(&base, "%s/.libvirt", userdir) == -1) { + VIR_FREE(userdir); goto out_of_memory; + } + VIR_FREE(userdir); if (virAsprintf(&qemu_driver->stateDir, "%s/qemu/run", base) == -1) goto out_of_memory; } if (virFileMakePath(qemu_driver->stateDir) < 0) { - qemudLog(QEMUD_ERR, _("Failed to create state dir '%s': %s\n"), - qemu_driver->stateDir, strerror(errno)); - goto error; + qemudLog(QEMUD_ERR, _("Failed to create state dir '%s': %s\n"), + qemu_driver->stateDir, strerror(errno)); + goto error; } /* Configuration paths are either ~/.libvirt/qemu/... (session) or diff --git a/src/remote_internal.c b/src/remote_internal.c index 51a40b8741..93b27afffe 100644 --- a/src/remote_internal.c +++ b/src/remote_internal.c @@ -605,19 +605,16 @@ doRemoteOpen (virConnectPtr conn, case trans_unix: { if (!sockname) { if (flags & VIR_DRV_OPEN_REMOTE_USER) { - struct passwd *pw; - uid_t uid = getuid(); + char *userdir = virGetUserDirectory(conn, getuid()); - if (!(pw = getpwuid(uid))) { - virReportSystemError(conn, errno, - _("unable to lookup user '%d'"), - uid); + if (!userdir) goto failed; - } - if (virAsprintf(&sockname, "@%s" LIBVIRTD_USER_UNIX_SOCKET, pw->pw_dir) < 0) + if (virAsprintf(&sockname, "@%s" LIBVIRTD_USER_UNIX_SOCKET, userdir) < 0) { + VIR_FREE(userdir); goto out_of_memory; - + } + VIR_FREE(userdir); } else { if (flags & VIR_DRV_OPEN_REMOTE_RO) sockname = strdup (LIBVIRTD_PRIV_UNIX_SOCKET_RO); diff --git a/src/storage_backend_fs.c b/src/storage_backend_fs.c index 0dd134cf82..544f4e2f6b 100644 --- a/src/storage_backend_fs.c +++ b/src/storage_backend_fs.c @@ -385,7 +385,8 @@ static int virStorageBackendFileSystemIsMounted(virConnectPtr conn, virStoragePoolObjPtr pool) { FILE *mtab; - struct mntent *ent; + struct mntent ent; + char buf[1024]; if ((mtab = fopen(_PATH_MOUNTED, "r")) == NULL) { virReportSystemError(conn, errno, @@ -394,8 +395,8 @@ virStorageBackendFileSystemIsMounted(virConnectPtr conn, return -1; } - while ((ent = getmntent(mtab)) != NULL) { - if (STREQ(ent->mnt_dir, pool->def->target.path)) { + while ((getmntent_r(mtab, &ent, buf, sizeof(buf))) != NULL) { + if (STREQ(ent.mnt_dir, pool->def->target.path)) { fclose(mtab); return 1; } diff --git a/src/storage_driver.c b/src/storage_driver.c index 6ca5c1e5ba..a4560611a9 100644 --- a/src/storage_driver.c +++ b/src/storage_driver.c @@ -108,7 +108,6 @@ storageDriverAutostart(virStorageDriverStatePtr driver) { static int storageDriverStartup(void) { uid_t uid = geteuid(); - struct passwd *pw; char *base = NULL; char driverConf[PATH_MAX]; @@ -125,16 +124,17 @@ storageDriverStartup(void) { if ((base = strdup (SYSCONF_DIR "/libvirt")) == NULL) goto out_of_memory; } else { - if (!(pw = getpwuid(uid))) { - storageLog("Failed to find user record for uid '%d': %s", - uid, strerror(errno)); - goto out_of_memory; - } + char *userdir = virGetUserDirectory(NULL, uid); + + if (!userdir) + goto error; - if (virAsprintf(&base, "%s/.libvirt", pw->pw_dir) == -1) { + if (virAsprintf(&base, "%s/.libvirt", userdir) == -1) { storageLog("out of memory in virAsprintf"); + VIR_FREE(userdir); goto out_of_memory; } + VIR_FREE(userdir); } /* Configuration paths are either ~/.libvirt/storage/... (session) or diff --git a/src/uml_driver.c b/src/uml_driver.c index 2af2305538..65bbbe666b 100644 --- a/src/uml_driver.c +++ b/src/uml_driver.c @@ -309,9 +309,9 @@ cleanup: static int umlStartup(void) { uid_t uid = geteuid(); - struct passwd *pw; char *base = NULL; char driverConf[PATH_MAX]; + char *userdir = NULL; if (VIR_ALLOC(uml_driver) < 0) return -1; @@ -325,11 +325,9 @@ umlStartup(void) { /* Don't have a dom0 so start from 1 */ uml_driver->nextvmid = 1; - if (!(pw = getpwuid(uid))) { - umlLog(VIR_LOG_ERROR, _("Failed to find user record for uid '%d': %s\n"), - uid, strerror(errno)); + userdir = virGetUserDirectory(NULL, uid); + if (!userdir) goto error; - } if (!uid) { if (virAsprintf(¨_driver->logDir, @@ -339,16 +337,17 @@ umlStartup(void) { if ((base = strdup (SYSCONF_DIR "/libvirt")) == NULL) goto out_of_memory; } else { + if (virAsprintf(¨_driver->logDir, - "%s/.libvirt/uml/log", pw->pw_dir) == -1) + "%s/.libvirt/uml/log", userdir) == -1) goto out_of_memory; - if (virAsprintf(&base, "%s/.libvirt", pw->pw_dir) == -1) + if (virAsprintf(&base, "%s/.libvirt", userdir) == -1) goto out_of_memory; } if (virAsprintf(¨_driver->monitorDir, - "%s/.uml", pw->pw_dir) == -1) + "%s/.uml", userdir) == -1) goto out_of_memory; /* Configuration paths are either ~/.libvirt/uml/... (session) or @@ -403,6 +402,8 @@ umlStartup(void) { umlAutostartConfigs(uml_driver); umlDriverUnlock(uml_driver); + VIR_FREE(userdir); + return 0; out_of_memory: @@ -410,6 +411,7 @@ out_of_memory: "%s", _("umlStartup: out of memory\n")); error: + VIR_FREE(userdir); VIR_FREE(base); umlDriverUnlock(uml_driver); umlShutdown(); diff --git a/src/util.c b/src/util.c index 7fe4ad3c3c..e4524d9517 100644 --- a/src/util.c +++ b/src/util.c @@ -49,6 +49,9 @@ #include #endif #include +#ifdef HAVE_GETPWUID_R +#include +#endif #include "virterror_internal.h" #include "logging.h" @@ -1431,3 +1434,37 @@ int virKillProcess(pid_t pid, int sig) return kill(pid, sig); #endif } + + +#ifdef HAVE_GETPWUID_R +char *virGetUserDirectory(virConnectPtr conn, + uid_t uid) +{ + char *strbuf; + char *ret; + struct passwd pwbuf; + struct passwd *pw; + size_t strbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); + + if (VIR_ALLOC_N(strbuf, strbuflen) < 0) { + virReportOOMError(conn); + return NULL; + } + + if (getpwuid_r(uid, &pwbuf, strbuf, strbuflen, &pw) != 0) { + virReportSystemError(conn, errno, + _("Failed to find user record for uid '%d'"), + uid); + VIR_FREE(strbuf); + return NULL; + } + + ret = strdup(pw->pw_dir); + + VIR_FREE(strbuf); + if (!ret) + virReportOOMError(conn); + + return ret; +} +#endif diff --git a/src/util.h b/src/util.h index 81cfad6b01..a94212e016 100644 --- a/src/util.h +++ b/src/util.h @@ -172,4 +172,9 @@ char *virGetHostname(void); int virKillProcess(pid_t pid, int sig); +#ifdef HAVE_GETPWUID_R +char *virGetUserDirectory(virConnectPtr conn, + uid_t uid); +#endif + #endif /* __VIR_UTIL_H__ */ diff --git a/src/xen_unified.c b/src/xen_unified.c index 95968150be..70d8c7d2c6 100644 --- a/src/xen_unified.c +++ b/src/xen_unified.c @@ -284,9 +284,6 @@ xenUnifiedOpen (virConnectPtr conn, virConnectAuthPtr auth, int flags) priv->handle = -1; priv->xendConfigVersion = -1; - priv->type = -1; - priv->len = -1; - priv->addr = NULL; priv->xshandle = NULL; priv->proxy = -1; diff --git a/src/xen_unified.h b/src/xen_unified.h index 569c7babc8..3123bd71de 100644 --- a/src/xen_unified.h +++ b/src/xen_unified.h @@ -142,13 +142,11 @@ struct _xenUnifiedPrivate { int xendConfigVersion; /* XenD config version */ - /* XXX This code is not IPv6 aware. */ /* connection to xend */ - int type; /* PF_UNIX or PF_INET */ - int len; /* length of addr */ - struct sockaddr *addr; /* type of address used */ - struct sockaddr_un addr_un; /* the unix address */ - struct sockaddr_in addr_in; /* the inet address */ + struct sockaddr_storage addr; + socklen_t addrlen; + int addrfamily; + int addrprotocol; /* Keep track of the drivers which opened. We keep a yes/no flag * here for each driver, corresponding to the array drivers in diff --git a/src/xend_internal.c b/src/xend_internal.c index 8c6e6524e7..321dfdf14a 100644 --- a/src/xend_internal.c +++ b/src/xend_internal.c @@ -75,30 +75,6 @@ #define XEND_CONFIG_MIN_VERS_PVFB_NEWCONF 3 #endif -/** - * xend_connection_type: - * - * The connection to the Xen Daemon can be done either though a normal TCP - * socket or a local domain direct connection. - */ -enum xend_connection_type { - XEND_DOMAIN, - XEND_TCP, -}; - -/** - * xend: - * - * Structure associated to a connection to a Xen daemon - */ -struct xend { - int len; - int type; - struct sockaddr *addr; - struct sockaddr_un addr_un; - struct sockaddr_in addr_in; -}; - #ifndef PROXY static int @@ -146,7 +122,7 @@ do_connect(virConnectPtr xend) int no_slow_start = 1; xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) xend->privateData; - s = socket(priv->type, SOCK_STREAM, 0); + s = socket(priv->addrfamily, SOCK_STREAM, priv->addrprotocol); if (s == -1) { virXendError(xend, VIR_ERR_INTERNAL_ERROR, "%s", _("failed to create a socket")); @@ -160,7 +136,7 @@ do_connect(virConnectPtr xend) sizeof(no_slow_start)); - if (connect(s, priv->addr, priv->len) == -1) { + if (connect(s, (struct sockaddr *)&priv->addr, priv->addrlen) == -1) { serrno = errno; close(s); errno = serrno; @@ -774,18 +750,16 @@ xenDaemonOpen_unix(virConnectPtr conn, const char *path) if ((conn == NULL) || (path == NULL)) return (-1); - addr = &priv->addr_un; + memset(&priv->addr, 0, sizeof(priv->addr)); + priv->addrfamily = AF_UNIX; + priv->addrprotocol = PF_UNIX; + priv->addrlen = sizeof(struct sockaddr_un); + + addr = (struct sockaddr_un *)&priv->addr; addr->sun_family = AF_UNIX; memset(addr->sun_path, 0, sizeof(addr->sun_path)); strncpy(addr->sun_path, path, sizeof(addr->sun_path)); - priv->len = sizeof(addr->sun_family) + strlen(addr->sun_path); - if ((unsigned int) priv->len > sizeof(addr->sun_path)) - priv->len = sizeof(addr->sun_path); - - priv->addr = (struct sockaddr *) addr; - priv->type = PF_UNIX; - return (0); } @@ -802,38 +776,71 @@ xenDaemonOpen_unix(virConnectPtr conn, const char *path) * Returns 0 in case of success, -1 in case of error. */ static int -xenDaemonOpen_tcp(virConnectPtr conn, const char *host, int port) +xenDaemonOpen_tcp(virConnectPtr conn, const char *host, const char *port) { - struct in_addr ip; - struct hostent *pent; xenUnifiedPrivatePtr priv; + struct addrinfo *res, *r; + struct addrinfo hints; + int saved_errno = EINVAL; + int ret; - if ((conn == NULL) || (host == NULL) || (port <= 0)) + if ((conn == NULL) || (host == NULL) || (port == NULL)) return (-1); priv = (xenUnifiedPrivatePtr) conn->privateData; - pent = gethostbyname(host); - if (pent == NULL) { - if (inet_aton(host, &ip) == 0) { - virXendError(NULL, VIR_ERR_UNKNOWN_HOST, - _("gethostbyname failed: %s"), host); - errno = ESRCH; - return (-1); + priv->addrlen = 0; + memset(&priv->addr, 0, sizeof(priv->addr)); + + // http://people.redhat.com/drepper/userapi-ipv6.html + memset (&hints, 0, sizeof hints); + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_ADDRCONFIG; + + ret = getaddrinfo (host, port, &hints, &res); + if (ret != 0) { + virXendError(NULL, VIR_ERR_UNKNOWN_HOST, + _("unable to resolve hostname '%s': %s"), + host, gai_strerror (ret)); + return -1; + } + + /* Try to connect to each returned address in turn. */ + for (r = res; r; r = r->ai_next) { + int sock; + + sock = socket (r->ai_family, SOCK_STREAM, r->ai_protocol); + if (sock == -1) { + saved_errno = errno; + continue; } - } else { - memcpy(&ip, pent->h_addr_list[0], sizeof(ip)); + + if (connect (sock, r->ai_addr, r->ai_addrlen) == -1) { + saved_errno = errno; + close (sock); + continue; + } + + priv->addrlen = r->ai_addrlen; + priv->addrfamily = r->ai_family; + priv->addrprotocol = r->ai_protocol; + memcpy(&priv->addr, + r->ai_addr, + r->ai_addrlen); + close(sock); + break; } - priv->len = sizeof(struct sockaddr_in); - priv->addr = (struct sockaddr *) &priv->addr_in; - priv->type = PF_INET; + freeaddrinfo (res); - priv->addr_in.sin_family = AF_INET; - priv->addr_in.sin_port = htons(port); - memcpy(&priv->addr_in.sin_addr, &ip, sizeof(ip)); + if (!priv->addrlen) { + virReportSystemError(conn, saved_errno, + _("unable to connect to '%s:%s'"), + host, port); + return -1; + } - return (0); + return 0; } @@ -2750,14 +2757,18 @@ xenDaemonOpen(virConnectPtr conn, /* * try though http on port 8000 */ - ret = xenDaemonOpen_tcp(conn, "localhost", 8000); + ret = xenDaemonOpen_tcp(conn, "localhost", "8000"); if (ret < 0) goto failed; ret = xend_detect_config_version(conn); if (ret == -1) goto failed; } else if (STRCASEEQ (conn->uri->scheme, "http")) { - ret = xenDaemonOpen_tcp(conn, conn->uri->server, conn->uri->port); + char *port; + if (virAsprintf(&port, "%d", conn->uri->port) == -1) + goto failed; + ret = xenDaemonOpen_tcp(conn, conn->uri->server, port); + VIR_FREE(port); if (ret < 0) goto failed; ret = xend_detect_config_version(conn); -- 2.47.2