From: yoe Date: Wed, 4 Oct 2006 21:43:22 +0000 (+0000) Subject: r189: Fix crashes, thanks (again) to Phillip X-Git-Url: http://git.alex.org.uk r189: Fix crashes, thanks (again) to Phillip --- diff --git a/nbd-server.c b/nbd-server.c index 4ecb1f5..77b3e0d 100644 --- a/nbd-server.c +++ b/nbd-server.c @@ -468,7 +468,7 @@ GArray* parse_cfile(gchar* f, GError** e) { p[2].target=&(s.authname); p[3].target=&(s.timeout); p[4].target=&(s.expected_size); - p[5].target=p[6].target=p[7].target=p[8].target=&(s.flags); + p[5].target=p[6].target=p[7].target=&(s.flags); for(j=0;jserver->flags & F_MULTIFILE); client->export = g_array_new(TRUE, TRUE, sizeof(int)); - for (i=0; iexportsize; i+=client->server->hunksize) { + + /* If multifile, open as many files as we can. + * For non-multifile, open exactly one file. + * (Either way, we must be able to open at least one file.) */ + for(i=0; ; i++) { + int fhandle; gchar *tmpname; + mode_t mode = (client->server->flags & F_READONLY) ? O_RDONLY : O_RDWR; - if(client->server->flags & F_MULTIFILE) { - tmpname=g_strdup_printf("%s.%d", client->exportname, - (int)(i/client->server->hunksize)); + if(multifile) { + tmpname=g_strdup_printf("%s.%d", client->exportname, i); } else { tmpname=g_strdup(client->exportname); } DEBUG2( "Opening %s\n", tmpname ); - if((fhandle = open(tmpname, (client->server->flags & F_READONLY) ? O_RDONLY : O_RDWR)) == -1) { - /* Read WRITE ACCESS was requested by media is only read only */ - client->server->flags |= F_AUTOREADONLY; - client->server->flags |= F_READONLY; - if((fhandle = open(tmpname, O_RDONLY)) == -1) - err("Could not open exported file: %m"); + fhandle = open(tmpname, mode); + if(fhandle == -1 && mode == O_RDWR) { + /* Try again because maybe media was read-only */ + fhandle = open(tmpname, O_RDONLY); + if(fhandle != -1) { + client->server->flags |= F_AUTOREADONLY; + client->server->flags |= F_READONLY; + } } - g_array_insert_val(client->export,i/client->server->hunksize,fhandle); + if(fhandle == -1) { + if(multifile && i*(client->server->hunksize) >= client->exportsize) + break; + err("Could not open exported file: %m"); + } + g_array_insert_val(client->export, i, fhandle); g_free(tmpname); + + if(!multifile) + break; } return 0; } @@ -963,7 +983,11 @@ int copyonwrite_prepare(CLIENT* client) { * @param client a connected client **/ void serveconnection(CLIENT *client) { - splitexport(client); + setupexport(client); + + /* Sanity check. There must be at least one file. */ + if(client->export->len == 0) + err("No file(s) to export\n"); if (!client->server->expected_size) { client->exportsize = size_autodetect(g_array_index(client->export,int,0));