server: Switch to fixed-length conn->exportname
[nbdkit/ericb.git] / server / backend.c
blob64267bfe6bed804a5757fcf4f575f9d79b379b79
1 /* nbdkit
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
6 * met:
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
30 * SUCH DAMAGE.
33 #include <config.h>
35 #include <assert.h>
36 #include <ctype.h>
37 #include <dlfcn.h>
38 #include <inttypes.h>
39 #include <stdio.h>
40 #include <string.h>
42 #include "internal.h"
43 #include "minmax.h"
45 /* Helpers for registering a new backend. */
47 /* Set all debug flags which apply to this backend. */
48 static void
49 set_debug_flags (void *dl, const char *name)
51 struct debug_flag *flag;
53 for (flag = debug_flags; flag != NULL; flag = flag->next) {
54 if (!flag->used && strcmp (name, flag->name) == 0) {
55 CLEANUP_FREE char *var = NULL;
56 int *sym;
58 /* Synthesize the name of the variable. */
59 if (asprintf (&var, "%s_debug_%s", name, flag->flag) == -1) {
60 perror ("asprintf");
61 exit (EXIT_FAILURE);
64 /* Find the symbol. */
65 sym = dlsym (dl, var);
66 if (sym == NULL) {
67 fprintf (stderr,
68 "%s: -D %s.%s: %s does not contain a "
69 "global variable called %s\n",
70 program_name, name, flag->flag, name, var);
71 exit (EXIT_FAILURE);
74 /* Set the flag. */
75 *sym = flag->value;
77 /* Mark this flag as used. */
78 flag->used = true;
83 void
84 backend_init (struct backend *b, struct backend *next, size_t index,
85 const char *filename, void *dl, const char *type)
87 b->next = next;
88 b->i = index;
89 b->type = type;
90 b->filename = strdup (filename);
91 if (b->filename == NULL) {
92 perror ("strdup");
93 exit (EXIT_FAILURE);
95 b->dl = dl;
97 debug ("registering %s %s", type, filename);
100 void
101 backend_load (struct backend *b, const char *name, void (*load) (void))
103 size_t i, len;
105 /* name is required. */
106 if (name == NULL) {
107 fprintf (stderr, "%s: %s: %s must have a .name field\n",
108 program_name, b->filename, b->type);
109 exit (EXIT_FAILURE);
112 len = strlen (name);
113 if (len == 0) {
114 fprintf (stderr, "%s: %s: %s.name field must not be empty\n",
115 program_name, b->filename, b->type);
116 exit (EXIT_FAILURE);
118 for (i = 0; i < len; ++i) {
119 unsigned char c = name[i];
121 if (!(isascii (c) && isalnum (c))) {
122 fprintf (stderr,
123 "%s: %s: %s.name ('%s') field "
124 "must contain only ASCII alphanumeric characters\n",
125 program_name, b->filename, b->type, name);
126 exit (EXIT_FAILURE);
130 /* Copy the module's name into local storage, so that name
131 * survives past unload.
133 b->name = strdup (name);
134 if (b->name == NULL) {
135 perror ("strdup");
136 exit (EXIT_FAILURE);
139 debug ("registered %s %s (name %s)", b->type, b->filename, b->name);
141 /* Set debug flags before calling load. */
142 set_debug_flags (b->dl, name);
144 /* Call the on-load callback if it exists. */
145 debug ("%s: load", name);
146 if (load)
147 load ();
150 void
151 backend_unload (struct backend *b, void (*unload) (void))
153 /* Acquiring this lock prevents any other backend callbacks from running
154 * simultaneously.
156 lock_unload ();
158 debug ("%s: unload %s", b->name, b->type);
159 if (unload)
160 unload ();
162 if (DO_DLCLOSE)
163 dlclose (b->dl);
164 free (b->filename);
166 unlock_unload ();
168 free (b->name);
172 backend_open (struct backend *b, struct connection *conn, int readonly)
174 struct b_conn_handle *h = &conn->handles[b->i];
175 int r;
177 debug ("%s: open readonly=%d", b->name, readonly);
179 assert (h->handle == NULL);
180 assert (h->can_write == -1);
181 if (readonly)
182 h->can_write = 0;
183 r = b->open (b, conn, readonly);
184 if (r == 0) {
185 assert (h->handle != NULL);
186 if (b->i) /* A filter must not succeed unless its backend did also */
187 assert (conn->handles[b->i - 1].handle);
189 else
190 assert (h->handle == NULL);
191 return r;
195 backend_prepare (struct backend *b, struct connection *conn)
197 struct b_conn_handle *h = &conn->handles[b->i];
199 debug ("%s: prepare readonly=%d", b->name, h->can_write == 0);
201 return b->prepare (b, conn, h->can_write == 0);
204 void
205 backend_close (struct backend *b, struct connection *conn)
207 struct b_conn_handle *h = &conn->handles[b->i];
209 debug ("%s: close", b->name);
211 b->close (b, conn);
212 reset_b_conn_handle (h);
215 void
216 backend_set_handle (struct backend *b, struct connection *conn, void *handle)
218 assert (b->i < conn->nr_handles);
219 assert (conn->handles[b->i].handle == NULL);
220 conn->handles[b->i].handle = handle;
223 bool
224 backend_valid_range (struct backend *b, struct connection *conn,
225 uint64_t offset, uint32_t count)
227 struct b_conn_handle *h = &conn->handles[b->i];
229 assert (h->exportsize >= 0); /* Guaranteed by negotiation phase */
230 return count > 0 && offset <= h->exportsize &&
231 offset + count <= h->exportsize;
234 /* Wrappers for all callbacks in a filter's struct nbdkit_next_ops. */
237 backend_reopen (struct backend *b, struct connection *conn, int readonly)
239 struct b_conn_handle *h = &conn->handles[b->i];
241 debug ("%s: reopen readonly=%d", b->name, readonly);
243 if (h->handle != NULL)
244 backend_close (b, conn);
245 return backend_open (b, conn, readonly);
248 int64_t
249 backend_get_size (struct backend *b, struct connection *conn)
251 struct b_conn_handle *h = &conn->handles[b->i];
253 debug ("%s: get_size", b->name);
255 if (h->exportsize == -1)
256 h->exportsize = b->get_size (b, conn);
257 return h->exportsize;
261 backend_can_write (struct backend *b, struct connection *conn)
263 struct b_conn_handle *h = &conn->handles[b->i];
265 debug ("%s: can_write", b->name);
267 if (h->can_write == -1)
268 h->can_write = b->can_write (b, conn);
269 return h->can_write;
273 backend_can_flush (struct backend *b, struct connection *conn)
275 struct b_conn_handle *h = &conn->handles[b->i];
277 debug ("%s: can_flush", b->name);
279 if (h->can_flush == -1)
280 h->can_flush = b->can_flush (b, conn);
281 return h->can_flush;
285 backend_is_rotational (struct backend *b, struct connection *conn)
287 struct b_conn_handle *h = &conn->handles[b->i];
289 debug ("%s: is_rotational", b->name);
291 if (h->is_rotational == -1)
292 h->is_rotational = b->is_rotational (b, conn);
293 return h->is_rotational;
297 backend_can_trim (struct backend *b, struct connection *conn)
299 struct b_conn_handle *h = &conn->handles[b->i];
300 int r;
302 debug ("%s: can_trim", b->name);
304 if (h->can_trim == -1) {
305 r = backend_can_write (b, conn);
306 if (r != 1) {
307 h->can_trim = 0;
308 return r;
310 h->can_trim = b->can_trim (b, conn);
312 return h->can_trim;
316 backend_can_zero (struct backend *b, struct connection *conn)
318 struct b_conn_handle *h = &conn->handles[b->i];
319 int r;
321 debug ("%s: can_zero", b->name);
323 if (h->can_zero == -1) {
324 r = backend_can_write (b, conn);
325 if (r != 1) {
326 h->can_zero = NBDKIT_ZERO_NONE;
327 return r; /* Relies on 0 == NBDKIT_ZERO_NONE */
329 h->can_zero = b->can_zero (b, conn);
331 return h->can_zero;
335 backend_can_fast_zero (struct backend *b, struct connection *conn)
337 struct b_conn_handle *h = &conn->handles[b->i];
338 int r;
340 debug ("%s: can_fast_zero", b->name);
342 if (h->can_fast_zero == -1) {
343 r = backend_can_zero (b, conn);
344 if (r < NBDKIT_ZERO_EMULATE) {
345 h->can_fast_zero = 0;
346 return r; /* Relies on 0 == NBDKIT_ZERO_NONE */
348 h->can_fast_zero = b->can_fast_zero (b, conn);
350 return h->can_fast_zero;
354 backend_can_extents (struct backend *b, struct connection *conn)
356 struct b_conn_handle *h = &conn->handles[b->i];
358 debug ("%s: can_extents", b->name);
360 if (h->can_extents == -1)
361 h->can_extents = b->can_extents (b, conn);
362 return h->can_extents;
366 backend_can_fua (struct backend *b, struct connection *conn)
368 struct b_conn_handle *h = &conn->handles[b->i];
369 int r;
371 debug ("%s: can_fua", b->name);
373 if (h->can_fua == -1) {
374 r = backend_can_write (b, conn);
375 if (r != 1) {
376 h->can_fua = NBDKIT_FUA_NONE;
377 return r; /* Relies on 0 == NBDKIT_FUA_NONE */
379 h->can_fua = b->can_fua (b, conn);
381 return h->can_fua;
385 backend_can_multi_conn (struct backend *b, struct connection *conn)
387 struct b_conn_handle *h = &conn->handles[b->i];
389 debug ("%s: can_multi_conn", b->name);
391 if (h->can_multi_conn == -1)
392 h->can_multi_conn = b->can_multi_conn (b, conn);
393 return h->can_multi_conn;
397 backend_can_cache (struct backend *b, struct connection *conn)
399 struct b_conn_handle *h = &conn->handles[b->i];
401 debug ("%s: can_cache", b->name);
403 if (h->can_cache == -1)
404 h->can_cache = b->can_cache (b, conn);
405 return h->can_cache;
409 backend_pread (struct backend *b, struct connection *conn,
410 void *buf, uint32_t count, uint64_t offset,
411 uint32_t flags, int *err)
413 int r;
415 assert (backend_valid_range (b, conn, offset, count));
416 assert (flags == 0);
417 debug ("%s: pread count=%" PRIu32 " offset=%" PRIu64,
418 b->name, count, offset);
420 r = b->pread (b, conn, buf, count, offset, flags, err);
421 if (r == -1)
422 assert (*err);
423 return r;
427 backend_pwrite (struct backend *b, struct connection *conn,
428 const void *buf, uint32_t count, uint64_t offset,
429 uint32_t flags, int *err)
431 struct b_conn_handle *h = &conn->handles[b->i];
432 bool fua = !!(flags & NBDKIT_FLAG_FUA);
433 int r;
435 assert (h->can_write == 1);
436 assert (backend_valid_range (b, conn, offset, count));
437 assert (!(flags & ~NBDKIT_FLAG_FUA));
438 if (fua)
439 assert (h->can_fua > NBDKIT_FUA_NONE);
440 debug ("%s: pwrite count=%" PRIu32 " offset=%" PRIu64 " fua=%d",
441 b->name, count, offset, fua);
443 r = b->pwrite (b, conn, buf, count, offset, flags, err);
444 if (r == -1)
445 assert (*err);
446 return r;
450 backend_flush (struct backend *b, struct connection *conn,
451 uint32_t flags, int *err)
453 struct b_conn_handle *h = &conn->handles[b->i];
454 int r;
456 assert (h->can_flush == 1);
457 assert (flags == 0);
458 debug ("%s: flush", b->name);
460 r = b->flush (b, conn, flags, err);
461 if (r == -1)
462 assert (*err);
463 return r;
467 backend_trim (struct backend *b, struct connection *conn,
468 uint32_t count, uint64_t offset, uint32_t flags,
469 int *err)
471 struct b_conn_handle *h = &conn->handles[b->i];
472 bool fua = !!(flags & NBDKIT_FLAG_FUA);
473 int r;
475 assert (h->can_write == 1);
476 assert (h->can_trim == 1);
477 assert (backend_valid_range (b, conn, offset, count));
478 assert (!(flags & ~NBDKIT_FLAG_FUA));
479 if (fua)
480 assert (h->can_fua > NBDKIT_FUA_NONE);
481 debug ("%s: trim count=%" PRIu32 " offset=%" PRIu64 " fua=%d",
482 b->name, count, offset, fua);
484 r = b->trim (b, conn, count, offset, flags, err);
485 if (r == -1)
486 assert (*err);
487 return r;
491 backend_zero (struct backend *b, struct connection *conn,
492 uint32_t count, uint64_t offset, uint32_t flags,
493 int *err)
495 struct b_conn_handle *h = &conn->handles[b->i];
496 bool fua = !!(flags & NBDKIT_FLAG_FUA);
497 bool fast = !!(flags & NBDKIT_FLAG_FAST_ZERO);
498 int r;
500 assert (h->can_write == 1);
501 assert (h->can_zero > NBDKIT_ZERO_NONE);
502 assert (backend_valid_range (b, conn, offset, count));
503 assert (!(flags & ~(NBDKIT_FLAG_MAY_TRIM | NBDKIT_FLAG_FUA |
504 NBDKIT_FLAG_FAST_ZERO)));
505 if (fua)
506 assert (h->can_fua > NBDKIT_FUA_NONE);
507 if (fast)
508 assert (h->can_fast_zero == 1);
509 debug ("%s: zero count=%" PRIu32 " offset=%" PRIu64
510 " may_trim=%d fua=%d fast=%d",
511 b->name, count, offset, !!(flags & NBDKIT_FLAG_MAY_TRIM), fua, fast);
513 r = b->zero (b, conn, count, offset, flags, err);
514 if (r == -1) {
515 assert (*err);
516 if (!fast)
517 assert (*err != ENOTSUP && *err != EOPNOTSUPP);
519 return r;
523 backend_extents (struct backend *b, struct connection *conn,
524 uint32_t count, uint64_t offset, uint32_t flags,
525 struct nbdkit_extents *extents, int *err)
527 struct b_conn_handle *h = &conn->handles[b->i];
528 int r;
530 assert (h->can_extents >= 0);
531 assert (backend_valid_range (b, conn, offset, count));
532 assert (!(flags & ~NBDKIT_FLAG_REQ_ONE));
533 debug ("%s: extents count=%" PRIu32 " offset=%" PRIu64 " req_one=%d",
534 b->name, count, offset, !!(flags & NBDKIT_FLAG_REQ_ONE));
536 if (h->can_extents == 0) {
537 /* By default it is safe assume that everything in the range is
538 * allocated.
540 r = nbdkit_add_extent (extents, offset, count, 0 /* allocated data */);
541 if (r == -1)
542 *err = errno;
543 return r;
545 r = b->extents (b, conn, count, offset, flags, extents, err);
546 if (r == -1)
547 assert (*err);
548 return r;
552 backend_cache (struct backend *b, struct connection *conn,
553 uint32_t count, uint64_t offset,
554 uint32_t flags, int *err)
556 struct b_conn_handle *h = &conn->handles[b->i];
557 int r;
559 assert (h->can_cache > NBDKIT_CACHE_NONE);
560 assert (backend_valid_range (b, conn, offset, count));
561 assert (flags == 0);
562 debug ("%s: cache count=%" PRIu32 " offset=%" PRIu64,
563 b->name, count, offset);
565 if (h->can_cache == NBDKIT_CACHE_EMULATE) {
566 static char buf[MAX_REQUEST_SIZE]; /* data sink, never read */
567 uint32_t limit;
569 while (count) {
570 limit = MIN (count, sizeof buf);
571 if (backend_pread (b, conn, buf, limit, offset, flags, err) == -1)
572 return -1;
573 count -= limit;
575 return 0;
577 r = b->cache (b, conn, count, offset, flags, err);
578 if (r == -1)
579 assert (*err);
580 return r;