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
44 #define NBDKIT_API_VERSION 2
45 #include <nbdkit-plugin.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
;
57 static struct allocator
*a
;
58 static const char *allocator_type
= "sparse";
68 memory_config (const char *key
, const char *value
)
70 if (strcmp (key
, "size") == 0) {
71 size
= nbdkit_parse_size (value
);
75 else if (strcmp (key
, "allocator") == 0) {
76 allocator_type
= value
;
79 nbdkit_error ("unknown parameter '%s'", key
);
87 memory_config_complete (void)
90 nbdkit_error ("you must specify size=<SIZE> on the command line");
96 #define memory_config_help \
97 "size=<SIZE> (required) Size of the backing disk\n" \
98 "allocator=sparse|... Backend allocation strategy"
101 memory_dump_plugin (void)
104 printf ("mlock=yes\n");
106 printf ("mlock=no\n");
109 printf ("zstd=yes\n");
111 printf ("zstd=no\n");
116 memory_get_ready (void)
118 a
= create_allocator (allocator_type
, memory_debug_dir
);
121 if (a
->f
->set_size_hint (a
, size
) == -1)
126 /* Create the per-connection handle. */
128 memory_open (int readonly
)
130 return NBDKIT_HANDLE_NOT_NEEDED
;
133 #define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
135 /* Get the disk size. */
137 memory_get_size (void *handle
)
142 /* Flush is a no-op, so advertise native FUA support */
144 memory_can_fua (void *handle
)
146 return NBDKIT_FUA_NATIVE
;
149 /* Serves the same data over multiple connections. */
151 memory_can_multi_conn (void *handle
)
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
;
168 memory_can_fast_zero (void *handle
)
175 memory_pread (void *handle
, void *buf
, uint32_t count
, uint64_t offset
,
179 return a
->f
->read (a
, buf
, count
, offset
);
184 memory_pwrite (void *handle
, const void *buf
, uint32_t count
, uint64_t offset
,
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
);
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). */
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
);
213 /* Nothing is persistent, so flush is trivially supported */
215 memory_flush (void *handle
, uint32_t flags
)
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
= {
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
,
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
,
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
)