]> arthur.barton.de Git - netatalk.git/commitdiff
Merge branch-2-1
authorFrank Lahm <franklahm@googlemail.com>
Tue, 16 Nov 2010 10:15:32 +0000 (11:15 +0100)
committerFrank Lahm <franklahm@googlemail.com>
Tue, 16 Nov 2010 10:15:32 +0000 (11:15 +0100)
NEWS
etc/afpd/acl_mappings.h
etc/cnid_dbd/cnid_metad.c
etc/cnid_dbd/comm.c
etc/cnid_dbd/usockfd.c
include/atalk/util.h
libatalk/cnid/dbd/cnid_dbd.c
libatalk/util/socket.c

diff --git a/NEWS b/NEWS
index 4b2873c504d4aeb1a9636afe69f3f1177f75273d..5abf8490efad54b2c1e16fae6073bc41bfda0e08 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -37,7 +37,11 @@ Changes in 2.1.5
 * UPD: afpd: support newlines in -loginmesg with \n escaping syntax
 * UPD: afpd: support for changed chmod semantics on ZFS with ACLs
        in onnv145+
-* FIX: afpd: fix leaking resource when moving objects on the server
+* FIX: afpd: fix leaking ressource when moving objects on the server
+* FIX: afpd: backport Solaris 10 compatibilty fix from 2.2: don't use
+       SO_SNDTIMEO/SO_RCVTIMEO, use non-blocking IO and select instead.
+* FIX: cnid_dbd: backport Solaris 10 compatibilty fix from 2.2: don't
+       use SO_SNDTIMEO/SO_RCVTIMEO, use non-blocking IO and select instead.
 
 Changes in 2.1.4
 ================
index 9bab0d76b6cd013ffbabbc4b1be22fa99837f18b..b7c4b6d266fdb9863005c61dc889cd66785453e7 100644 (file)
@@ -1,5 +1,4 @@
 /*
-   $Id: acl_mappings.h,v 1.1 2009-02-02 11:55:00 franklahm Exp $
    Copyright (c) 2008,2009 Frank Lahm <franklahm@gmail.com>
 
    This program is free software; you can redistribute it and/or modify
  * Stuff for mapping between ACL implementations
  */
 
