Network Block Device  @PACKAGE_VERSION@
Data Structures | Macros | Enumerations | Functions | Variables
nbd-server.c File Reference
#include "lfs.h"
#include <assert.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <signal.h>
#include <errno.h>
#include <netinet/tcp.h>
#include <netinet/in.h>
#include <netdb.h>
#include <syslog.h>
#include <unistd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <linux/falloc.h>
#include <arpa/inet.h>
#include <strings.h>
#include <dirent.h>
#include <getopt.h>
#include <pwd.h>
#include <grp.h>
#include <glib.h>
#include "cliserv.h"

Go to the source code of this file.

Data Structures

struct  SERVER
 Variables associated with a server. More...
 
struct  FILE_INFO
 Variables associated with a client socket. More...
 
struct  CLIENT
 
struct  PARAM
 Configuration file values. More...
 

Macros

#define MY_NAME   "nbd_server"
 
#define SYSCONFDIR   "/etc"
 Default position of the config file.
 
#define CFILE   SYSCONFDIR "/nbd-server/config"
 
#define msg2(a, b)   g_message((char*)b)
 Logging macros, now nothing goes to syslog unless you say ISSERVER.
 
#define msg3(a, b, c)   g_message((char*)b,c)
 
#define msg4(a, b, c, d)   g_message((char*)b,c,d)
 
#define DEBUG(...)
 
#define OFFT_MAX   ~((off_t)1<<(sizeof(off_t)*8-1))
 The highest value a variable of type off_t can reach.
 
#define LINELEN   256
 Size of static buffer used to read the authorization file (yuck)
 
#define BUFSIZE   ((1024*1024)+sizeof(struct nbd_reply))
 Size of buffer that can hold requests.
 
#define DIFFPAGESIZE   4096
 diff file uses those chunks
 
#define F_READONLY   1
 Per-export flags:
 
#define F_MULTIFILE   2
 flag to tell us a file is exported using -m
 
#define F_COPYONWRITE   4
 flag to tell us a file is exported using copyonwrite
 
#define F_AUTOREADONLY   8
 flag to tell us a file is set to autoreadonly
 
#define F_SPARSE   16
 flag to tell us copyronwrite should use a sparse file
 
#define F_SDP   32
 flag to tell us the export should be done using the Socket Direct Protocol for RDMA
 
#define F_SYNC   64
 Whether to fsync() after a write.
 
#define F_FLUSH   128
 Whether server wants FLUSH to be sent by the client.
 
#define F_FUA   256
 Whether server wants FUA to be sent by the client.
 
#define F_ROTATIONAL   512
 Whether server wants the client to implement the elevator algorithm.
 
#define F_TEMPORARY   1024
 Whether the backing file is temporary and should be created then unlinked.
 
#define F_TRIM   2048
 Whether server wants TRIM (discard) to be sent by the client.
 
