summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
b89cbd6)
* Added -a option to nbd-server's manpage (and removed erroneous '-c
this' entry)
#error I need at least some 32-bit type
#endif
#error I need at least some 32-bit type
#endif
#if SIZEOF_UNSIGNED_INT==8
typedef unsigned int u64;
#elif SIZEOF_UNSIGNED_LONG_INT==8
#if SIZEOF_UNSIGNED_INT==8
typedef unsigned int u64;
#elif SIZEOF_UNSIGNED_LONG_INT==8
#else
#error I need at least some 64-bit type
#endif
#else
#error I need at least some 64-bit type
#endif
-#ifdef FS_32BIT
-struct { unsigned char m[8]; } cliserv_magic = { { 0x00, 0x00, 0x42, 0x02, 0x81, 0x86, 0x12, 0x53 } };
-#else
u64 cliserv_magic = 0x00420281861253LL;
u64 cliserv_magic = 0x00420281861253LL;
#define INIT_PASSWD "NBDMAGIC"
#define INFO(a) do { } while(0)
#define INIT_PASSWD "NBDMAGIC"
#define INFO(a) do { } while(0)
setvbuf(stderr, NULL, _IONBF, 0);
}
setvbuf(stderr, NULL, _IONBF, 0);
}
#ifdef WORDS_BIGENDIAN
u64 ntohll(u64 a)
{
#ifdef WORDS_BIGENDIAN
u64 ntohll(u64 a)
{
}
#endif
#define htonll ntohll
}
#endif
#define htonll ntohll
<cmdsynopsis>
<command>&dhpackage;</command>
<cmdsynopsis>
<command>&dhpackage;</command>
- <arg><option>-c <replaceable>this</replaceable></option></arg>
<arg choice=plain><replaceable>port</replaceable</arg>
<arg choice=plain><replaceable>filename</replaceable></arg>
<arg><replaceable>size</replaceable></arg>
<arg><option>-r</option></arg>
<arg><option>-m</option></arg>
<arg><option>-c</option></arg>
<arg choice=plain><replaceable>port</replaceable</arg>
<arg choice=plain><replaceable>filename</replaceable></arg>
<arg><replaceable>size</replaceable></arg>
<arg><option>-r</option></arg>
<arg><option>-m</option></arg>
<arg><option>-c</option></arg>
+ <arg><option>-a <replaceable>timeout</replaceable></option></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
then be used for whatever purpose a normal block device (harddisk,
CD-ROM, ...) can be used for.</para>
then be used for whatever purpose a normal block device (harddisk,
CD-ROM, ...) can be used for.</para>
- <para>NBD can be usefull for diskless clients that need swapspace,
+ <para>NBD can be useful for diskless clients that need swapspace,
but you can also create a filesystem on it and use it as though it
were a local filesystem.</para>
but you can also create a filesystem on it and use it as though it
were a local filesystem.</para>
lost.</para>
</listitem>
</varlistentry>
lost.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>timeout</option></term>
+ <listitem>
+ <para>Maximum number of idle seconds. If a connection is
+ inactive for this amount of time, it is terminated; this is to
+ avoid stale nbd-server processes staying in memory. Use of
+ this option is strongly recommended.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
<refsect1>
</variablelist>
</refsect1>
<refsect1>
* clean on 32 bit machines. Anton Altaparmakov <aia21@cam.ac.uk>
* Version 2.0 - Version synchronised with client
* Version 2.1 - Reap zombie client processes when they exit. Removed
* clean on 32 bit machines. Anton Altaparmakov <aia21@cam.ac.uk>
* Version 2.0 - Version synchronised with client
* Version 2.1 - Reap zombie client processes when they exit. Removed
- * (uncommented) the _IO magic, it's no longer necessary.
+ * (uncommented) the _IO magic, it's no longer necessary. Wouter
+ * Verhelst <wouter@debian.org>
* Version 2.2 - Auto switch to read-only mode (usefull for floppies).
* Version 2.2 - Auto switch to read-only mode (usefull for floppies).
+ * Version 2.3 - Fixed code so that Large File Support works. This
+ * removes the FS_32BIT compile-time directive; define
+ * _FILE_OFFSET_BITS=64 and _LARGEFILE_SOURCE if you used to be
+ * using FS_32BIT. This will allow you to use files >2GB instead of
+ * having to use the -m option. Wouter Verhelst <wouter@debian.org>
#define GIGA (1*1024*1024*1024)
#include <sys/types.h>
#define GIGA (1*1024*1024*1024)
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mount.h> /* For BLKGETSIZE */
#include <sys/ioctl.h>
#include <sys/mount.h> /* For BLKGETSIZE */
-#ifdef FS_32BIT
-typedef u32 fsoffset_t;
-#define htonll htonl
-#define ntohll ntohl
-#else
-typedef u64 fsoffset_t;
-#endif
-
-
//#define DODBG
#ifdef DODBG
#define DEBUG( a ) printf( a )
//#define DODBG
#ifdef DODBG
#define DEBUG( a ) printf( a )
#define DEBUG3( a,b,c )
#endif
#define DEBUG3( a,b,c )
#endif
-#if defined(HAVE_LLSEEK) && !defined(sun)
-/* Solaris already has llseek defined in unistd.h */
-extern long long llseek(unsigned int, long long, unsigned int);
-#endif
-
void serveconnection(int net);
void set_peername(int net,char *clientname);
void serveconnection(int net);
void set_peername(int net,char *clientname);
+#define OFFT_MAX (((off_t)1)<<(sizeof(off_t)*8))-1
int port; /* Port I'm listening at */
char *exportname; /* File I'm exporting */
int port; /* Port I'm listening at */
char *exportname; /* File I'm exporting */
-fsoffset_t exportsize = (fsoffset_t)-1; /* ...and its length */
-fsoffset_t hunksize = (fsoffset_t)-1;
+off_t exportsize = OFFT_MAX; /* ...and its length */
+off_t hunksize = OFFT_MAX;
int flags = 0;
int export[1024];
int difffile=-1 ;
int flags = 0;
int export[1024];
int difffile=-1 ;
int last = strlen(argv[i])-1;
char suffix = argv[i][last];
if (suffix == 'k' || suffix == 'K' ||
suffix == 'm' || suffix == 'M')
argv[i][last] = '\0';
int last = strlen(argv[i])-1;
char suffix = argv[i][last];
if (suffix == 'k' || suffix == 'K' ||
suffix == 'm' || suffix == 'M')
argv[i][last] = '\0';
- es = (fsoffset_t)atol(argv[i]);
+ es = (off_t)atol(argv[i]);
switch (suffix) {
case 'm':
case 'M': es <<= 10;
switch (suffix) {
case 'm':
case 'M': es <<= 10;
#define SEND writeit( net, &reply, sizeof( reply ));
#define ERROR { reply.error = htonl(-1); SEND; reply.error = 0; lastpoint = -1; }
#define SEND writeit( net, &reply, sizeof( reply ));
#define ERROR { reply.error = htonl(-1); SEND; reply.error = 0; lastpoint = -1; }
-fsoffset_t lastpoint = (fsoffset_t)-1;
+off_t lastpoint = (off_t)-1;
-void maybeseek(int handle, fsoffset_t a)
+void maybeseek(int handle, off_t a)
- if (a > exportsize)
- err("Can not happen\n");
- if (lastpoint != a) {
-#if defined(HAVE_LLSEEK) && !defined(FS_32BIT)
- if (llseek(handle, a, SEEK_SET) < 0)
-#else
- if (lseek(handle, (long)a, SEEK_SET) < 0)
-#endif
- err("Can not seek locally!\n");
- lastpoint = a;
- } else {
- DEBUG("@");
- }
+if (a > exportsize)
+ err("Can not happen\n");
+if (lastpoint != a) {
+ if (lseek(handle, a, SEEK_SET) < 0)
+ err("Can not seek locally!\n");
+ lastpoint = a;
+} else {
+ DEBUG("@");
+}
-void myseek(int handle,fsoffset_t a)
+void myseek(int handle,off_t a)
-#if HAVE_LLSEEK && !defined(FS_32BIT)
- if (llseek(handle, a, SEEK_SET) < 0)
-#else
- if (lseek(handle, (long)a, SEEK_SET) < 0)
-#endif
+ if (lseek(handle, a, SEEK_SET) < 0)
err("Can not seek locally!\n");
}
char pagebuf[DIFFPAGESIZE];
err("Can not seek locally!\n");
}
char pagebuf[DIFFPAGESIZE];
-int rawexpread(fsoffset_t a, char *buf, int len)
+int rawexpread(off_t a, char *buf, int len)
{
maybeseek(export[a/hunksize], a%hunksize);
return (read(export[a/hunksize], buf, len) != len);
}
{
maybeseek(export[a/hunksize], a%hunksize);
return (read(export[a/hunksize], buf, len) != len);
}
-int expread(fsoffset_t a, char *buf, int len)
+int expread(off_t a, char *buf, int len)
- fsoffset_t mapcnt, mapl, maph, pagestart;
+ off_t mapcnt, mapl, maph, pagestart;
if (!(flags & F_COPYONWRITE))
return rawexpread(a, buf, len);
if (!(flags & F_COPYONWRITE))
return rawexpread(a, buf, len);
-int rawexpwrite(fsoffset_t a, char *buf, int len)
+int rawexpwrite(off_t a, char *buf, int len)
{
maybeseek(export[a/hunksize], a%hunksize);
return (write(export[a/hunksize], buf, len) != len);
}
{
maybeseek(export[a/hunksize], a%hunksize);
return (write(export[a/hunksize], buf, len) != len);
}
-int expwrite(fsoffset_t a, char *buf, int len)
+int expwrite(off_t a, char *buf, int len)
{
u32 mapcnt,mapl,maph ; int wrlen,rdlen ;
{
u32 mapcnt,mapl,maph ; int wrlen,rdlen ;
- fsoffset_t pagestart ; int offset ;
+ off_t pagestart ; int offset ;
if (!(flags & F_COPYONWRITE))
return(rawexpwrite(a,buf,len));
if (!(flags & F_COPYONWRITE))
return(rawexpwrite(a,buf,len));
struct nbd_reply reply;
char zeros[300];
int i = 0;
struct nbd_reply reply;
char zeros[300];
int i = 0;
memset(zeros, 0, 290);
if (write(net, INIT_PASSWD, 8) < 0)
err("Negotiation failed: %m");
memset(zeros, 0, 290);
if (write(net, INIT_PASSWD, 8) < 0)
err("Negotiation failed: %m");
cliserv_magic = htonll(cliserv_magic);
cliserv_magic = htonll(cliserv_magic);
if (write(net, &cliserv_magic, sizeof(cliserv_magic)) < 0)
err("Negotiation failed: %m");
size_host = htonll(exportsize);
if (write(net, &cliserv_magic, sizeof(cliserv_magic)) < 0)
err("Negotiation failed: %m");
size_host = htonll(exportsize);
-#ifdef FS_32BIT
- if (write(net, zeros, 4) < 0 || write(net, &size_host, 4) < 0)
-#else
if (write(net, &size_host, 8) < 0)
if (write(net, &size_host, 8) < 0)
err("Negotiation failed: %m");
if (write(net, zeros, 128) < 0)
err("Negotiation failed: %m");
err("Negotiation failed: %m");
if (write(net, zeros, 128) < 0)
err("Negotiation failed: %m");
(unsigned long long)request.from / 512, len);
#endif
memcpy(reply.handle, request.handle, sizeof(reply.handle));
(unsigned long long)request.from / 512, len);
#endif
memcpy(reply.handle, request.handle, sizeof(reply.handle));
- if (((request.from + len) > exportsize) ||
+ if ((request.from + len) > (OFFT_MAX)) {
+ DEBUG("[Number too large!]");
+ ERROR;
+ continue;
+ }
+ if ((((off_t)request.from + len) > exportsize) ||
((flags & F_READONLY) && request.type)) {
DEBUG("[RANGE!]");
ERROR;
((flags & F_READONLY) && request.type)) {
DEBUG("[RANGE!]");
ERROR;
strncpy(clientname,peername,255) ;
}
strncpy(clientname,peername,255) ;
}
-fsoffset_t size_autodetect(int export)
+off_t size_autodetect(int export)
u32 es32;
struct stat stat_buf;
int error;
DEBUG("looking for export size with lseek SEEK_END\n");
u32 es32;
struct stat stat_buf;
int error;
DEBUG("looking for export size with lseek SEEK_END\n");
- es = (fsoffset_t)lseek(export, 0, SEEK_END);
- if ((signed long long)es > 0LL)
+ es = lseek(export, (off_t)0, SEEK_END);
+ if (es > ((off_t)0))
return es;
DEBUG("looking for export size with fstat\n");
stat_buf.st_size = 0;
error = fstat(export, &stat_buf);
if (!error && stat_buf.st_size > 0)
return es;
DEBUG("looking for export size with fstat\n");
stat_buf.st_size = 0;
error = fstat(export, &stat_buf);
if (!error && stat_buf.st_size > 0)
- return (fsoffset_t)stat_buf.st_size;
+ return (off_t)stat_buf.st_size;
#ifdef BLKGETSIZE
DEBUG("looking for export size with ioctl BLKGETSIZE\n");
if (!ioctl(export, BLKGETSIZE, &es32) && es32) {
#ifdef BLKGETSIZE
DEBUG("looking for export size with ioctl BLKGETSIZE\n");
if (!ioctl(export, BLKGETSIZE, &es32) && es32) {
- es = (fsoffset_t)es32 * (fsoffset_t)512;
+ es = (off_t)es32 * (off_t)512;
return es;
}
#endif
err("Could not find size of exported block device: %m");
return es;
}
#endif
err("Could not find size of exported block device: %m");
}
int main(int argc, char *argv[])
{
int net;
}
int main(int argc, char *argv[])
{
int net;
if (sizeof( struct nbd_request )!=28) {
fprintf(stderr,"Bad size of structure. Alignment problems?\n");
if (sizeof( struct nbd_request )!=28) {
fprintf(stderr,"Bad size of structure. Alignment problems?\n");
void serveconnection(int net)
{
void serveconnection(int net)
{
for (i=0; i<exportsize; i+=hunksize) {
char exportname3[1024];
for (i=0; i<exportsize; i+=hunksize) {
char exportname3[1024];
err("Could not open exported file: %m");
}
}
err("Could not open exported file: %m");
}
}
-
- if (exportsize == (fsoffset_t)-1) {
+
+ if (exportsize == (off_t)OFFT_MAX) {
exportsize = size_autodetect(export[0]);
}
exportsize = size_autodetect(export[0]);
}
- if (exportsize > ((fsoffset_t)-1 >> 1)) {
-#ifdef HAVE_LLSEEK
- if ((exportsize >> 10) > ((fsoffset_t)-1 >> 1))
- msg3(LOG_INFO, "size of exported file/device is %LuMB",
- (unsigned long long)(exportsize >> 20));
- else
- msg3(LOG_INFO, "size of exported file/device is %LuKB",
- (unsigned long long)(exportsize >> 10));
- }
-#else
+ if (exportsize > (off_t)OFFT_MAX) {
err("Size of exported file is too big\n");
}
err("Size of exported file is too big\n");
}
else
msg3(LOG_INFO, "size of exported file/device is %Lu",
(unsigned long long)exportsize);
else
msg3(LOG_INFO, "size of exported file/device is %Lu",
(unsigned long long)exportsize);