+/* Solaris 10u8 still hasn't got ACE_INHERITED_ACE */
+#ifndef ACE_INHERITED_ACE
+#define ACE_INHERITED_ACE 0x0080
+#endif
+
 struct ace_rights_map {
     u_int32_t from;
     u_int32_t to;
index 66108c013b3532b9b303935feb69f3f9547167a5..23a6fd0266334e05e9dbb7f9e396890780cade9a 100644 (file)
@@ -597,7 +597,8 @@ int main(int argc, char *argv[])
         if (rqstfd <= 0)
             continue;
 
-        ret = readt(rqstfd, &len, sizeof(int), 4);
+        ret = readt(rqstfd, &len, sizeof(int), 1, 4);
+
         if (!ret) {
             /* already close */
             goto loop_end;
index 8038f2668f7795479e2472919f6673c60f14173e..89355d767b8c0072a01d42763a935850b03e5a9c 100644 (file)
@@ -255,7 +255,7 @@ int comm_rcv(struct cnid_dbd_rqst *rqst, time_t timeout, const sigset_t *sigmask
     }
 
     nametmp = rqst->name;
-    if ((b = readt(cur_fd, rqst, sizeof(struct cnid_dbd_rqst), CNID_DBD_TIMEOUT))
+    if ((b = readt(cur_fd, rqst, sizeof(struct cnid_dbd_rqst), 1, CNID_DBD_TIMEOUT))
         != sizeof(struct cnid_dbd_rqst)) {
         if (b)
             LOG(log_error, logtype_cnid, "error reading message header: %s", strerror(errno));
@@ -264,7 +264,7 @@ int comm_rcv(struct cnid_dbd_rqst *rqst, time_t timeout, const sigset_t *sigmask
         return 0;
     }
     rqst->name = nametmp;
-    if (rqst->namelen && readt(cur_fd, rqst->name, rqst->namelen, CNID_DBD_TIMEOUT)
+    if (rqst->namelen && readt(cur_fd, rqst->name, rqst->namelen, 1, CNID_DBD_TIMEOUT)
         != rqst->namelen) {
         LOG(log_error, logtype_cnid, "error reading message name: %s", strerror(errno));
         invalidate_fd(cur_fd);
index d9dadb5b9828a879d447897a4acf8e8e060a177a..ceb6ff211ad6628693b18e48bb2c1fbec2925c03 100644 (file)
@@ -155,7 +155,6 @@ int usockfd_check(int sockfd, const sigset_t *sigset)
     socklen_t size;
     fd_set readfds;
     int ret;
-    struct timeval tv;
      
     FD_ZERO(&readfds);
     FD_SET(sockfd, &readfds);
@@ -177,10 +176,6 @@ int usockfd_check(int sockfd, const sigset_t *sigset)
                 strerror(errno));
             return -1;
         }
-        if (setnonblock(fd, 1) != 0) {
-            LOG(log_error, logtype_cnid, "setnonblock: %s", strerror(errno));
-            return -1;
-        }
         return fd;
     } else
         return 0;
index 790f5941dc0beedead9132f68c8854163538edeb..d6209ed93c86cf624ba3292c4cd98096cb3b8aab 100644 (file)
@@ -127,7 +127,7 @@ extern int lock_reg(int fd, int cmd, int type, off_t offest, int whence, off_t l
  ******************************************************************/
 
 extern int setnonblock(int fd, int cmd);
-extern ssize_t readt(int socket, void *data, const size_t length, int timeout);
+extern ssize_t readt(int socket, void *data, const size_t length, int setnonblocking, int timeout);
 extern const char *getip_string(const struct sockaddr *sa);
 extern unsigned int getip_port(const struct sockaddr *sa);
 extern void apply_ip_mask(struct sockaddr *ai, int maskbits);
index 20d3a900881ef0ce9a2ad5a2cd266c6c3b0b4143..01c984062543317ea6bfb65f1f3c2206af05fe47 100644 (file)
@@ -89,7 +89,7 @@ static int tsock_getfd(const char *host, const char *port)
         if ((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
             LOG(log_info, logtype_default, "tsock_getfd: socket CNID server %s:: %s",
                 host, strerror(errno));
-                continue;
+            continue;
         }
 
         attr = 1;
@@ -107,7 +107,7 @@ static int tsock_getfd(const char *host, const char *port)
             sock = -1;
             return -1;
         }
-        
+
         if (connect(sock, p->ai_addr, p->ai_addrlen) == -1) {
             if (errno == EINPROGRESS) {
                 struct timeval tv;
@@ -165,7 +165,7 @@ static int tsock_getfd(const char *host, const char *port)
                 continue;
             }
         }
-        
+
         /* We've got a socket */
         break;
     }
@@ -197,11 +197,20 @@ static int tsock_getfd(const char *host, const char *port)
 static int write_vec(int fd, struct iovec *iov, ssize_t towrite, int vecs)
 {
     ssize_t len;
+    int slept = 0;
+    int sleepsecs;
 
     while (1) {
         if (((len = writev(fd, iov, vecs)) == -1 && errno == EINTR))
             continue;
 
+        if ((! slept) && len == -1 && errno == EAGAIN) {
+            sleepsecs = 5;
+            while ((sleepsecs = sleep(sleepsecs)));
+            slept = 1;
+            continue;
+        }
+
         if (len == towrite) /* wrote everything out */
             break;
 
@@ -224,7 +233,7 @@ static int init_tsock(CNID_private *db)
     int len;
     struct iovec iov[2];
 
-    LOG(log_debug, logtype_cnid, "init_tsock: BEGIN. Opening volume '%s', CNID Server: %s/%s", 
+    LOG(log_debug, logtype_cnid, "init_tsock: BEGIN. Opening volume '%s', CNID Server: %s/%s",
         db->db_dir, db->cnidserver, db->cnidport);
 
     if ((fd = tsock_getfd(db->cnidserver, db->cnidport)) < 0)
@@ -273,7 +282,7 @@ static int send_packet(CNID_private *db, struct cnid_dbd_rqst *rqst)
             db->db_dir, strerror(errno));
         return -1;
     }
-    
+
     LOG(log_maxdebug, logtype_cnid, "send_packet: {done}");
     return 0;
 }
@@ -321,7 +330,7 @@ static ssize_t read_packet(int socket, void *data, const size_t length)
     stored = 0;
 
     while (stored < length) {
-        len = read(socket, (u_int8_t *) data + stored, length - stored);
+        len = readt(socket, (u_int8_t *) data + stored, length - stored, 0, 5);
         if (len == -1) {
             switch (errno) {
             case EINTR:
@@ -443,7 +452,7 @@ static int transmit(CNID_private *db, struct cnid_dbd_rqst *rqst, struct cnid_db
                     memcpy(db->client_stamp, stamp, ADEDLEN_PRIVSYN);
                 memcpy(db->stamp, stamp, ADEDLEN_PRIVSYN);
             }
-            LOG(log_debug, logtype_cnid, "transmit: attached to '%s', stamp: '%08lx'.", 
+            LOG(log_debug, logtype_cnid, "transmit: attached to '%s', stamp: '%08lx'.",
                 db->db_dir, *(uint64_t *)stamp);
         }
         if (!dbd_rpc(db, rqst, rply)) {
index 4f8445929b6f0f3f915633e1bcdb16b7510a3484..06ee10e580d909de12a87854e5f0f12dd7a92219 100644 (file)
@@ -30,6 +30,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#include <sys/time.h>
+#include <time.h>
 
 #include <atalk/logger.h>
 
@@ -67,23 +69,35 @@ int setnonblock(int fd, int cmd)
 /*!
  * non-blocking drop-in replacement for read with timeout using select
  *
- * @param socket   (r)  must be nonblocking !
- * @param data     (rw) buffer for the read data
- * @param lenght   (r)  how many bytes to read
- * @param timeout  (r)  number of seconds to try reading
+ * @param socket          (r)  socket, if in blocking mode, pass "setnonblocking" arg as 1
+ * @param data            (rw) buffer for the read data
+ * @param lenght          (r)  how many bytes to read
+ * @param setnonblocking  (r)  when non-zero this func will enable and disable non blocking
+ *                             io mode for the socket
+ * @param timeout         (r)  number of seconds to try reading
  *
  * @returns number of bytes actually read or -1 on fatal error
  */
-ssize_t readt(int socket, void *data, const size_t length, int timeout)
+ssize_t readt(int socket, void *data, const size_t length, int setnonblocking, int timeout)
 {
     size_t stored;
     ssize_t len;
-    struct timeval tv;
+    struct timeval now, end, tv;
     fd_set rfds;
     int ret;
 
     stored = 0;
 
+    if (setnonblocking) {
+        if (setnonblock(socket, 1) != 0)
+            return -1;
+    }
+
+    /* Calculate end time */
+    (void)gettimeofday(&now, NULL);
+    end = now;
+    end.tv_sec += timeout;
+
     while (stored < length) {
         len = read(socket, (char *) data + stored, length - stored);
         if (len == -1) {
@@ -91,31 +105,58 @@ ssize_t readt(int socket, void *data, const size_t length, int timeout)
             case EINTR:
                 continue;
             case EAGAIN:
-                tv.tv_usec = 0;
-                tv.tv_sec  = timeout;
-
                 FD_ZERO(&rfds);
                 FD_SET(socket, &rfds);
+                tv.tv_usec = 0;
+                tv.tv_sec  = timeout;
+                        
                 while ((ret = select(socket + 1, &rfds, NULL, NULL, &tv)) < 1) {
                     switch (ret) {
                     case 0:
-                        LOG(log_warning, logtype_cnid, "select timeout 1s");
-                        return stored;
+                        LOG(log_warning, logtype_afpd, "select timeout %d s", timeout);
+                        goto exit;
+
                     default: /* -1 */
-                        LOG(log_error, logtype_cnid, "select: %s", strerror(errno));
-                        return -1;
+                        if (errno == EINTR) {
+                            (void)gettimeofday(&now, NULL);
+                            if (now.tv_sec >= end.tv_sec && now.tv_usec >= end.tv_usec) {
+                                LOG(log_warning, logtype_afpd, "select timeout %d s", timeout);
+                                goto exit;
+                            }
+                            if (now.tv_usec > end.tv_usec) {
+                                tv.tv_usec = 1000000 + end.tv_usec - now.tv_usec;
+                                tv.tv_sec  = end.tv_sec - now.tv_sec - 1;
+                            } else {
+                                tv.tv_usec = end.tv_usec - now.tv_usec;
+                                tv.tv_sec  = end.tv_sec - now.tv_sec;
+                            }
+                            FD_ZERO(&rfds);
+                            FD_SET(socket, &rfds);
+                            continue;
+                        }
+                        LOG(log_error, logtype_afpd, "select: %s", strerror(errno));
+                        stored = -1;
+                        goto exit;
                     }
-                }
+                } /* while (select) */
                 continue;
-            }
-            LOG(log_error, logtype_cnid, "read: %s", strerror(errno));
-            return -1;
-        }
+            } /* switch (errno) */
+            LOG(log_error, logtype_afpd, "read: %s", strerror(errno));
+            stored = -1;
+            goto exit;
+        } /* (len == -1) */
         else if (len > 0)
             stored += len;
         else
             break;
+    } /* while (stored < length) */
+
+exit:
+    if (setnonblocking) {
+        if (setnonblock(socket, 0) != 0)
+            return -1;
     }
+
     return stored;
 }