Network Block Device  @PACKAGE_VERSION@
nbdsrv.h
Go to the documentation of this file.
1 #ifndef NBDSRV_H
2 #define NBDSRV_H
3 
4 #include "lfs.h"
5 
6 #include <glib.h>
7 #include <stdbool.h>
8 #include <stdint.h>
9 
10 #include <sys/socket.h>
11 #include <sys/types.h>
12 #include "nbd.h"
13 
14 /* Structures */
15 
16 /**
17  * Types of virtuatlization
18  **/
19 typedef enum {
20  VIRT_NONE=0, /**< No virtualization */
21  VIRT_IPLIT, /**< Literal IP address as part of the filename */
22  VIRT_IPHASH, /**< Replacing all dots in an ip address by a / before
23  doing the same as in IPLIT */
24  VIRT_CIDR, /**< Every subnet in its own directory */
25 } VIRT_STYLE;
26 
27 /**
28  * Variables associated with a server.
29  **/
30 typedef struct {
31  gchar* exportname; /**< (unprocessed) filename of the file we're exporting */
32  uint64_t expected_size; /**< size of the exported file as it was told to
33  us through configuration */
34  gchar* listenaddr; /**< The IP address we're listening on */
35  char* authname; /**< filename of the authorization file */
36  int flags; /**< flags associated with this exported file */
37  VIRT_STYLE virtstyle;/**< The style of virtualization, if any */
38  uint8_t cidrlen; /**< The length of the mask when we use
39  CIDR-style virtualization */
40  gchar* prerun; /**< command to be ran after connecting a client,
41  but before starting to serve */
42  gchar* postrun; /**< command that will be ran after the client
43  disconnects */
44  gchar* servename; /**< name of the export as selected by nbd-client */
45  int max_connections; /**< maximum number of opened connections */
46  gchar* transactionlog;/**< filename for transaction log */
47  gchar* cowdir; /**< directory for copy-on-write diff files. */
48 } SERVER;
49 
50 /**
51  * Variables associated with a client connection
52  */
53 typedef struct {
54  uint64_t exportsize; /**< size of the file we're exporting */
55  char *clientname; /**< peer, in human-readable format */
56  struct sockaddr_storage clientaddr; /**< peer, in binary format, network byte order */
57  char *exportname; /**< (processed) filename of the file we're exporting */
58  GArray *export; /**< array of FILE_INFO of exported files;
59  array size is always 1 unless we're
60  doing the multiple file option */
61  int net; /**< The actual client socket */
62  SERVER *server; /**< The server this client is getting data from */
63  char* difffilename; /**< filename of the copy-on-write file, if any */
64  int difffile; /**< filedescriptor of copyonwrite file. @todo
65  shouldn't this be an array too? (cfr export) Or
66  make -m and -c mutually exclusive */
67  uint32_t difffilelen; /**< number of pages in difffile */
68  uint32_t *difmap; /**< see comment on the global difmap for this one */
69  gboolean modern; /**< client was negotiated using modern negotiation protocol */
70  int transactionlogfd;/**< fd for transaction log */
71  int clientfeats; /**< Features supported by this client */
72  pthread_mutex_t lock;
73 } CLIENT;
74 
75 /**
76  * Variables associated with an open file
77  **/
78 typedef struct {
79  int fhandle; /**< file descriptor */
80  off_t startoff; /**< starting offset of this file */
81 } FILE_INFO;
82 
83 /* Constants and macros */
84 
85 /**
86  * Error domain common for all NBD server errors.
87  **/
88 #define NBDS_ERR g_quark_from_static_string("server-error-quark")
89 
90 /**
91  * NBD server error codes.
92  **/
93 typedef enum {
94  NBDS_ERR_CFILE_NOTFOUND, /**< The configuration file is not found */
95  NBDS_ERR_CFILE_MISSING_GENERIC, /**< The (required) group "generic" is missing */
96  NBDS_ERR_CFILE_KEY_MISSING, /**< A (required) key is missing */
97  NBDS_ERR_CFILE_VALUE_INVALID, /**< A value is syntactically invalid */
98  NBDS_ERR_CFILE_VALUE_UNSUPPORTED, /**< A value is not supported in this build */
99  NBDS_ERR_CFILE_NO_EXPORTS, /**< A config file was specified that does not
100  define any exports */
101  NBDS_ERR_CFILE_INCORRECT_PORT, /**< The reserved port was specified for an
102  old-style export. */
103  NBDS_ERR_CFILE_DIR_UNKNOWN, /**< A directory requested does not exist*/
104  NBDS_ERR_CFILE_READDIR_ERR, /**< Error occurred during readdir() */
105  NBDS_ERR_SO_LINGER, /**< Failed to set SO_LINGER to a socket */
106  NBDS_ERR_SO_REUSEADDR, /**< Failed to set SO_REUSEADDR to a socket */
107  NBDS_ERR_SO_KEEPALIVE, /**< Failed to set SO_KEEPALIVE to a socket */
108  NBDS_ERR_GAI, /**< Failed to get address info */
109  NBDS_ERR_SOCKET, /**< Failed to create a socket */
110  NBDS_ERR_BIND, /**< Failed to bind an address to socket */
111  NBDS_ERR_LISTEN, /**< Failed to start listening on a socket */
112  NBDS_ERR_SYS, /**< Underlying system call or library error */
113 } NBDS_ERRS;
114 
115 /**
116  * Logging macros.
117  *
118  * @todo remove this. We should use g_log in all cases, and use the
119  * logging mangler to redirect to syslog if and when necessary.
120  */
121 #ifdef ISSERVER
122 #define msg(prio, ...) syslog(prio, __VA_ARGS__)
123 #else
124 #define msg(prio, ...) g_log(G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, __VA_ARGS__)
125 #endif
126 #define MY_NAME "nbd_server"
127 
128 /** Per-export flags: */
129 #define F_READONLY 1 /**< flag to tell us a file is readonly */
130 #define F_MULTIFILE 2 /**< flag to tell us a file is exported using -m */
131 #define F_COPYONWRITE 4 /**< flag to tell us a file is exported using
132  copyonwrite */
133 #define F_AUTOREADONLY 8 /**< flag to tell us a file is set to autoreadonly */
134 #define F_SPARSE 16 /**< flag to tell us copyronwrite should use a sparse file */
135 #define F_SDP 32 /**< flag to tell us the export should be done using the Socket Direct Protocol for RDMA */
136 #define F_SYNC 64 /**< Whether to fsync() after a write */
137 #define F_FLUSH 128 /**< Whether server wants FLUSH to be sent by the client */
138 #define F_FUA 256 /**< Whether server wants FUA to be sent by the client */
139 #define F_ROTATIONAL 512 /**< Whether server wants the client to implement the elevator algorithm */
140 #define F_TEMPORARY 1024 /**< Whether the backing file is temporary and should be created then unlinked */
141 #define F_TRIM 2048 /**< Whether server wants TRIM (discard) to be sent by the client */
142 #define F_FIXED 4096 /**< Client supports fixed new-style protocol (and can thus send us extra options */
143 #define F_TREEFILES 8192 /**< flag to tell us a file is exported using -t */
145 /* Functions */
146 
147 /**
148  * Check whether a given address matches a given netmask.
149  *
150  * @param mask the address or netmask to check against, in ASCII representation
151  * @param addr the address to check
152  *
153  * @return true if the address matches the mask, false otherwise; in case of
154  * failure to parse netmask, returns false with err set appropriately.
155  * @todo decide what to do with v6-mapped IPv4 addresses.
156  */
157 bool address_matches(const char* mask, const struct sockaddr* addr, GError** err);
158 
159 /**
160  * Gets a byte to allow for address masking.
161  *
162  * @param masklen the length of the requested mask.
163  * @return if the length of the mask is 8 or longer, 0xFF. Otherwise, a byte
164  * with `masklen' number of leading bits set to 1, everything else set to 0.
165  */
166 uint8_t getmaskbyte(int masklen) G_GNUC_PURE;
167 
168 /**
169  * Check whether a client is allowed to connect. Works with an authorization
170  * file which contains one line per machine or network, with CIDR-style
171  * netmasks.
172  *
173  * @param opts The client who's trying to connect.
174  * @return 0 - authorization refused, 1 - OK
175  **/
176 int authorized_client(CLIENT *opts);
177 
178 /**
179  * duplicate server
180  * @param s the old server we want to duplicate
181  * @return new duplicated server
182  **/
183 SERVER* dup_serve(const SERVER *const s);
184 
185 /**
186  * Detect the size of a file.
187  *
188  * @param fhandle An open filedescriptor
189  * @return the size of the file, or UINT64_MAX if detection was
190  * impossible.
191  **/
192 uint64_t size_autodetect(int fhandle);
193 
194 /**
195  * Punch a hole in the backend file (if supported by the current system).
196  *
197  * @param req the request for which this is being processed
198  * @param client the client for which we're processing this request
199  **/
200 int exptrim(struct nbd_request* req, CLIENT* client);
201 
202 /**
203  * seek to a position in a file, with error handling.
204  * @param handle a filedescriptor
205  * @param a position to seek to
206  * @todo get rid of this.
207  **/
208 void myseek(int handle, off_t a);
209 #endif //NBDSRV_H
The (required) group "generic" is missing.
Definition: nbdsrv.h:95
uint8_t getmaskbyte(int masklen) G_GNUC_PURE
Gets a byte to allow for address masking.
Definition: nbdsrv.c:98
gchar * servename
name of the export as selected by nbd-client
Definition: nbdsrv.h:44
pthread_mutex_t lock
Definition: nbdsrv.h:72
GArray * export
array of FILE_INFO of exported files; array size is always 1 unless we're doing the multiple file opt...
Definition: nbdsrv.h:58
Variables associated with a server.
Definition: nbdsrv.h:30
void err(const char *s)
Definition: cliserv.c:59
uint32_t difffilelen
number of pages in difffile
Definition: nbdsrv.h:67
void myseek(int handle, off_t a)
seek to a position in a file, with error handling.
Definition: nbdsrv.c:289
SERVER * server
The server this client is getting data from.
Definition: nbdsrv.h:62
Failed to set SO_LINGER to a socket.
Definition: nbdsrv.h:105
No virtualization.
Definition: nbdsrv.h:20
gchar * postrun
command that will be ran after the client disconnects
Definition: nbdsrv.h:42
int clientfeats
Features supported by this client.
Definition: nbdsrv.h:71
NBDS_ERRS
NBD server error codes.
Definition: nbdsrv.h:93
Failed to bind an address to socket.
Definition: nbdsrv.h:110
Error occurred during readdir()
Definition: nbdsrv.h:104
int fhandle
file descriptor
Definition: nbdsrv.h:79
off_t startoff
starting offset of this file
Definition: nbdsrv.h:80
The configuration file is not found.
Definition: nbdsrv.h:94
gchar * cowdir
directory for copy-on-write diff files.
Definition: nbdsrv.h:47
int flags
flags associated with this exported file
Definition: nbdsrv.h:36
Failed to start listening on a socket.
Definition: nbdsrv.h:111
A (required) key is missing.
Definition: nbdsrv.h:96
gchar * exportname
(unprocessed) filename of the file we're exporting
Definition: nbdsrv.h:31
int net
The actual client socket.
Definition: nbdsrv.h:61
int authorized_client(CLIENT *opts)
Check whether a client is allowed to connect.
Definition: nbdsrv.c:110
Underlying system call or library error.
Definition: nbdsrv.h:112
gchar * transactionlog
filename for transaction log
Definition: nbdsrv.h:46
Every subnet in its own directory.
Definition: nbdsrv.h:24
gchar * listenaddr
The IP address we're listening on.
Definition: nbdsrv.h:34
Failed to set SO_KEEPALIVE to a socket.
Definition: nbdsrv.h:107
char * clientname
peer, in human-readable format
Definition: nbdsrv.h:55
Variables associated with a client connection.
Definition: nbdsrv.h:53
int difffile
filedescriptor of copyonwrite file.
Definition: nbdsrv.h:64
bool address_matches(const char *mask, const struct sockaddr *addr, GError **err)
Check whether a given address matches a given netmask.
Definition: nbdsrv.c:30
Failed to get address info.
Definition: nbdsrv.h:108
Variables associated with an open file.
Definition: nbdsrv.h:78
uint32_t * difmap
see comment on the global difmap for this one
Definition: nbdsrv.h:68
VIRT_STYLE
Types of virtuatlization.
Definition: nbdsrv.h:19
Literal IP address as part of the filename.
Definition: nbdsrv.h:21
int exptrim(struct nbd_request *req, CLIENT *client)
Punch a hole in the backend file (if supported by the current system).
Definition: nbdsrv.c:237
int transactionlogfd
fd for transaction log
Definition: nbdsrv.h:70
The reserved port was specified for an old-style export.
Definition: nbdsrv.h:101
int max_connections
maximum number of opened connections
Definition: nbdsrv.h:45
VIRT_STYLE virtstyle
The style of virtualization, if any.
Definition: nbdsrv.h:37
Failed to set SO_REUSEADDR to a socket.
Definition: nbdsrv.h:106
uint64_t expected_size
size of the exported file as it was told to us through configuration
Definition: nbdsrv.h:32
gchar * prerun
command to be ran after connecting a client, but before starting to serve
Definition: nbdsrv.h:40
uint64_t exportsize
size of the file we're exporting
Definition: nbdsrv.h:54
SERVER * dup_serve(const SERVER *const s)
duplicate server
Definition: nbdsrv.c:154
char * authname
filename of the authorization file
Definition: nbdsrv.h:35
uint64_t size_autodetect(int fhandle)
Detect the size of a file.
Definition: nbdsrv.c:196
gboolean modern
client was negotiated using modern negotiation protocol
Definition: nbdsrv.h:69
A config file was specified that does not define any exports.
Definition: nbdsrv.h:99
char * difffilename
filename of the copy-on-write file, if any
Definition: nbdsrv.h:63
char handle[8]
Definition: nbd.h:39
Replacing all dots in an ip address by a / before doing the same as in IPLIT.
Definition: nbdsrv.h:22
uint8_t cidrlen
The length of the mask when we use CIDR-style virtualization.
Definition: nbdsrv.h:38
A value is not supported in this build.
Definition: nbdsrv.h:98
A directory requested does not exist.
Definition: nbdsrv.h:103
char * exportname
(processed) filename of the file we're exporting
Definition: nbdsrv.h:57
A value is syntactically invalid.
Definition: nbdsrv.h:97
Failed to create a socket.
Definition: nbdsrv.h:109