2 * Copyright (C) 2013-2019 Red Hat Inc.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of Red Hat nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 #ifndef NBDKIT_INTERNAL_H
34 #define NBDKIT_INTERNAL_H
39 #include <sys/socket.h>
42 #define NBDKIT_API_VERSION 2
43 #include "nbdkit-plugin.h"
44 #include "nbdkit-filter.h"
48 #define UNIX_PATH_MAX 104
50 #define UNIX_PATH_MAX 108
58 #define SOCK_CLOEXEC 0
62 # include <valgrind.h>
63 /* http://valgrind.org/docs/manual/faq.html#faq.unhelpful */
64 # define DO_DLCLOSE !RUNNING_ON_VALGRIND
65 #elif defined(__SANITIZE_ADDRESS__)
71 #define container_of(ptr, type, member) ({ \
72 const typeof (((type *) 0)->member) *__mptr = (ptr); \
73 (type *) ((char *) __mptr - offsetof(type, member)); \
78 struct debug_flag
*next
;
79 char *name
; /* plugin or filter name */
80 char *flag
; /* flag name */
81 int value
; /* value of flag */
82 bool used
; /* if flag was successfully set */
86 LOG_TO_DEFAULT
, /* --log not specified: log to stderr, unless
87 we forked into the background in which
89 LOG_TO_STDERR
, /* --log=stderr forced on the command line */
90 LOG_TO_SYSLOG
, /* --log=syslog forced on the command line */
93 extern struct debug_flag
*debug_flags
;
94 extern const char *exportname
;
95 extern bool foreground
;
96 extern const char *ipaddr
;
97 extern enum log_to log_to
;
99 extern const char *port
;
100 extern bool readonly
;
101 extern const char *run
;
102 extern const char *selinux_label
;
105 extern const char *tls_certificates_dir
;
106 extern const char *tls_psk
;
107 extern bool tls_verify_peer
;
108 extern char *unixsocket
;
109 extern const char *user
, *group
;
112 extern struct backend
*backend
;
113 #define for_each_backend(b) for (b = backend; b != NULL; b = b->next)
116 extern volatile int quit
;
118 extern void set_up_quit_pipe (void);
119 extern void handle_quit (int sig
);
120 extern void set_quit (void);
123 extern void set_up_signals (void);
126 extern bool forked_into_background
;
127 extern void fork_into_background (void);
130 extern void run_command (void);
132 /* socket-activation.c */
133 #define FIRST_SOCKET_ACTIVATION_FD 3 /* defined by systemd ABI */
134 extern unsigned int get_socket_activation (void);
137 extern void change_user (void);
142 /* Flags for connection_send_function */
144 SEND_MORE
= 1, /* Hint to use MSG_MORE/corking to group send()s */
147 typedef int (*connection_recv_function
) (struct connection
*,
148 void *buf
, size_t len
)
149 __attribute__((__nonnull__ (1, 2)));
150 typedef int (*connection_send_function
) (struct connection
*,
151 const void *buf
, size_t len
,
153 __attribute__((__nonnull__ (1, 2)));
154 typedef void (*connection_close_function
) (struct connection
*)
155 __attribute__((__nonnull__ (1)));
158 pthread_mutex_t request_lock
;
159 pthread_mutex_t read_lock
;
160 pthread_mutex_t write_lock
;
161 pthread_mutex_t status_lock
;
162 int status
; /* 1 for more I/O with client, 0 for shutdown, -1 on error */
163 void *crypto_session
;
183 bool structured_replies
;
184 bool meta_context_base_allocation
;
187 connection_recv_function recv
;
188 connection_send_function send
;
189 connection_close_function close
;
192 extern int handle_single_connection (int sockin
, int sockout
);
193 extern int connection_set_handle (struct connection
*conn
,
194 size_t i
, void *handle
)
195 __attribute__((__nonnull__ (1 /* not 3 */)));
196 extern void *connection_get_handle (struct connection
*conn
, size_t i
)
197 __attribute__((__nonnull__ (1)));
198 extern int connection_get_status (struct connection
*conn
)
199 __attribute__((__nonnull__ (1)));
200 extern int connection_set_status (struct connection
*conn
, int value
)
201 __attribute__((__nonnull__ (1)));
203 /* protocol-handshake.c */
204 extern int protocol_handshake (struct connection
*conn
)
205 __attribute__((__nonnull__ (1)));
206 extern int protocol_compute_eflags (struct connection
*conn
, uint16_t *flags
)
207 __attribute__((__nonnull__ (1, 2)));
209 /* protocol-handshake-oldstyle.c */
210 extern int protocol_handshake_oldstyle (struct connection
*conn
)
211 __attribute__((__nonnull__ (1)));
213 /* protocol-handshake-newstyle.c */
214 extern int protocol_handshake_newstyle (struct connection
*conn
)
215 __attribute__((__nonnull__ (1)));
218 extern int protocol_recv_request_send_reply (struct connection
*conn
)
219 __attribute__((__nonnull__ (1)));
221 /* The context ID of base:allocation. As far as I can tell it doesn't
222 * matter what this is as long as nbdkit always returns the same
225 #define base_allocation_id 1
228 #define root_tls_certificates_dir sysconfdir "/pki/" PACKAGE_NAME
229 extern void crypto_init (bool tls_set_on_cli
);
230 extern void crypto_free (void);
231 extern int crypto_negotiate_tls (struct connection
*conn
,
232 int sockin
, int sockout
)
233 __attribute__((__nonnull__ (1)));
236 #define debug nbdkit_debug
239 #if !HAVE_VFPRINTF_PERCENT_M
241 #define vfprintf nbdkit_vfprintf
242 extern int nbdkit_vfprintf (FILE *f
, const char *fmt
, va_list args
)
243 __attribute__((__format__ (printf
, 2, 0)));
245 extern void log_stderr_verror (const char *fs
, va_list args
)
246 __attribute__((__format__ (printf
, 1, 0)));
247 extern void log_syslog_verror (const char *fs
, va_list args
)
248 __attribute__((__format__ (printf
, 1, 0)));
251 /* Next filter or plugin in the chain. This is always NULL for
252 * plugins and never NULL for filters.
254 struct backend
*next
;
256 /* A unique index used to fetch the handle from the connections
257 * object. The plugin (last in the chain) has index 0, and the
258 * filters have index 1, 2, ... depending how "far" they are from
263 void (*free
) (struct backend
*);
264 int (*thread_model
) (struct backend
*);
265 const char *(*name
) (struct backend
*);
266 const char *(*plugin_name
) (struct backend
*);
267 void (*usage
) (struct backend
*);
268 const char *(*version
) (struct backend
*);
269 void (*dump_fields
) (struct backend
*);
270 void (*config
) (struct backend
*, const char *key
, const char *value
);
271 void (*config_complete
) (struct backend
*);
272 const char *(*magic_config_key
) (struct backend
*);
273 int (*open
) (struct backend
*, struct connection
*conn
, int readonly
);
274 int (*prepare
) (struct backend
*, struct connection
*conn
);
275 int (*finalize
) (struct backend
*, struct connection
*conn
);
276 void (*close
) (struct backend
*, struct connection
*conn
);
278 int64_t (*get_size
) (struct backend
*, struct connection
*conn
);
279 int (*can_write
) (struct backend
*, struct connection
*conn
);
280 int (*can_flush
) (struct backend
*, struct connection
*conn
);
281 int (*is_rotational
) (struct backend
*, struct connection
*conn
);
282 int (*can_trim
) (struct backend
*, struct connection
*conn
);
283 int (*can_zero
) (struct backend
*, struct connection
*conn
);
284 int (*can_extents
) (struct backend
*, struct connection
*conn
);
285 int (*can_fua
) (struct backend
*, struct connection
*conn
);
286 int (*can_multi_conn
) (struct backend
*, struct connection
*conn
);
287 int (*can_cache
) (struct backend
*, struct connection
*conn
);
289 int (*pread
) (struct backend
*, struct connection
*conn
, void *buf
,
290 uint32_t count
, uint64_t offset
, uint32_t flags
, int *err
);
291 int (*pwrite
) (struct backend
*, struct connection
*conn
, const void *buf
,
292 uint32_t count
, uint64_t offset
, uint32_t flags
, int *err
);
293 int (*flush
) (struct backend
*, struct connection
*conn
, uint32_t flags
,
295 int (*trim
) (struct backend
*, struct connection
*conn
, uint32_t count
,
296 uint64_t offset
, uint32_t flags
, int *err
);
297 int (*zero
) (struct backend
*, struct connection
*conn
, uint32_t count
,
298 uint64_t offset
, uint32_t flags
, int *err
);
299 int (*extents
) (struct backend
*, struct connection
*conn
, uint32_t count
,
300 uint64_t offset
, uint32_t flags
,
301 struct nbdkit_extents
*extents
, int *err
);
302 int (*cache
) (struct backend
*, struct connection
*conn
, uint32_t count
,
303 uint64_t offset
, uint32_t flags
, int *err
);
307 extern struct backend
*plugin_register (size_t index
, const char *filename
,
308 void *dl
, struct nbdkit_plugin
*(*plugin_init
) (void))
309 __attribute__((__nonnull__ (2, 3, 4)));
310 extern void set_debug_flags (void *dl
, const char *name
)
311 __attribute__((__nonnull__ (1, 2)));
314 extern struct backend
*filter_register (struct backend
*next
, size_t index
,
315 const char *filename
, void *dl
,
316 struct nbdkit_filter
*(*filter_init
) (void))
317 __attribute__((__nonnull__ (1, 3, 4, 5)));
320 extern void lock_init_thread_model (void);
321 extern void lock_connection (void);
322 extern void unlock_connection (void);
323 extern void lock_request (struct connection
*conn
)
324 __attribute__((__nonnull__ (1)));
325 extern void unlock_request (struct connection
*conn
)
326 __attribute__((__nonnull__ (1)));
327 extern void lock_unload (void);
328 extern void unlock_unload (void);
331 extern int *bind_unix_socket (size_t *)
332 __attribute__((__nonnull__ (1)));
333 extern int *bind_tcpip_socket (size_t *)
334 __attribute__((__nonnull__ (1)));
335 extern void accept_incoming_connections (int *socks
, size_t nr_socks
)
336 __attribute__((__nonnull__ (1)));
337 extern void free_listening_sockets (int *socks
, size_t nr_socks
)
338 __attribute__((__nonnull__ (1)));
341 extern void threadlocal_init (void);
342 extern void threadlocal_new_server_thread (void);
343 extern void threadlocal_set_name (const char *name
)
344 __attribute__((__nonnull__ (1)));
345 extern const char *threadlocal_get_name (void);
346 extern void threadlocal_set_instance_num (size_t instance_num
);
347 extern size_t threadlocal_get_instance_num (void);
348 extern void threadlocal_set_sockaddr (const struct sockaddr
*addr
,
350 __attribute__((__nonnull__ (1)));
351 /*extern void threadlocal_get_sockaddr ();*/
352 extern void threadlocal_set_error (int err
);
353 extern int threadlocal_get_error (void);
354 extern void *threadlocal_buffer (size_t size
);
356 /* Declare program_name. */
357 #if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME == 1
359 #define program_name program_invocation_short_name
361 #define program_name "nbdkit"
364 #endif /* NBDKIT_INTERNAL_H */