Replace all uses of strerror() by ovs_strerror(), for thread safety.
[sliver-openvswitch.git] / lib / netlink-socket.c
index 3bdbbd7..dfe39ac 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "netlink-socket.h"
-#include <assert.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <stdlib.h>
@@ -60,8 +59,7 @@ static void log_nlmsg(const char *function, int error,
 \f
 /* Netlink sockets. */
 
-struct nl_sock
-{
+struct nl_sock {
     int fd;
     uint32_t next_seq;
     uint32_t pid;
@@ -101,7 +99,7 @@ nl_sock_create(int protocol, struct nl_sock **sockp)
         max_iovs = sysconf(_SC_UIO_MAXIOV);
         if (max_iovs < _XOPEN_IOV_MAX) {
             if (max_iovs == -1 && errno) {
-                VLOG_WARN("sysconf(_SC_UIO_MAXIOV): %s", strerror(errno));
+                VLOG_WARN("sysconf(_SC_UIO_MAXIOV): %s", ovs_strerror(errno));
             }
             max_iovs = _XOPEN_IOV_MAX;
         } else if (max_iovs > MAX_IOVS) {
@@ -112,14 +110,11 @@ nl_sock_create(int protocol, struct nl_sock **sockp)
     }
 
     *sockp = NULL;
-    sock = malloc(sizeof *sock);
-    if (sock == NULL) {
-        return ENOMEM;
-    }
+    sock = xmalloc(sizeof *sock);
 
     sock->fd = socket(AF_NETLINK, SOCK_RAW, protocol);
     if (sock->fd < 0) {
-        VLOG_ERR("fcntl: %s", strerror(errno));
+        VLOG_ERR("fcntl: %s", ovs_strerror(errno));
         goto error;
     }
     sock->protocol = protocol;
@@ -129,8 +124,12 @@ nl_sock_create(int protocol, struct nl_sock **sockp)
     rcvbuf = 1024 * 1024;
     if (setsockopt(sock->fd, SOL_SOCKET, SO_RCVBUFFORCE,
                    &rcvbuf, sizeof rcvbuf)) {
-        VLOG_WARN_RL(&rl, "setting %d-byte socket receive buffer failed (%s)",
-                     rcvbuf, strerror(errno));
+        /* Only root can use SO_RCVBUFFORCE.  Everyone else gets EPERM.
+         * Warn only if the failure is therefore unexpected. */
+        if (errno != EPERM) {
+            VLOG_WARN_RL(&rl, "setting %d-byte socket receive buffer failed "
+                         "(%s)", rcvbuf, ovs_strerror(errno));
+        }
     }
 
     retval = get_socket_rcvbuf(sock->fd);
@@ -145,14 +144,14 @@ nl_sock_create(int protocol, struct nl_sock **sockp)
     remote.nl_family = AF_NETLINK;
     remote.nl_pid = 0;
     if (connect(sock->fd, (struct sockaddr *) &remote, sizeof remote) < 0) {
-        VLOG_ERR("connect(0): %s", strerror(errno));
+        VLOG_ERR("connect(0): %s", ovs_strerror(errno));
         goto error;
     }
 
     /* Obtain pid assigned by kernel. */
     local_size = sizeof local;
     if (getsockname(sock->fd, (struct sockaddr *) &local, &local_size) < 0) {
-        VLOG_ERR("getsockname: %s", strerror(errno));
+        VLOG_ERR("getsockname: %s", ovs_strerror(errno));
         goto error;
     }
     if (local_size < sizeof local || local.nl_family != AF_NETLINK) {
@@ -223,7 +222,7 @@ nl_sock_join_mcgroup(struct nl_sock *sock, unsigned int multicast_group)
     if (setsockopt(sock->fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP,
                    &multicast_group, sizeof multicast_group) < 0) {
         VLOG_WARN("could not join multicast group %u (%s)",
-                  multicast_group, strerror(errno));
+                  multicast_group, ovs_strerror(errno));
         return errno;
     }
     return 0;
@@ -242,11 +241,11 @@ nl_sock_join_mcgroup(struct nl_sock *sock, unsigned int multicast_group)
 int
 nl_sock_leave_mcgroup(struct nl_sock *sock, unsigned int multicast_group)
 {
-    assert(!sock->dump);
+    ovs_assert(!sock->dump);
     if (setsockopt(sock->fd, SOL_NETLINK, NETLINK_DROP_MEMBERSHIP,
                    &multicast_group, sizeof multicast_group) < 0) {
         VLOG_WARN("could not leave multicast group %u (%s)",
-                  multicast_group, strerror(errno));
+                  multicast_group, ovs_strerror(errno));
         return errno;
     }
     return 0;
@@ -333,7 +332,7 @@ nl_sock_recv__(struct nl_sock *sock, struct ofpbuf *buf, bool wait)
     struct msghdr msg;
     ssize_t retval;
 
-    assert(buf->allocated >= sizeof *nlmsghdr);
+    ovs_assert(buf->allocated >= sizeof *nlmsghdr);
     ofpbuf_clear(buf);
 
     iov[0].iov_base = buf->base;
@@ -528,7 +527,7 @@ nl_sock_transact_multiple__(struct nl_sock *sock,
             }
             if (txn->error) {
                 VLOG_DBG_RL(&rl, "received NAK error=%d (%s)",
-                            error, strerror(txn->error));
+                            error, ovs_strerror(txn->error));
             }
         } else {
             txn->error = 0;
@@ -630,7 +629,7 @@ nl_sock_transact_multiple(struct nl_sock *sock,
         if (error == ENOBUFS) {
             VLOG_DBG_RL(&rl, "receive buffer overflow, resending request");
         } else if (error) {
-            VLOG_ERR_RL(&rl, "transaction error (%s)", strerror(error));
+            VLOG_ERR_RL(&rl, "transaction error (%s)", ovs_strerror(error));
             nl_sock_record_errors__(transactions, n, error);
         }
     }
@@ -683,7 +682,7 @@ nl_sock_transact(struct nl_sock *sock, const struct ofpbuf *request,
     struct nl_transaction *transactionp;
     struct nl_transaction transaction;
 
-    transaction.request = (struct ofpbuf *) request;
+    transaction.request = CONST_CAST(struct ofpbuf *, request);
     transaction.reply = replyp ? ofpbuf_new(1024) : NULL;
     transactionp = &transaction;
 
@@ -816,7 +815,7 @@ nl_dump_recv(struct nl_dump *dump)
 
     if (nl_msg_nlmsgerr(&dump->buffer, &retval)) {
         VLOG_INFO_RL(&rl, "netlink dump request error (%s)",
-                     strerror(retval));
+                     ovs_strerror(retval));
         return retval && retval != EAGAIN ? retval : EPROTO;
     }
 
@@ -881,7 +880,7 @@ nl_dump_done(struct nl_dump *dump)
     while (!dump->status) {
         struct ofpbuf reply;
         if (!nl_dump_next(dump, &reply)) {
-            assert(dump->status);
+            ovs_assert(dump->status);
         }
     }
 
@@ -1100,7 +1099,7 @@ nl_lookup_genl_family(const char *name, int *number)
         }
         ofpbuf_delete(reply);
 
-        assert(*number != 0);
+        ovs_assert(*number != 0);
     }
     return *number > 0 ? 0 : -*number;
 }
