X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fsocket-util.c;h=7f34ea2e939ea86b0e27e482b5ba4ab477e106a1;hb=77d14d9c7f9ce7245eff56aacd420646577892d0;hp=906b970a91e134345f0b76cf45cb78fefb888c7d;hpb=4816a18f33380a33d381b77d41df39113c94500d;p=sliver-openvswitch.git diff --git a/lib/socket-util.c b/lib/socket-util.c index 906b970a9..7f34ea2e9 100644 --- a/lib/socket-util.c +++ b/lib/socket-util.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -72,11 +73,11 @@ set_nonblocking(int fd) if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) != -1) { return 0; } else { - VLOG_ERR("fcntl(F_SETFL) failed: %s", strerror(errno)); + VLOG_ERR("fcntl(F_SETFL) failed: %s", ovs_strerror(errno)); return errno; } } else { - VLOG_ERR("fcntl(F_GETFL) failed: %s", strerror(errno)); + VLOG_ERR("fcntl(F_GETFL) failed: %s", ovs_strerror(errno)); return errno; } } @@ -132,8 +133,10 @@ rlim_is_finite(rlim_t limit) int get_max_fds(void) { - static int max_fds = -1; - if (max_fds < 0) { + static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; + static int max_fds; + + if (ovsthread_once_start(&once)) { struct rlimit r; if (!getrlimit(RLIMIT_NOFILE, &r) && rlim_is_finite(r.rlim_cur)) { max_fds = r.rlim_cur; @@ -141,7 +144,9 @@ get_max_fds(void) VLOG_WARN("failed to obtain fd limit, defaulting to 1024"); max_fds = 1024; } + ovsthread_once_done(&once); } + return max_fds; } @@ -197,11 +202,14 @@ lookup_hostname(const char *host_name, struct in_addr *addr) switch (getaddrinfo(host_name, NULL, &hints, &result)) { case 0: - *addr = ((struct sockaddr_in *) result->ai_addr)->sin_addr; + *addr = ALIGNED_CAST(struct sockaddr_in *, + result->ai_addr)->sin_addr; freeaddrinfo(result); return 0; +#ifdef EAI_ADDRFAMILY case EAI_ADDRFAMILY: +#endif case EAI_NONAME: case EAI_SERVICE: return ENOENT; @@ -220,8 +228,10 @@ lookup_hostname(const char *host_name, struct in_addr *addr) case EAI_MEMORY: return ENOMEM; +#ifdef EAI_NODATA case EAI_NODATA: return ENXIO; +#endif case EAI_SYSTEM: return errno; @@ -255,7 +265,7 @@ check_connection_completion(int fd) } return 0; } else if (retval < 0) { - VLOG_ERR_RL(&rl, "poll: %s", strerror(errno)); + VLOG_ERR_RL(&rl, "poll: %s", ovs_strerror(errno)); return errno; } else { return EAGAIN; @@ -448,7 +458,8 @@ make_unix_socket(int style, bool nonblock, int dirfd; if (unlink(bind_path) && errno != ENOENT) { - VLOG_WARN("unlinking \"%s\": %s\n", bind_path, strerror(errno)); + VLOG_WARN("unlinking \"%s\": %s\n", + bind_path, ovs_strerror(errno)); } fatal_signal_add_file_to_unlink(bind_path); @@ -598,7 +609,7 @@ inet_open_active(int style, const char *target, uint16_t default_port, /* Create non-blocking socket. */ fd = socket(AF_INET, style, 0); if (fd < 0) { - VLOG_ERR("%s: socket: %s", target, strerror(errno)); + VLOG_ERR("%s: socket: %s", target, ovs_strerror(errno)); error = errno; goto exit; } @@ -612,7 +623,7 @@ inet_open_active(int style, const char *target, uint16_t default_port, * connect(), the handshake SYN frames will be sent with a TOS of 0. */ error = set_dscp(fd, dscp); if (error) { - VLOG_ERR("%s: socket: %s", target, strerror(error)); + VLOG_ERR("%s: socket: %s", target, ovs_strerror(error)); goto exit; } @@ -724,7 +735,7 @@ inet_open_passive(int style, const char *target, int default_port, fd = socket(AF_INET, style, 0); if (fd < 0) { error = errno; - VLOG_ERR("%s: socket: %s", target, strerror(error)); + VLOG_ERR("%s: socket: %s", target, ovs_strerror(error)); return -error; } error = set_nonblocking(fd); @@ -734,14 +745,15 @@ inet_open_passive(int style, const char *target, int default_port, if (style == SOCK_STREAM && setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes) < 0) { error = errno; - VLOG_ERR("%s: setsockopt(SO_REUSEADDR): %s", target, strerror(error)); + VLOG_ERR("%s: setsockopt(SO_REUSEADDR): %s", + target, ovs_strerror(error)); goto error; } /* Bind. */ if (bind(fd, (struct sockaddr *) &sin, sizeof sin) < 0) { error = errno; - VLOG_ERR("%s: bind: %s", target, strerror(error)); + VLOG_ERR("%s: bind: %s", target, ovs_strerror(error)); goto error; } @@ -750,14 +762,14 @@ inet_open_passive(int style, const char *target, int default_port, * connect(), the handshake SYN frames will be sent with a TOS of 0. */ error = set_dscp(fd, dscp); if (error) { - VLOG_ERR("%s: socket: %s", target, strerror(error)); + VLOG_ERR("%s: socket: %s", target, ovs_strerror(error)); goto error; } /* Listen. */ if (style == SOCK_STREAM && listen(fd, 10) < 0) { error = errno; - VLOG_ERR("%s: listen: %s", target, strerror(error)); + VLOG_ERR("%s: listen: %s", target, ovs_strerror(error)); goto error; } @@ -766,7 +778,7 @@ inet_open_passive(int style, const char *target, int default_port, socklen_t sin_len = sizeof sin; if (getsockname(fd, (struct sockaddr *) &sin, &sin_len) < 0) { error = errno; - VLOG_ERR("%s: getsockname: %s", target, strerror(error)); + VLOG_ERR("%s: getsockname: %s", target, ovs_strerror(error)); goto error; } if (sin.sin_family != AF_INET || sin_len != sizeof sin) { @@ -796,15 +808,19 @@ error: int get_null_fd(void) { - static int null_fd = -1; - if (null_fd < 0) { + static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; + static int null_fd; + + if (ovsthread_once_start(&once)) { null_fd = open("/dev/null", O_RDWR); if (null_fd < 0) { int error = errno; - VLOG_ERR("could not open /dev/null: %s", strerror(error)); - return -error; + VLOG_ERR("could not open /dev/null: %s", ovs_strerror(error)); + null_fd = -error; } + ovsthread_once_done(&once); } + return null_fd; } @@ -869,13 +885,13 @@ fsync_parent_dir(const char *file_name) * really an error. */ } else { error = errno; - VLOG_ERR("%s: fsync failed (%s)", dir, strerror(error)); + VLOG_ERR("%s: fsync failed (%s)", dir, ovs_strerror(error)); } } close(fd); } else { error = errno; - VLOG_ERR("%s: open failed (%s)", dir, strerror(error)); + VLOG_ERR("%s: open failed (%s)", dir, ovs_strerror(error)); } free(dir); @@ -913,7 +929,7 @@ void xpipe(int fds[2]) { if (pipe(fds)) { - VLOG_FATAL("failed to create pipe (%s)", strerror(errno)); + VLOG_FATAL("failed to create pipe (%s)", ovs_strerror(errno)); } } @@ -929,7 +945,7 @@ void xsocketpair(int domain, int type, int protocol, int fds[2]) { if (socketpair(domain, type, protocol, fds)) { - VLOG_FATAL("failed to create socketpair (%s)", strerror(errno)); + VLOG_FATAL("failed to create socketpair (%s)", ovs_strerror(errno)); } } @@ -944,7 +960,7 @@ getsockopt_int(int fd, int level, int option, const char *optname, int *valuep) len = sizeof value; if (getsockopt(fd, level, option, &value, &len)) { error = errno; - VLOG_ERR_RL(&rl, "getsockopt(%s): %s", optname, strerror(error)); + VLOG_ERR_RL(&rl, "getsockopt(%s): %s", optname, ovs_strerror(error)); } else if (len != sizeof value) { error = EINVAL; VLOG_ERR_RL(&rl, "getsockopt(%s): value is %u bytes (expected %zu)", @@ -1072,7 +1088,7 @@ describe_fd(int fd) ds_init(&string); if (fstat(fd, &s)) { - ds_put_format(&string, "fstat failed (%s)", strerror(errno)); + ds_put_format(&string, "fstat failed (%s)", ovs_strerror(errno)); } else if (S_ISSOCK(s.st_mode)) { describe_sockaddr(&string, fd, getsockname); ds_put_cstr(&string, "<->"); @@ -1312,7 +1328,7 @@ recv_data_and_fds(int sock, goto error; } else { size_t n_fds = (p->cmsg_len - CMSG_LEN(0)) / sizeof *fds; - const int *fds_data = (const int *) CMSG_DATA(p); + const int *fds_data = ALIGNED_CAST(const int *, CMSG_DATA(p)); ovs_assert(n_fds > 0); if (n_fds > SOUTIL_MAX_FDS) { @@ -1338,3 +1354,42 @@ error: *n_fdsp = 0; return EPROTO; } + +/* Calls ioctl() on an AF_INET sock, passing the specified 'command' and + * 'arg'. Returns 0 if successful, otherwise a positive errno value. */ +int +af_inet_ioctl(unsigned long int command, const void *arg) +{ + static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; + static int sock; + + if (ovsthread_once_start(&once)) { + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) { + sock = -errno; + VLOG_ERR("failed to create inet socket: %s", ovs_strerror(errno)); + } + ovsthread_once_done(&once); + } + + return (sock < 0 ? -sock + : ioctl(sock, command, arg) == -1 ? errno + : 0); +} + +int +af_inet_ifreq_ioctl(const char *name, struct ifreq *ifr, unsigned long int cmd, + const char *cmd_name) +{ + int error; + + ovs_strzcpy(ifr->ifr_name, name, sizeof ifr->ifr_name); + error = af_inet_ioctl(cmd, ifr); + if (error) { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20); + VLOG_DBG_RL(&rl, "%s: ioctl(%s) failed: %s", name, cmd_name, + ovs_strerror(error)); + } + return error; +} +