2 * Copyright (C) 2013 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
35 * A simple but more realistic read-only file server.
46 #include <sys/types.h>
49 #include <nbdkit-plugin.h>
51 static char *filename
= NULL
;
53 /* A debug flag which can be set on the command line using
54 * '-D example2.extra=1' to enable very verbose debugging to help
55 * developers. Use the debug flags for extra debugging which would
56 * only be useful for the original developers of the plugin. For
57 * ordinary debugging, just use nbdkit_debug and enable messages with
58 * the -v flag on the command line.
60 int example2_debug_extra
= 0;
63 example2_unload (void)
68 /* If you want to display extra information about the plugin when
69 * the user does ‘nbdkit example2 --dump-plugin’ then you can print
70 * ‘key=value’ lines here.
73 example2_dump_plugin (void)
75 printf ("example2_extra=hello\n");
78 /* Called for each key=value passed on the command line. This plugin
79 * only accepts file=<filename>, which is required.
82 example2_config (const char *key
, const char *value
)
84 if (strcmp (key
, "file") == 0) {
85 /* See FILENAMES AND PATHS in nbdkit-plugin(3). */
86 filename
= nbdkit_realpath (value
);
91 nbdkit_error ("unknown parameter '%s'", key
);
98 /* Check the user did pass a file=<FILENAME> parameter. */
100 example2_config_complete (void)
102 if (filename
== NULL
) {
103 nbdkit_error ("you must supply the file=<FILENAME> parameter "
104 "after the plugin name on the command line");
111 #define example2_config_help \
112 "file=<FILENAME> (required) The filename to serve."
114 /* The per-connection handle. */
115 struct example2_handle
{
119 /* Create the per-connection handle.
121 * Because this plugin can only serve readonly, we can ignore the
122 * 'readonly' parameter.
125 example2_open (int readonly
)
127 struct example2_handle
*h
;
129 h
= malloc (sizeof *h
);
131 nbdkit_error ("malloc: %m");
135 h
->fd
= open (filename
, O_RDONLY
|O_CLOEXEC
);
137 nbdkit_error ("open: %s: %m", filename
);
145 /* Free up the per-connection handle. */
147 example2_close (void *handle
)
149 struct example2_handle
*h
= handle
;
155 /* In fact NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS would work here.
156 * However for the benefit of people who blindly cut and paste code
157 * without bothering to read any documentation, leave this at a safe
160 #define THREAD_MODEL NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS
162 /* Get the file size. */
164 example2_get_size (void *handle
)
166 struct example2_handle
*h
= handle
;
169 if (fstat (h
->fd
, &statbuf
) == -1) {
170 nbdkit_error ("stat: %m");
174 /* Use the debug flags for extra debugging which would only be
175 * useful for the original developers of the plugin. For ordinary
176 * debugging, just use nbdkit_debug and enable messages with the -v
177 * flag on the command line. This is a contrived example of how to
180 if (example2_debug_extra
)
181 nbdkit_debug ("extra debugging: statbuf.st_size = %jd\n",
182 (intmax_t)statbuf
.st_size
);
184 return statbuf
.st_size
;
187 /* Read data from the file. */
189 example2_pread (void *handle
, void *buf
, uint32_t count
, uint64_t offset
)
191 struct example2_handle
*h
= handle
;
194 ssize_t r
= pread (h
->fd
, buf
, count
, offset
);
196 nbdkit_error ("pread: %m");
200 nbdkit_error ("pread: unexpected end of file");
211 static struct nbdkit_plugin plugin
= {
213 .version
= PACKAGE_VERSION
,
214 .unload
= example2_unload
,
215 .dump_plugin
= example2_dump_plugin
,
216 .config
= example2_config
,
217 .config_complete
= example2_config_complete
,
218 .config_help
= example2_config_help
,
219 .open
= example2_open
,
220 .close
= example2_close
,
221 .get_size
= example2_get_size
,
222 .pread
= example2_pread
,
223 /* In this plugin, errno is preserved properly along error return
224 * paths from failed system calls.
226 .errno_is_preserved
= 1,
229 NBDKIT_REGISTER_PLUGIN(plugin
)