#define F_FIXED   4096
 Client supports fixed new-style protocol (and can thus send us extra options.
 
#define F_OLDSTYLE   1
 Global flags:
 
#define F_LIST   2
 Allow clients to list the exports on a server.
 
#define NEG_INIT   (1 << 0)
 
#define NEG_OLD   (1 << 1)
 
#define NEG_MODERN   (1 << 2)
 
#define SEND(net, reply)
 sending macro.
 
#define ERROR(client, reply, errcode)   { reply.error = htonl(errcode); SEND(client->net,reply); reply.error = 0; }
 error macro.
 

Enumerations

enum  VIRT_STYLE { VIRT_NONE =0, VIRT_IPLIT, VIRT_IPHASH, VIRT_CIDR }
 Types of virtuatlization. More...
 
enum  PARAM_TYPE { PARAM_INT, PARAM_INT64, PARAM_STRING, PARAM_BOOL }
 Type of configuration file values. More...
 
enum  CFILE_ERRORS {
  CFILE_NOTFOUND, CFILE_MISSING_GENERIC, CFILE_KEY_MISSING, CFILE_VALUE_INVALID,
  CFILE_VALUE_UNSUPPORTED, CFILE_PROGERR, CFILE_NO_EXPORTS, CFILE_INCORRECT_PORT,
  CFILE_DIR_UNKNOWN, CFILE_READDIR_ERR
}
 Error codes for config file parsing. More...
 

Functions

static const char * getcommandname (uint64_t command)
 Translate a command name into human readable form.
 
int authorized_client (CLIENT *opts)
 Check whether a client is allowed to connect.
 
static void readit (int f, void *buf, size_t len)
 Read data from a file descriptor into a buffer.
 
static void consume (int f, void *buf, size_t len, size_t bufsiz)
 Consume data from an FD that we don't want.
 
static void writeit (int f, void *buf, size_t len)
 Write data from a buffer into a filedescriptor.
 
void usage ()
 Print out a message about how to use nbd-server.
 
void dump_section (SERVER *serve, gchar *section_header)
 
SERVERcmdline (int argc, char *argv[])
 Parse the command line.
 
void remove_server (gpointer s)
 Remove a SERVER from memory.
 
SERVERdup_serve (SERVER *s)
 duplicate server
 
int append_serve (SERVER *s, GArray *a)
 append new server to array
 
GArray * parse_cfile (gchar *f, bool have_global, GError **e)
 Parse the config file.
 
GArray * do_cfile_dir (gchar *dir, GError **e)
 Parse config file snippets in a directory.
 
void sigchld_handler (int s)
 Signal handler for SIGCHLD.
 
void killchild (gpointer key, gpointer value, gpointer user_data)
 Kill a child.
 
void sigterm_handler (int s)
 Handle SIGTERM and dispatch it to our children.
 
off_t size_autodetect (int fhandle)
 Detect the size of a file.
 
int get_filepos (GArray *export, off_t a, int *fhandle, off_t *foffset, size_t *maxbytes)
 Get the file handle and offset, given an export offset.
 
void myseek (int handle, off_t a)
 seek to a position in a file, with error handling.
 
ssize_t rawexpwrite (off_t a, char *buf, size_t len, CLIENT *client, int fua)
 Write an amount of bytes at a given offset to the right file.
 
int rawexpwrite_fully (off_t a, char *buf, size_t len, CLIENT *client, int fua)
 Call rawexpwrite repeatedly until all data has been written.
 
ssize_t rawexpread (off_t a, char *buf, size_t len, CLIENT *client)
 Read an amount of bytes at a given offset from the right file.
 
int rawexpread_fully (off_t a, char *buf, size_t len, CLIENT *client)
 Call rawexpread repeatedly until all data has been read.
 
int expread (off_t a, char *buf, size_t len, CLIENT *client)
 Read an amount of bytes at a given offset from the right file.
 
int expwrite (off_t a, char *buf, size_t len, CLIENT *client, int fua)
 Write an amount of bytes at a given offset to the right file.
 
int expflush (CLIENT *client)
 Flush data to a client.
 
int exptrim (struct nbd_request *req, CLIENT *client)
 
static void send_reply (uint32_t opt, int net, uint32_t reply_type, size_t datasize, void *data)
 
static CLIENThandle_export_name (uint32_t opt, int net, GArray *servers, uint32_t cflags)
 
static void handle_list (uint32_t opt, int net, GArray *servers, uint32_t cflags)
 
CLIENTnegotiate (int net, CLIENT *client, GArray *servers, int phase)
 Do the initial negotiation.
 
int mainloop (CLIENT *client)
 Serve a file to a single client.
 
void setupexport (CLIENT *client)
 Set up client export array, which is an array of FILE_INFO.
 
int copyonwrite_prepare (CLIENT *client)
 
int do_run (gchar *command, gchar *file)
 Run a command.
 
void serveconnection (CLIENT *client)
 Serve a connection.
 
void set_peername (int net, CLIENT *client)
 Find the name of the file we have to serve.
 
void destroy_pid_t (gpointer data)
 Destroy a pid_t*.
 
int serveloop (GArray *servers)
 Loop through the available servers, and serve them.
 
void dosockopts (int socket)
 
int setup_serve (SERVER *serve)
 Connect a server's socket.
 
void open_modern (void)
 
void setup_servers (GArray *servers)
 Connect our servers.
 
void daemonize (SERVER *serve)
 Go daemon (unless we specified at compile time that we didn't want this)
 
void serve_err (SERVER *serve, const char *msg) G_GNUC_NORETURN
 
void dousers (void)
 Set up user-ID and/or group-ID.
 
void glib_message_syslog_redirect (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
 
int main (int argc, char *argv[])
 Main entry point...
 

Variables

gchar * config_file_pos
 Where our config file actually is.
 
gchar * runuser =NULL
 What user we're running as.
 
gchar * rungroup =NULL
 What group we're running as.
 
int glob_flags =0
 global flags
 
int dontfork = 0
 
GHashTable * children
 
char pidfname [256]
 name of our PID file
 
char pidftemplate [256]
 template to be used for the filename of the PID file
 
char default_authname [] = SYSCONFDIR "/nbd-server/allow"
 default name of allow file
 
int modernsock =0
 Socket for the modern handler.
 
char * modern_listen
 listenaddr value for modernsock
 
char * modernport =NBD_DEFAULT_PORT
 Port number on which to listen for new-style nbd-client connections.
 
bool logged_oversized =false
 whether we logged oversized requests already
 

Macro Definition Documentation

#define BUFSIZE   ((1024*1024)+sizeof(struct nbd_reply))

Size of buffer that can hold requests.

Definition at line 156 of file nbd-server.c.

Referenced by mainloop().

#define CFILE   SYSCONFDIR "/nbd-server/config"

Definition at line 113 of file nbd-server.c.

Referenced by main(), and usage().

#define DEBUG (   ...)
#define DIFFPAGESIZE   4096

diff file uses those chunks

Definition at line 157 of file nbd-server.c.

Referenced by copyonwrite_prepare(), expread(), and expwrite().

#define ERROR (   client,
  reply,
  errcode 
)    { reply.error = htonl(errcode); SEND(client->net,reply); reply.error = 0; }

error macro.

Definition at line 1704 of file nbd-server.c.

Referenced by mainloop().

#define F_AUTOREADONLY   8

flag to tell us a file is set to autoreadonly

Definition at line 164 of file nbd-server.c.

Referenced by mainloop(), and setupexport().

#define F_COPYONWRITE   4

flag to tell us a file is exported using copyonwrite

Definition at line 162 of file nbd-server.c.

Referenced by cmdline(), dump_section(), expflush(), expread(), expwrite(), mainloop(), parse_cfile(), serveconnection(), and setupexport().

#define F_FIXED   4096

Client supports fixed new-style protocol (and can thus send us extra options.

Definition at line 173 of file nbd-server.c.

#define F_FLUSH   128

Whether server wants FLUSH to be sent by the client.

Definition at line 168 of file nbd-server.c.

Referenced by negotiate(), and parse_cfile().

#define F_FUA   256

Whether server wants FUA to be sent by the client.

Definition at line 169 of file nbd-server.c.

Referenced by negotiate(), and parse_cfile().

#define F_LIST   2

Allow clients to list the exports on a server.

Definition at line 177 of file nbd-server.c.

Referenced by handle_list(), and parse_cfile().

#define F_MULTIFILE   2

flag to tell us a file is exported using -m

Definition at line 161 of file nbd-server.c.

Referenced by cmdline(), dump_section(), parse_cfile(), and setupexport().

#define F_OLDSTYLE   1

Global flags:

Allow oldstyle (port-based) exports

Definition at line 176 of file nbd-server.c.

Referenced by cmdline(), parse_cfile(), and setup_serve().

#define F_READONLY   1

Per-export flags:

flag to tell us a file is readonly

Definition at line 160 of file nbd-server.c.

Referenced by cmdline(), dump_section(), mainloop(), negotiate(), parse_cfile(), and setupexport().

#define F_ROTATIONAL   512

Whether server wants the client to implement the elevator algorithm.

Definition at line 170 of file nbd-server.c.

Referenced by negotiate(), and parse_cfile().

#define F_SDP   32

flag to tell us the export should be done using the Socket Direct Protocol for RDMA

Definition at line 166 of file nbd-server.c.

Referenced by parse_cfile(), and setup_serve().

#define F_SPARSE   16

flag to tell us copyronwrite should use a sparse file

Definition at line 165 of file nbd-server.c.

Referenced by expwrite(), and parse_cfile().

#define F_SYNC   64

Whether to fsync() after a write.

Definition at line 167 of file nbd-server.c.

Referenced by expwrite(), parse_cfile(), and rawexpwrite().

#define F_TEMPORARY   1024

Whether the backing file is temporary and should be created then unlinked.

Definition at line 171 of file nbd-server.c.

Referenced by parse_cfile(), and setupexport().

#define F_TRIM   2048

Whether server wants TRIM (discard) to be sent by the client.

Definition at line 172 of file nbd-server.c.

Referenced by negotiate(), and parse_cfile().

#define LINELEN   256

Size of static buffer used to read the authorization file (yuck)

Definition at line 154 of file nbd-server.c.

Referenced by authorized_client().

#define msg2 (   a,
 
)    g_message((char*)b)

Logging macros, now nothing goes to syslog unless you say ISSERVER.

Definition at line 134 of file nbd-server.c.

Referenced by mainloop(), and serveloop().

#define msg3 (   a,
  b,
 
)    g_message((char*)b,c)
#define msg4 (   a,
  b,
  c,
 
)    g_message((char*)b,c,d)

