r339: Explicitly set the client socket to nonblocking, since some systems
[nbd.git] / nbd-server.c
index 2c2c973..5425eb5 100644 (file)
@@ -555,18 +555,17 @@ GArray* parse_cfile(gchar* f, GError** e) {
                { "readonly",   FALSE,  PARAM_BOOL,     NULL, F_READONLY },
                { "multifile",  FALSE,  PARAM_BOOL,     NULL, F_MULTIFILE },
                { "copyonwrite", FALSE, PARAM_BOOL,     NULL, F_COPYONWRITE },
-               { "autoreadonly", FALSE, PARAM_BOOL,    NULL, F_AUTOREADONLY },
                { "sparse_cow", FALSE,  PARAM_BOOL,     NULL, F_SPARSE },
                { "sdp",        FALSE,  PARAM_BOOL,     NULL, F_SDP },
                { "listenaddr", FALSE,  PARAM_STRING,   NULL, 0 },
        };
-       const int lp_size=15;
+       const int lp_size=sizeof(lp)/sizeof(PARAM);
        PARAM gp[] = {
                { "user",       FALSE, PARAM_STRING,    &runuser,       0 },
                { "group",      FALSE, PARAM_STRING,    &rungroup,      0 },
        };
        PARAM* p=gp;
-       int p_size=2;
+       int p_size=sizeof(gp)/sizeof(PARAM);
        GKeyFile *cfile;
        GError *err = NULL;
        const char *err_msg=NULL;
@@ -603,9 +602,8 @@ GArray* parse_cfile(gchar* f, GError** e) {
                lp[6].target=&(s.prerun);
                lp[7].target=&(s.postrun);
                lp[8].target=lp[9].target=lp[10].target=
-                               lp[11].target=lp[12].target=
-                               lp[13].target=&(s.flags);
-               lp[14].target=&(s.listenaddr);
+                               lp[11].target=lp[12].target=&(s.flags);
+               lp[13].target=&(s.listenaddr);
 
                /* After the [generic] group, start parsing exports */
                if(i==1) {
@@ -1220,8 +1218,12 @@ void setupexport(CLIENT* client) {
                        /* Try again because maybe media was read-only */
                        fi.fhandle = open(tmpname, O_RDONLY);
                        if(fi.fhandle != -1) {
-                               client->server->flags |= F_AUTOREADONLY;
-                               client->server->flags |= F_READONLY;
+                               /* Opening the base file in copyonwrite mode is
+                                * okay */
+                               if(!(client->server->flags & F_COPYONWRITE)) {
+                                       client->server->flags |= F_AUTOREADONLY;
+                                       client->server->flags |= F_READONLY;
+                               }
                        }
                }
                if(fi.fhandle == -1) {
@@ -1393,7 +1395,6 @@ int serveloop(GArray* servers) {
        int sock;
        fd_set mset;
        fd_set rset;
-       struct timeval tv;
 
        /* 
         * Set up the master fd_set. The set of descriptors we need
@@ -1415,16 +1416,21 @@ int serveloop(GArray* servers) {
                pid_t *pid;
 
                memcpy(&rset, &mset, sizeof(fd_set));
-               tv.tv_sec=0;
-               tv.tv_usec=500;
-               if(select(max+1, &rset, NULL, NULL, &tv)>0) {
+               if(select(max+1, &rset, NULL, NULL, NULL)>0) {
                        DEBUG("accept, ");
                        for(i=0;i<servers->len;i++) {
                                serve=&(g_array_index(servers, SERVER, i));
                                if(FD_ISSET(serve->socket, &rset)) {
+                                       int sock_flags;
                                        if ((net=accept(serve->socket, (struct sockaddr *) &addrin, &addrinlen)) < 0)
                                                err("accept: %m");
 
+                                       if((sock_flags = fcntl(net, F_GETFL, 0))==-1) {
+                                               err("fcntl F_GETFL");
+                                       }
+                                       if(fcntl(net, F_SETFL, sock_flags &~O_NONBLOCK)==-1) {
+                                               err("fcntl F_SETFL ~O_NONBLOCK");
+                                       }
                                        client = g_malloc(sizeof(CLIENT));
                                        client->server=serve;
                                        client->exportsize=OFFT_MAX;
@@ -1451,7 +1457,7 @@ int serveloop(GArray* servers) {
                                        /* child */
                                        g_hash_table_destroy(children);
                                        for(i=0;i<servers->len;i++) {
-                                               serve=g_array_index(servers, SERVER*, i);
+                                               serve=&g_array_index(servers, SERVER, i);
                                                close(serve->socket);
                                        }
                                        /* FALSE does not free the