* so that processes don't think they have to wait for us, which is
* interesting for initscripts as well. Wouter Verhelst
* <wouter@debian.org>
+ * Version 2.5 - Bugfix release: forgot to reset child_arraysize to
+ * zero after fork()ing, resulting in nbd-server going berserk
+ * when it receives a signal with at least one child open. Wouter
+ * Verhelst <wouter@debian.org>
+ * 10/10/2003 - Added socket option SO_KEEPALIVE (sf.net bug 819235);
+ * rectified type of mainloop::size_host (sf.net bugs 814435 and
+ * 817385); close the PID file after writing to it, so that the
+ * daemon can actually be found. Wouter Verhelst
+ * <wouter@debian.org>
*/
#define VERSION PACKAGE_VERSION
// #define ISSERVER
#define MY_NAME "nbd_server"
-/* Authorization file should contain lines with IP addresses of
- clients authorized to use the server. If it does not exist,
- access is permitted.
-
- You may want to set this to an absolute path if you're not using
- -DNODAEMON, since if you don't, nbd-server will look for this file
- in the root-directory ("/"). */
-#define AUTH_FILE "nbd_server.allow"
/* how much space for child PIDs we have by default. Dynamically
allocated, and will be realloc()ed if out of space, so this should
probably be fair for most situations. */
//#undef _IO
/* Deep magic: ioctl.h defines _IO macro (at least on linux) */
-
/* Debugging macros, now nothing goes to syslog unless you say ISSERVER */
#ifdef ISSERVER
#define msg2(a,b) syslog(a,b)
#define msg4(a,b,c,d) do { fprintf(stderr,b,c,d); fputs("\n",stderr) ; } while(0)
#endif
-
#include <sys/ioctl.h>
#include <sys/mount.h> /* For BLKGETSIZE */
char difffilename[256];
unsigned int timeout = 0;
int autoreadonly = 0;
+char *auth_file="nbd_server.allow";
int authorized_client(char *name)
/* 0 - authorization refused, 1 - OK
char line[LINELEN] ;
- if ((f=fopen(AUTH_FILE,"r"))==NULL) {
+ if ((f=fopen(auth_file,"r"))==NULL) {
msg4(LOG_INFO,"Can't open authorization file %s (%s).",
- AUTH_FILE,strerror(errno)) ;
+ auth_file,strerror(errno)) ;
return 1 ;
}
" -r read only\n"
" -m multiple file\n"
" -c copy on write\n"
+ " -l file with list of hosts that are allowed to connect.\n"
" -a maximum idle seconds, terminates when idle time exceeded\n"
" if port is set to 0, stdin is used (for running from inetd)\n"
" if file_to_export contains '%%s', it is substituted with IP\n"
break;
case 'c': flags |=F_COPYONWRITE;
break;
+ case 'l':
+ free(auth_file);
+ if (i+1<argc) {
+ auth_file=argv[++i];
+ } else {
+ fprintf(stderr, "host list file requires an argument");
+ }
+ break;
case 'a':
if (i+1<argc) {
timeout = atoi(argv[i+1]);
pidf=fopen(pidfname, "w");
if(pidf) {
fprintf(pidf,"%d", (int)getpid());
+ fclose(pidf);
} else {
perror("fopen");
fprintf(stderr, "Not fatal; continuing");
/* lose the pesky "Address already in use" error message */
if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
- err("setsockopt");
+ err("setsockopt SO_REUSEADDR");
+ }
+ if (setsockopt(sock,SOL_SOCKET,SO_KEEPALIVE,&yes,sizeof(int)) == -1) {
+ err("setsockopt SO_KEEPALIVE");
}
DEBUG("Waiting for connections... bind, ");
close(net) ; continue ; }
/* child */
realloc(children,0);
+ child_arraysize=0;
close(sock) ;
#endif // NOFORK
msg2(LOG_INFO,"Starting to serve") ;
struct nbd_reply reply;
char zeros[300];
int i = 0;
- off_t size_host;
+ u64 size_host;
memset(zeros, 0, 290);
if (write(net, INIT_PASSWD, 8) < 0)
cliserv_magic = htonll(cliserv_magic);
if (write(net, &cliserv_magic, sizeof(cliserv_magic)) < 0)
err("Negotiation failed: %m");
- size_host = htonll(exportsize);
+ size_host = htonll((u64)exportsize);
if (write(net, &size_host, 8) < 0)
err("Negotiation failed: %m");
if (write(net, zeros, 128) < 0)