Definition at line 136 of file nbd-server.c.

Referenced by authorized_client(), and set_peername().

#define MY_NAME   "nbd_server"

Definition at line 102 of file nbd-server.c.

#define NEG_INIT   (1 << 0)

Definition at line 183 of file nbd-server.c.

Referenced by mainloop(), negotiate(), and serveloop().

#define NEG_MODERN   (1 << 2)

Definition at line 185 of file nbd-server.c.

Referenced by mainloop(), negotiate(), and serveloop().

#define NEG_OLD   (1 << 1)

Definition at line 184 of file nbd-server.c.

Referenced by mainloop(), and negotiate().

#define OFFT_MAX   ~((off_t)1<<(sizeof(off_t)*8-1))

The highest value a variable of type off_t can reach.

This is a signed integer, so set all bits except for the leftmost one.

Definition at line 153 of file nbd-server.c.

Referenced by handle_export_name(), main(), mainloop(), serveloop(), and size_autodetect().

#define SEND (   net,
  reply 
)
Value:
{ writeit( net, &reply, sizeof( reply )); \
if (client->transactionlogfd != -1) \
writeit(client->transactionlogfd, &reply, sizeof(reply)); }

sending macro.

Definition at line 1700 of file nbd-server.c.

Referenced by mainloop().

