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
41 #include <sys/types.h>
44 #include <nbdkit-plugin.h>
46 static char *filename
= NULL
;
54 /* Called for each key=value passed on the command line. This plugin
55 * only accepts file=<filename>, which is required.
58 file_config (const char *key
, const char *value
)
60 if (strcmp (key
, "file") == 0) {
61 /* See FILENAMES AND PATHS in nbdkit-plugin(3). */
62 filename
= nbdkit_absolute_path (value
);
67 nbdkit_error ("unknown parameter '%s'", key
);
74 /* Check the user did pass a file=<FILENAME> parameter. */
76 file_config_complete (void)
78 if (filename
== NULL
) {
79 nbdkit_error ("you must supply the file=<FILENAME> parameter after the plugin name on the command line");
86 #define file_config_help \
87 "file=<FILENAME> (required) The filename to serve."
89 /* The per-connection handle. */
94 /* Create the per-connection handle. */
96 file_open (int readonly
)
101 h
= malloc (sizeof *h
);
103 nbdkit_error ("malloc: %m");
107 flags
= O_CLOEXEC
|O_NOCTTY
;
113 h
->fd
= open (filename
, flags
);
115 nbdkit_error ("open: %s: %m", filename
);
123 /* Free up the per-connection handle. */
125 file_close (void *handle
)
127 struct handle
*h
= handle
;
133 #define THREAD_MODEL NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS
135 /* Get the file size. */
137 file_get_size (void *handle
)
139 struct handle
*h
= handle
;
142 if (fstat (h
->fd
, &statbuf
) == -1) {
143 nbdkit_error ("stat: %m");
147 return statbuf
.st_size
;
150 /* Read data from the file. */
152 file_pread (void *handle
, void *buf
, uint32_t count
, uint64_t offset
)
154 struct handle
*h
= handle
;
157 ssize_t r
= pread (h
->fd
, buf
, count
, offset
);
159 nbdkit_error ("pread: %m");
163 nbdkit_error ("pread: unexpected end of file");
174 /* Write data to the file. */
176 file_pwrite (void *handle
, const void *buf
, uint32_t count
, uint64_t offset
)
178 struct handle
*h
= handle
;
181 ssize_t r
= pwrite (h
->fd
, buf
, count
, offset
);
183 nbdkit_error ("pwrite: %m");
194 /* Flush the file to disk. */
196 file_flush (void *handle
)
198 struct handle
*h
= handle
;
200 if (fdatasync (h
->fd
) == -1) {
201 nbdkit_error ("fdatasync: %m");
208 static struct nbdkit_plugin plugin
= {
210 .longname
= "nbdkit file plugin",
211 .version
= PACKAGE_VERSION
,
212 .unload
= file_unload
,
213 .config
= file_config
,
214 .config_complete
= file_config_complete
,
215 .config_help
= file_config_help
,
218 .get_size
= file_get_size
,
220 .pwrite
= file_pwrite
,
224 NBDKIT_REGISTER_PLUGIN(plugin
)