mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 11:22:23 +00:00
Remove use of non-reentrant POSIX apis
This commit is contained in:
parent
d0eab955c2
commit
1b745219c7
17
ChangeLog
17
ChangeLog
@ -1,3 +1,18 @@
|
||||
Thu Jan 21 19:04:12 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
|
||||
|
||||
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 <meyering@redhat.com>
|
||||
|
||||
xm_internal.c: fix locking bug: s/Lock/Unlock/
|
||||
@ -44,7 +59,7 @@ Thu Jan 22 09:51:29 PST 2009 John Levon <john.levon@sun.com>
|
||||
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 <berrange@redhat.com>
|
||||
Thu Jan 22 18:18:12 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
|
||||
|
||||
Missing test case fix up from Xen threadsafety changes
|
||||
* tests/sexpr2xmltest.c, tests/Makefile.am: Pass a real
|
||||
|
@ -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])
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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", userdir) >= maxlen) {
|
||||
VIR_FREE(userdir);
|
||||
goto snprintf_error;
|
||||
}
|
||||
|
||||
if (snprintf(sockname, maxlen, "@%s/.libvirt/libvirt-sock", pw->pw_dir) >= maxlen)
|
||||
if (snprintf(server->logDir, PATH_MAX, "%s/.libvirt/log", userdir) >= PATH_MAX) {
|
||||
VIR_FREE(userdir);
|
||||
goto snprintf_error;
|
||||
|
||||
if (snprintf(server->logDir, PATH_MAX, "%s/.libvirt/log", pw->pw_dir) >= PATH_MAX)
|
||||
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;
|
||||
}
|
||||
|
@ -310,6 +310,7 @@ virAsprintf;
|
||||
virRun;
|
||||
virSkipSpaces;
|
||||
virKillProcess;
|
||||
virGetUserDirectory;
|
||||
|
||||
|
||||
# uuid.h
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
goto out_of_memory;
|
||||
|
||||
if (virAsprintf(&base, "%s/.libvirt", pw->pw_dir) == -1) {
|
||||
"%s/.libvirt/qemu/log", userdir) == -1) {
|
||||
VIR_FREE(userdir);
|
||||
goto out_of_memory;
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 (virAsprintf(&base, "%s/.libvirt", pw->pw_dir) == -1) {
|
||||
if (!userdir)
|
||||
goto error;
|
||||
|
||||
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
|
||||
|
@ -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();
|
||||
|
37
src/util.c
37
src/util.c
@ -49,6 +49,9 @@
|
||||
#include <paths.h>
|
||||
#endif
|
||||
#include <netdb.h>
|
||||
#ifdef HAVE_GETPWUID_R
|
||||
#include <pwd.h>
|
||||
#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
|
||||
|
@ -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__ */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
} else {
|
||||
memcpy(&ip, pent->h_addr_list[0], sizeof(ip));
|
||||
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;
|
||||
}
|
||||
|
||||
priv->len = sizeof(struct sockaddr_in);
|
||||
priv->addr = (struct sockaddr *) &priv->addr_in;
|
||||
priv->type = PF_INET;
|
||||
/* Try to connect to each returned address in turn. */
|
||||
for (r = res; r; r = r->ai_next) {
|
||||
int sock;
|
||||
|
||||
priv->addr_in.sin_family = AF_INET;
|
||||
priv->addr_in.sin_port = htons(port);
|
||||
memcpy(&priv->addr_in.sin_addr, &ip, sizeof(ip));
|
||||
sock = socket (r->ai_family, SOCK_STREAM, r->ai_protocol);
|
||||
if (sock == -1) {
|
||||
saved_errno = errno;
|
||||
continue;
|
||||
}
|
||||
|
||||
return (0);
|
||||
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;
|
||||
}
|
||||
|
||||
freeaddrinfo (res);
|
||||
|
||||
if (!priv->addrlen) {
|
||||
virReportSystemError(conn, saved_errno,
|
||||
_("unable to connect to '%s:%s'"),
|
||||
host, port);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user