#define SYSCONFDIR   "/etc"

Default position of the config file.

Definition at line 111 of file nbd-server.c.

Enumeration Type Documentation

Error codes for config file parsing.

Enumerator:
CFILE_NOTFOUND 

The configuration file is not found.

CFILE_MISSING_GENERIC 

The (required) group "generic" is missing.

CFILE_KEY_MISSING 

A (required) key is missing.

CFILE_VALUE_INVALID 

A value is syntactically invalid.

CFILE_VALUE_UNSUPPORTED 

A value is not supported in this build.

CFILE_PROGERR 

Programmer error.

CFILE_NO_EXPORTS 

A config file was specified that does not define any exports.

CFILE_INCORRECT_PORT 

The reserved port was specified for an old-style export.

CFILE_DIR_UNKNOWN 

A directory requested does not exist.

CFILE_READDIR_ERR 

Error occurred during readdir()

Definition at line 615 of file nbd-server.c.

enum PARAM_TYPE

Type of configuration file values.

Enumerator:
PARAM_INT 

This parameter is an integer.

PARAM_INT64 

This parameter is an integer.

PARAM_STRING 

This parameter is a string.

PARAM_BOOL 

This parameter is a boolean.

Definition at line 265 of file nbd-server.c.

enum VIRT_STYLE

Types of virtuatlization.

Enumerator:
VIRT_NONE 

No virtualization.

VIRT_IPLIT 

Literal IP address as part of the filename.

VIRT_IPHASH 

Replacing all dots in an ip address by a / before doing the same as in IPLIT.

VIRT_CIDR 

Every subnet in its own directory.

Definition at line 201 of file nbd-server.c.

Function Documentation

int append_serve ( SERVER s,
GArray *  a 
)

append new server to array

Parameters
sserver
aserver array
Returns
0 success, -1 error

Definition at line 705 of file nbd-server.c.

References dup_serve(), err(), SERVER::listenaddr, SERVER::port, and SERVER::socket_family.

Referenced by main(), and parse_cfile().

int authorized_client ( CLIENT opts)

Check whether a client is allowed to connect.

Works with an authorization file which contains one line per machine, no wildcards.

Parameters
optsThe client who's trying to connect.
Returns
0 - authorization refused, 1 - OK

Definition at line 318 of file nbd-server.c.

References SERVER::authname, CLIENT::clientname, len, LINELEN, msg4, and CLIENT::server.

Referenced by serveloop().

SERVER* cmdline ( int  argc,
char *  argv[] 
)
static void consume ( int  f,
void *  buf,
size_t  len,
size_t  bufsiz 
)
inlinestatic

Consume data from an FD that we don't want.

Parameters
fa file descriptor
bufa buffer
lenthe number of bytes to consume
bufsizthe size of the buffer

