r337: Check multi-file export in 'make check', too; and tell automake that we have...
[nbd.git] / nbd-server.c
index 2c2c973..a683f8c 100644 (file)
@@ -170,6 +170,7 @@ typedef enum {
  **/
 typedef struct {
        gchar* exportname;    /**< (unprocessed) filename of the file we're exporting */
+       gchar* cowname;      /**< template for the filename of the copy-on-write file */
        off_t expected_size; /**< size of the exported file as it was told to
                               us through configuration */
        gchar* listenaddr;   /**< The IP address we're listening on */
@@ -555,18 +556,18 @@ 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 },
+               { "cowname",    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 +604,11 @@ 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);
+               lp[14].target=&(s.cowname);
+
+               s.cowname = "$F-$I-$P.diff";
 
                /* After the [generic] group, start parsing exports */
                if(i==1) {
@@ -1220,8 +1223,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 +1400,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,9 +1421,7 @@ 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));
@@ -1451,7 +1455,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