2 * Copyright (C) 2013 Red Hat Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * * Neither the name of Red Hat nor the names of its contributors may be
17 * used to endorse or promote products derived from this software without
18 * specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
27 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * A simple but more realistic read-only file server.
47 #include <nbdkit-plugin.h>
49 static const char *filename
= NULL
;
51 /* Called for each key=value passed on the command line. This plugin
52 * only accepts file=<filename>, which is required.
55 example2_config (const char *key
, const char *value
)
57 if (strcmp (key
, "file") == 0) {
61 nbdkit_error ("unknown parameter '%s'", key
);
68 /* Check the user did pass a file=<FILENAME> parameter. */
70 example2_config_complete (void)
72 if (filename
== NULL
) {
73 nbdkit_error ("you must supply the file=<FILENAME> parameter after the plugin name on the command line");
80 #define example2_config_help \
81 "file=<FILENAME> (required) The filename to serve."
83 /* The per-connection handle. */
84 struct example2_handle
{
88 /* Create the per-connection handle. */
92 struct example2_handle
*h
;
94 h
= malloc (sizeof *h
);
96 nbdkit_error ("malloc: %m");
100 h
->fd
= open (filename
, O_RDONLY
|O_CLOEXEC
);
102 nbdkit_error ("open: %s: %m", filename
);
110 /* Free up the per-connection handle. */
112 example2_close (void *handle
)
114 struct example2_handle
*h
= handle
;
120 /* In fact NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS would work here.
121 * However for the benefit of people who blindly cut and paste code
122 * without bothering to read any documentation, leave this at a safe
125 #define THREAD_MODEL NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS
127 /* Read data from the file. */
129 example2_pread (void *handle
, void *buf
, size_t count
, off_t offset
)
131 struct example2_handle
*h
= handle
;
134 ssize_t r
= read (h
->fd
, buf
, count
);
136 nbdkit_error ("read error: %m");
140 nbdkit_error ("unexpected end of file");
150 static struct nbdkit_plugin plugin
= {
152 .config
= example2_config
,
153 .config_complete
= example2_config_complete
,
154 .config_help
= example2_config_help
,
155 .open
= example2_open
,
156 .close
= example2_close
,
157 .pread
= example2_pread
,
160 NBDKIT_REGISTER_PLUGIN(plugin
)