Don't forget to EXTRA_DIST the .in.sgml file, too
[nbd.git] / nbdsrv.h
blobf3be7382c90e0a9269f939d18d6c154697bb4052
1 #ifndef NBDSRV_H
2 #define NBDSRV_H
4 #include "lfs.h"
6 #include <glib.h>
7 #include <stdbool.h>
8 #include <stdint.h>
10 #include <sys/socket.h>
11 #include <sys/types.h>
12 #include "nbd.h"
14 /* Structures */
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;
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;
50 /**
51 * Variables associated with a client connection
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;
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;
83 /* Constants and macros */
85 /**
86 * Error domain common for all NBD server errors.
87 **/
88 #define NBDS_ERR g_quark_from_static_string("server-error-quark")
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;
116 * Logging macros.
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.
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"
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 */
148 * Check whether a given address matches a given netmask.
150 * @param mask the address or netmask to check against, in ASCII representation
151 * @param addr the address to check
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.
157 bool address_matches(const char* mask, const struct sockaddr* addr, GError** err);
160 * Gets a byte to allow for address masking.
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.
166 uint8_t getmaskbyte(int masklen) G_GNUC_PURE;
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.
173 * @param opts The client who's trying to connect.
174 * @return 0 - authorization refused, 1 - OK
176 int authorized_client(CLIENT *opts);
179 * duplicate server
180 * @param s the old server we want to duplicate
181 * @return new duplicated server
183 SERVER* dup_serve(const SERVER *const s);
186 * Detect the size of a file.
188 * @param fhandle An open filedescriptor
189 * @return the size of the file, or UINT64_MAX if detection was
190 * impossible.
192 uint64_t size_autodetect(int fhandle);
195 * Punch a hole in the backend file (if supported by the current system).
197 * @param req the request for which this is being processed
198 * @param client the client for which we're processing this request
200 int exptrim(struct nbd_request* req, CLIENT* client);
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.
208 void myseek(int handle, off_t a);
209 #endif //NBDSRV_H