@@ -1188,7 +1187,7 @@ nlmsg_to_string(const struct ofpbuf *buffer, int protocol)
             if (e) {
                 ds_put_format(&ds, " error(%d", e->error);
                 if (e->error < 0) {
-                    ds_put_format(&ds, "(%s)", strerror(-e->error));
+                    ds_put_format(&ds, "(%s)", ovs_strerror(-e->error));
                 }
                 ds_put_cstr(&ds, ", in-reply-to(");
                 nlmsghdr_to_string(&e->msg, protocol, &ds);
@@ -1201,7 +1200,7 @@ nlmsg_to_string(const struct ofpbuf *buffer, int protocol)
             if (error) {
                 ds_put_format(&ds, " done(%d", *error);
                 if (*error < 0) {
-                    ds_put_format(&ds, "(%s)", strerror(-*error));
+                    ds_put_format(&ds, "(%s)", ovs_strerror(-*error));
                 }
                 ds_put_cstr(&ds, ")");
             } else {
@@ -1233,6 +1232,6 @@ log_nlmsg(const char *function, int error,
 
     ofpbuf_use_const(&buffer, message, size);
     nlmsg = nlmsg_to_string(&buffer, protocol);
-    VLOG_DBG_RL(&rl, "%s (%s): %s", function, strerror(error), nlmsg);
+    VLOG_DBG_RL(&rl, "%s (%s): %s", function, ovs_strerror(error), nlmsg);
     free(nlmsg);
 }