Definition at line 395 of file nbd-server.c.

References readit().

Referenced by mainloop().

int copyonwrite_prepare ( CLIENT client)
void daemonize ( SERVER serve)

Go daemon (unless we specified at compile time that we didn't want this)

Parameters
servethe first server of our configuration. If its port is zero, then do not daemonize, because we're doing inetd then. This parameter is only used to create a PID file of the form /var/run/nbd-server.<port>.pid; it's not modified in any way.

Definition at line 2452 of file nbd-server.c.

References err(), pidfname, pidftemplate, and SERVER::port.

Referenced by main().

void destroy_pid_t ( gpointer  data)

Destroy a pid_t*.

Parameters
dataa pointer to pid_t which should be freed

Definition at line 2156 of file nbd-server.c.

Referenced by setup_servers().

GArray* do_cfile_dir ( gchar *  dir,
GError **  e 
)

Parse config file snippets in a directory.

Uses readdir() and friends to find files and open them, then passes them on to parse_cfile with have_global set false

Definition at line 773 of file nbd-server.c.

References CFILE_DIR_UNKNOWN, CFILE_READDIR_ERR, and parse_cfile().

Referenced by parse_cfile().

int do_run ( gchar *  command,
gchar *  file 
)

Run a command.

This is used for the prerun'' andpostrun'' config file options

Parameters
commandthe command to be ran. Read from the config file
filethe file name we're about to export

Definition at line 2003 of file nbd-server.c.

Referenced by serveconnection().

void dosockopts ( int  socket)

Definition at line 2285 of file nbd-server.c.

References err().

Referenced by open_modern(), and setup_serve().

void dousers ( void  )

Set up user-ID and/or group-ID.

Definition at line 2498 of file nbd-server.c.

References err(), rungroup, and runuser.

Referenced by main().

void dump_section ( SERVER serve,
gchar *  section_header 
)
SERVER* dup_serve ( SERVER s)
int expflush ( CLIENT client)

Flush data to a client.

Parameters
clientThe client we're going to write for.
Returns
0 on success, nonzero on failure

Definition at line 1466 of file nbd-server.c.

References CLIENT::difffile, CLIENT::export, F_COPYONWRITE, FILE_INFO::fhandle, SERVER::flags, and CLIENT::server.

Referenced by mainloop().

int expread ( off_t  a,
char *  buf,
size_t  len,
CLIENT client 
)

Read an amount of bytes at a given offset from the right file.

This abstracts the read-side of the copyonwrite stuff, and calls rawexpread() with the right parameters to do the actual work.

Parameters
aThe offset where the read should start
bufA buffer to read into
lenThe size of buf
clientThe client we're going to read for
Returns
0 on success, nonzero on failure

Definition at line 1366 of file nbd-server.c.

References DEBUG, CLIENT::difffile, DIFFPAGESIZE, CLIENT::difmap, F_COPYONWRITE, SERVER::flags, myseek(), rawexpread_fully(), and CLIENT::server.

Referenced by mainloop().

int exptrim ( struct nbd_request req,
CLIENT client 
)
int expwrite ( off_t  a,
char *  buf,
size_t  len,
CLIENT client,
int  fua 
)

Write an amount of bytes at a given offset to the right file.

This abstracts the write-side of the copyonwrite option, and calls rawexpwrite() with the right parameters to do the actual work.

Parameters
aThe offset where the write should start
bufThe buffer to write from
lenThe length of buf
clientThe client we're going to write for.
fuaFlag to indicate 'Force Unit Access'
Returns
0 on success, nonzero on failure

Definition at line 1408 of file nbd-server.c.

References DEBUG, CLIENT::difffile, CLIENT::difffilelen, DIFFPAGESIZE, CLIENT::difmap, F_COPYONWRITE, F_SPARSE, F_SYNC, fdatasync, SERVER::flags, myseek(), rawexpread_fully(), rawexpwrite_fully(), and CLIENT::server.

Referenced by mainloop().

int get_filepos ( GArray *  export,
off_t  a,
int *  fhandle,
off_t *  foffset,
size_t *  maxbytes 
)

Get the file handle and offset, given an export offset.

Parameters
exportAn array of export files
aThe offset to get corresponding file/offset for
fhandle[out] File descriptor
foffset[out] Offset into fhandle
maxbytes[out] Tells how many bytes can be read/written from fhandle starting at foffset (0 if there is no limit)
Returns
0 on success, -1 on failure

Definition at line 1171 of file nbd-server.c.

References FILE_INFO::fhandle, and FILE_INFO::startoff.

Referenced by rawexpread(), and rawexpwrite().

static const char* getcommandname ( uint64_t  command)
inlinestatic

Translate a command name into human readable form.

Parameters
commandThe command number (after applying NBD_CMD_MASK_COMMAND)
Returns
pointer to the command name

Definition at line 295 of file nbd-server.c.

References NBD_CMD_DISC, NBD_CMD_FLUSH, NBD_CMD_READ, and NBD_CMD_WRITE.

Referenced by mainloop().

void glib_message_syslog_redirect ( const gchar *  log_domain,
GLogLevelFlags  log_level,
const gchar *  message,
gpointer  user_data 
)

Definition at line 2525 of file nbd-server.c.

Referenced by main().

static CLIENT* handle_export_name ( uint32_t  opt,
int  net,
GArray *  servers,
uint32_t  cflags 
)
static
static void handle_list ( uint32_t  opt,
int  net,
GArray *  servers,
uint32_t  cflags 
)
static
void killchild ( gpointer  key,
gpointer  value,
gpointer  user_data 
)

Kill a child.

Called from sigterm_handler::g_hash_table_foreach.

Parameters
keythe key
valuethe value corresponding to the above key
user_dataa pointer which we always set to 1, so that we know what will happen next.

Definition at line 1087 of file nbd-server.c.

Referenced by sigterm_handler().

int main ( int  argc,
char *  argv[] 
)
int mainloop ( CLIENT client)
void myseek ( int  handle,
off_t  a 
)

seek to a position in a file, with error handling.

Parameters
handlea filedescriptor
aposition to seek to
Todo:
get rid of this; lastpoint is a global variable right now, but it shouldn't be. If we pass it on as a parameter, that makes things a lot easier.

Definition at line 1216 of file nbd-server.c.

References err().

Referenced by expread(), expwrite(), rawexpread(), and rawexpwrite().

CLIENT* negotiate ( int  net,
CLIENT client,
GArray *  servers,
int  phase 
)
void open_modern ( void  )

Definition at line 2384 of file nbd-server.c.

References dosockopts(), err(), modern_listen, modernport, and modernsock.

Referenced by setup_servers().

GArray * parse_cfile ( gchar *  f,
bool  have_global,
GError **  e 
)

Parse the config file.

Parameters
fthe name of the config file
ea GError.
See Also
CFILE_ERRORS for what error values this function can return.
Returns
a Array of SERVER* pointers, If the config file is empty or does not exist, returns an empty GHashTable; if the config file contains an error, returns NULL, and e is set appropriately

Definition at line 842 of file nbd-server.c.

References append_serve(), SERVER::authname, CFILE_MISSING_GENERIC, CFILE_NO_EXPORTS, CFILE_NOTFOUND, CFILE_VALUE_INVALID, CFILE_VALUE_UNSUPPORTED, SERVER::cidrlen, do_cfile_dir(), err(), SERVER::expected_size, SERVER::exportname, F_COPYONWRITE, F_FLUSH, F_FUA, F_LIST, F_MULTIFILE, F_OLDSTYLE, F_READONLY, F_ROTATIONAL, F_SDP, F_SPARSE, F_SYNC, F_TEMPORARY, F_TRIM, SERVER::flags, PARAM::flagval, glob_flags, SERVER::listenaddr, SERVER::max_connections, modern_listen, modernport, PARAM_BOOL, PARAM_INT, PARAM_INT64, PARAM_OFFT, PARAM_STRING, SERVER::port, SERVER::postrun, SERVER::prerun, PARAM::required, rungroup, runuser, SERVER::servename, SERVER::socket_family, SERVER::transactionlog, VIRT_CIDR, VIRT_IPHASH, VIRT_IPLIT, VIRT_NONE, and SERVER::virtstyle.

Referenced by do_cfile_dir(), and main().

ssize_t rawexpread ( off_t  a,
char *  buf,
size_t  len,
CLIENT client 
)

Read an amount of bytes at a given offset from the right file.

This abstracts the read-side of the multiple files option.

Parameters
aThe offset where the read should start
bufA buffer to read into
lenThe size of buf
clientThe client we're serving for
Returns
The number of bytes actually read, or -1 in case of an error.

Definition at line 1325 of file nbd-server.c.

References DEBUG, CLIENT::export, get_filepos(), and myseek().

Referenced by rawexpread_fully().

int rawexpread_fully ( off_t  a,
char *  buf,
size_t  len,
CLIENT client 
)

Call rawexpread repeatedly until all data has been read.

Returns
0 on success, nonzero on failure

Definition at line 1345 of file nbd-server.c.

References rawexpread().

Referenced by expread(), and expwrite().

ssize_t rawexpwrite ( off_t  a,
char *  buf,
size_t  len,
CLIENT client,
int  fua 
)

Write an amount of bytes at a given offset to the right file.

This abstracts the write-side of the multiple file option.

Parameters
aThe offset where the write should start
bufThe buffer to write from
lenThe length of buf
clientThe client we're serving for
fuaFlag to indicate 'Force Unit Access'
Returns
The number of bytes actually written, or -1 in case of an error

Definition at line 1233 of file nbd-server.c.

References DEBUG, CLIENT::export, F_SYNC, fdatasync, SERVER::flags, get_filepos(), myseek(), and CLIENT::server.

Referenced by rawexpwrite_fully().

int rawexpwrite_fully ( off_t  a,
char *  buf,
size_t  len,
CLIENT client,
int  fua 
)

Call rawexpwrite repeatedly until all data has been written.

Parameters
aThe offset where the write should start
bufThe buffer to write from
lenThe length of buf
clientThe client we're serving for
fuaFlag to indicate 'Force Unit Access'
Returns
0 on success, nonzero on failure

Definition at line 1303 of file nbd-server.c.

References rawexpwrite().

Referenced by expwrite().

static void readit ( int  f,
void *  buf,
size_t  len 
)
inlinestatic

Read data from a file descriptor into a buffer.

Parameters
fa file descriptor
bufa buffer
lenthe number of bytes to be read

Definition at line 372 of file nbd-server.c.

References DEBUG, and err().

Referenced by consume(), and mainloop().

void remove_server ( gpointer  s)

Remove a SERVER from memory.

Used from the hash table

Definition at line 633 of file nbd-server.c.

References SERVER::authname, SERVER::exportname, SERVER::listenaddr, SERVER::postrun, SERVER::prerun, and SERVER::transactionlog.

static void send_reply ( uint32_t  opt,
int  net,
uint32_t  reply_type,
size_t  datasize,
void *  data 
)
static

Definition at line 1511 of file nbd-server.c.

References htonll, and magic.

Referenced by handle_list(), and negotiate().

void serve_err ( SERVER serve,
const char *  msg 
)

Definition at line 2489 of file nbd-server.c.

References err(), SERVER::exportname, and SERVER::port.

void serveconnection ( CLIENT client)

Serve a connection.

Todo:
allow for multithreading, perhaps use libevent. Not just yet, though; follow the road map.
Parameters
clienta connected client

Definition at line 2023 of file nbd-server.c.

References copyonwrite_prepare(), do_run(), CLIENT::exportname, F_COPYONWRITE, SERVER::flags, mainloop(), CLIENT::net, SERVER::postrun, SERVER::prerun, CLIENT::server, setmysockopt(), setupexport(), SERVER::transactionlog, and CLIENT::transactionlogfd.

Referenced by main(), and serveloop().

int serveloop ( GArray *  servers)
void set_peername ( int  net,
CLIENT client 
)

Find the name of the file we have to serve.

This will use g_strdup_printf to put the IP address of the client inside a filename containing "%s" (in the form as specified by the "virtstyle" option). That name is then written to client->exportname.

Parameters
netA socket connected to an nbd client
clientinformation about the client. The IP address in human-readable format will be written to a new char* buffer, the address of which will be stored in client->clientname.

Definition at line 2065 of file nbd-server.c.

References SERVER::cidrlen, CLIENT::clientname, err(), SERVER::exportname, CLIENT::exportname, msg3, msg4, CLIENT::server, VIRT_CIDR, VIRT_IPHASH, VIRT_IPLIT, VIRT_NONE, and SERVER::virtstyle.

Referenced by main(), and serveloop().

int setup_serve ( SERVER serve)

Connect a server's socket.

Parameters
servethe server we want to connect.

Definition at line 2323 of file nbd-server.c.

References DEBUG, dosockopts(), err(), F_OLDSTYLE, F_SDP, SERVER::flags, glob_flags, SERVER::listenaddr, SERVER::port, SERVER::servename, SERVER::socket, and SERVER::socket_family.

Referenced by setup_servers().

void setup_servers ( GArray *  servers)

Connect our servers.

Definition at line 2419 of file nbd-server.c.

References children, destroy_pid_t(), err(), open_modern(), setup_serve(), sigchld_handler(), and sigterm_handler().

Referenced by main().

void setupexport ( CLIENT client)

Set up client export array, which is an array of FILE_INFO.

Also, split a single exportfile into multiple ones, if that was asked.

Parameters
clientinformation on the client which we want to setup export for

Definition at line 1877 of file nbd-server.c.

References DEBUG, err(), SERVER::expected_size, CLIENT::export, CLIENT::exportname, CLIENT::exportsize, F_AUTOREADONLY, F_COPYONWRITE, F_MULTIFILE, F_READONLY, F_TEMPORARY, FILE_INFO::fhandle, SERVER::flags, msg3, CLIENT::server, size_autodetect(), and FILE_INFO::startoff.

Referenced by serveconnection().

void sigchld_handler ( int  s)

Signal handler for SIGCHLD.

Parameters
sthe signal we're handling (must be SIGCHLD, or something is severely wrong)

Definition at line 1060 of file nbd-server.c.

References children, DEBUG, and msg3.

Referenced by setup_servers().

void sigterm_handler ( int  s)

Handle SIGTERM and dispatch it to our children.

Parameters
sthe signal we're handling (must be SIGTERM, or something is severely wrong).

Definition at line 1100 of file nbd-server.c.

References children, killchild(), and pidfname.

Referenced by setup_servers().

off_t size_autodetect ( int  fhandle)

Detect the size of a file.

Parameters
fhandleAn open filedescriptor
Returns
the size of the file, or OFFT_MAX if detection was impossible.

Definition at line 1119 of file nbd-server.c.

References __attribute__, DEBUG, err(), and OFFT_MAX.

Referenced by setupexport().

void usage ( )

Print out a message about how to use nbd-server.

Split out to a separate function so that we can call it from multiple places

Definition at line 427 of file nbd-server.c.

References CFILE, and VERSION.

static void writeit ( int  f,
void *  buf,
size_t  len 
)
inlinestatic

Write data from a buffer into a filedescriptor.

Parameters
fa file descriptor
bufa buffer containing data
lenthe number of bytes to be written

Definition at line 412 of file nbd-server.c.

References DEBUG, and err().

Referenced by mainloop().

Variable Documentation

GHashTable* children

Definition at line 178 of file nbd-server.c.

Referenced by serveloop(), setup_servers(), sigchld_handler(), and sigterm_handler().

gchar* config_file_pos

Where our config file actually is.

Definition at line 116 of file nbd-server.c.

Referenced by cmdline(), and main().

char default_authname[] = SYSCONFDIR "/nbd-server/allow"

default name of allow file

Definition at line 181 of file nbd-server.c.

Referenced by cmdline().

int dontfork = 0

Definition at line 126 of file nbd-server.c.

Referenced by cmdline(), main(), and serveloop().

int glob_flags =0

global flags

Definition at line 123 of file nbd-server.c.

Referenced by cmdline(), handle_list(), parse_cfile(), and setup_serve().

bool logged_oversized =false

whether we logged oversized requests already

Definition at line 196 of file nbd-server.c.

Referenced by mainloop().

char* modern_listen

listenaddr value for modernsock

Definition at line 192 of file nbd-server.c.

Referenced by open_modern(), and parse_cfile().

char* modernport =NBD_DEFAULT_PORT

Port number on which to listen for new-style nbd-client connections.

Definition at line 193 of file nbd-server.c.

Referenced by open_modern(), and parse_cfile().

int modernsock =0

Socket for the modern handler.

Not used if a client was only specified on the command line; only port used if oldstyle is set to false (and then the command-line client isn't used, gna gna)

Definition at line 187 of file nbd-server.c.

Referenced by open_modern(), and serveloop().

char pidfname[256]

name of our PID file

Definition at line 179 of file nbd-server.c.

Referenced by daemonize(), and sigterm_handler().

char pidftemplate[256]

template to be used for the filename of the PID file

Definition at line 180 of file nbd-server.c.

Referenced by cmdline(), daemonize(), and main().

gchar* rungroup =NULL

What group we're running as.

Definition at line 121 of file nbd-server.c.

Referenced by dousers(), and parse_cfile().

gchar* runuser =NULL

What user we're running as.

Definition at line 119 of file nbd-server.c.

Referenced by dousers(), and parse_cfile().