Update Red Hat Copyright Notices
[nbdkit.git] / plugins / memory / memory.c
blob19d9a6cdde31466ed5ea76bacfe3655dc16ffa96
1 /* nbdkit
2 * Copyright Red Hat
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 <stdio.h>
36 #include <stdlib.h>
37 #include <stdbool.h>
38 #include <stdint.h>
39 #include <inttypes.h>
40 #include <string.h>
41 #include <errno.h>
42 #include <assert.h>
44 #define NBDKIT_API_VERSION 2
45 #include <nbdkit-plugin.h>
47 #include "cleanup.h"
48 #include "allocator.h"
50 /* The size of disk in bytes (initialized by size=<SIZE> parameter). */
51 static int64_t size = -1;
53 /* Debug directory operations (-D memory.dir=1). */
54 NBDKIT_DLL_PUBLIC int memory_debug_dir;
56 /* Allocator. */
57 static struct allocator *a;
58 static const char *allocator_type = "sparse";
60 static void
61 memory_unload (void)
63 if (a)
64 a->f->free (a);
67 static int
68 memory_config (const char *key, const char *value)
70 if (strcmp (key, "size") == 0) {
71 size = nbdkit_parse_size (value);
72 if (size == -1)
73 return -1;
75 else if (strcmp (key, "allocator") == 0) {
76 allocator_type = value;
78 else {
79 nbdkit_error ("unknown parameter '%s'", key);
80 return -1;
83 return 0;
86 static int
87 memory_config_complete (void)
89 if (size == -1) {
90 nbdkit_error ("you must specify size=<SIZE> on the command line");
91 return -1;
93 return 0;
96 #define memory_config_help \
97 "size=<SIZE> (required) Size of the backing disk\n" \
98 "allocator=sparse|... Backend allocation strategy"
100 static void
101 memory_dump_plugin (void)
103 #ifdef HAVE_MLOCK
104 printf ("mlock=yes\n");
105 #else
106 printf ("mlock=no\n");
107 #endif
108 #ifdef HAVE_LIBZSTD
109 printf ("zstd=yes\n");
110 #else
111 printf ("zstd=no\n");
112 #endif
115 static int
116 memory_get_ready (void)
118 a = create_allocator (allocator_type, memory_debug_dir);
119 if (a == NULL)
120 return -1;
121 if (a->f->set_size_hint (a, size) == -1)
122 return -1;
123 return 0;
126 /* Create the per-connection handle. */
127 static void *
128 memory_open (int readonly)
130 return NBDKIT_HANDLE_NOT_NEEDED;
133 #define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
135 /* Get the disk size. */
136 static int64_t
137 memory_get_size (void *handle)
139 return size;
142 /* Flush is a no-op, so advertise native FUA support */
143 static int
144 memory_can_fua (void *handle)
146 return NBDKIT_FUA_NATIVE;
149 /* Serves the same data over multiple connections. */
150 static int
151 memory_can_multi_conn (void *handle)
153 return 1;
156 /* Cache. */
157 static int
158 memory_can_cache (void *handle)
160 /* Everything is already in memory, returning this without
161 * implementing .cache lets nbdkit do the correct no-op.
163 return NBDKIT_CACHE_NATIVE;
166 /* Fast zero. */
167 static int
168 memory_can_fast_zero (void *handle)
170 return 1;
173 /* Read data. */
174 static int
175 memory_pread (void *handle, void *buf, uint32_t count, uint64_t offset,
176 uint32_t flags)
178 assert (!flags);
179 return a->f->read (a, buf, count, offset);
182 /* Write data. */
183 static int
184 memory_pwrite (void *handle, const void *buf, uint32_t count, uint64_t offset,
185 uint32_t flags)
187 /* Flushing, and thus FUA flag, is a no-op */
188 assert ((flags & ~NBDKIT_FLAG_FUA) == 0);
189 return a->f->write (a, buf, count, offset);
192 /* Zero. */
193 static int
194 memory_zero (void *handle, uint32_t count, uint64_t offset, uint32_t flags)
196 /* Flushing, and thus FUA flag, is a no-op. Assume that
197 * a->f->zero generally beats writes, so FAST_ZERO is a no-op. */
198 assert ((flags & ~(NBDKIT_FLAG_FUA | NBDKIT_FLAG_MAY_TRIM |
199 NBDKIT_FLAG_FAST_ZERO)) == 0);
200 return a->f->zero (a, count, offset);
203 /* Trim (same as zero). */
204 static int
205 memory_trim (void *handle, uint32_t count, uint64_t offset, uint32_t flags)
207 /* Flushing, and thus FUA flag, is a no-op */
208 assert ((flags & ~NBDKIT_FLAG_FUA) == 0);
209 a->f->zero (a, count, offset);
210 return 0;
213 /* Nothing is persistent, so flush is trivially supported */
214 static int
215 memory_flush (void *handle, uint32_t flags)
217 return 0;
220 /* Extents. */
221 static int
222 memory_extents (void *handle, uint32_t count, uint64_t offset,
223 uint32_t flags, struct nbdkit_extents *extents)
225 return a->f->extents (a, count, offset, extents);
228 static struct nbdkit_plugin plugin = {
229 .name = "memory",
230 .version = PACKAGE_VERSION,
231 .unload = memory_unload,
232 .config = memory_config,
233 .config_complete = memory_config_complete,
234 .config_help = memory_config_help,
235 .magic_config_key = "size",
236 .dump_plugin = memory_dump_plugin,
237 .get_ready = memory_get_ready,
238 .open = memory_open,
239 .get_size = memory_get_size,
240 .can_fua = memory_can_fua,
241 .can_multi_conn = memory_can_multi_conn,
242 .can_cache = memory_can_cache,
243 .can_fast_zero = memory_can_fast_zero,
244 .pread = memory_pread,
245 .pwrite = memory_pwrite,
246 .zero = memory_zero,
247 .trim = memory_trim,
248 .flush = memory_flush,
249 .extents = memory_extents,
250 /* In this plugin, errno is preserved properly along error return
251 * paths from failed system calls.
253 .errno_is_preserved = 1,
256 NBDKIT_REGISTER_PLUGIN (plugin)