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 [] = "/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[] = "/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().