2 ======================================================================
4 General ideas for improvements
5 ------------------------------
7 * Listen on specific interfaces or protocols (eg. only IPv6).
9 * Performance - measure and improve it. Chart it over various buffer
10 sizes and threads, as that should make it easier to identify
13 * Exit on last connection (the default behaviour of qemu-nbd unless
16 * Limit number of incoming connections (like qemu-nbd -e).
18 * For parallel plugins, only create threads on demand from parallel
19 client requests, rather than pre-creating all threads at connection
20 time, up to the thread pool size limit. Of course, once created, a
21 thread is reused as possible until the connection closes.
23 * Async callbacks. The current parallel support requires one thread
24 per pending message; a solution with fewer threads would split
25 low-level code between request and response, where the callback has
26 to inform nbdkit when the response is ready:
27 https://www.redhat.com/archives/libguestfs/2018-January/msg00149.html
29 * More NBD protocol features. The currently missing features are
30 structured replies for sparse reads, block size constraints, and
33 * Add a callback to let plugins request minimum alignment for the
34 buffer to pread/pwrite; useful for a plugin utilizing O_DIRECT or
35 other situation where pre-aligned buffers are more efficient.
36 Ideally, a blocksize filter would honor strict alignment below and
37 advertise loose alignment above; all other filters (particularly
38 ones like offset) can fail to initialize if they can't guarantee
39 strict alignment and don't want to deal with bounce buffers.
41 * Test that zero-length read/write/extents requests behave sanely
42 (NBD protocol says they are unspecified).
44 * If a client negotiates structured replies, and issues a read/extents
45 call that exceeds EOF (qemu 3.1 is one such client, when nbdkit
46 serves non-sector-aligned images), return the valid answer for the
47 subset of the request in range and then NBD_REPLY_TYPE_ERROR_OFFSET
48 for the tail, rather than erroring the entire request.
50 * Test and document how to run nbdkit from inetd and xinetd in
53 * Audit the code base to get rid of strerror() usage (the function is
54 not thread-safe); however, using geterror_r() can be tricky as it
55 has a different signature in glibc than in POSIX.
57 * Teach nbdkit_error() to have smart newline appending (for existing
58 inconsistent clients), while fixing internal uses to omit the
59 newline. Commit ef4f72ef has some ideas on smart newlines, but that
60 should probably be factored into a utility function.
62 * We may need a way to lock nbdkit into memory and adjust the OOM
63 killer score. See this LKML discussion:
64 https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1933394.html
65 and also look at the implementation of the -swap option in
68 * Add a mode of operation where nbdkit is handed a pre-opened fd to be
69 used immediately in transmission phase (skipping handshake). There
70 are already third-party clients of the kernel's /dev/nbdX which rely
71 on their own protocol instead of NBD handshake, before calling
72 ioctl(NBD_SET_SOCK); this mode would let the third-party client
73 continue to keep their non-standard handshake while utilizing nbdkit
74 to prototype new behaviors in serving the kernel.
76 * Clients should be able to list export names supported by plugins.
77 Current behaviour is not really correct: We only list the -e
78 parameter from the command line, which is different from the export
79 name(s) that a plugin might want to support. Probably we should
80 deprecate the -e option entirely since it does nothing useful.
82 * Add plugin "connect" method. This would be called on a connection
83 before handshaking or TLS negotiation, and could be used (with
84 nbdkit_peer_name) to accept or reject connections based on IP
85 address, rather like a poor man's TCP wrappers. See also commit
88 * Background thread for filters. Some filters (readahead, cache and
89 proposed scan filter - see below) could be more effective if they
90 were able to defer work to a background thread. However it's not as
91 simple as just creating a background thread, because you only have
92 access to the connection / next_ops from the context of a filter
93 callback. (Also you can't "save" next_ops because it becomes
94 invalid outside the callback). The background thread would need to
95 have its own connection to the plugin, which would be independent of
96 any client connection, and this requires some care because it breaks
97 an existing assumption.
99 * Add scan filter. This would be placed on top of cache filters and
100 would scan (read) the whole disk in the background, ensuring it is
101 copied into the cache. Useful if you have a slow plugin, limited
102 size device, and lots of local disk space, especially if you know
103 that the NBD clients will eventually read all of the device. RWMJ
104 wrote an implementation of this but it doesn't work well without a
107 * "nbdkit.so": nbdkit as a loadable shared library. The aim of nbdkit
108 is to make it reusable from other programs (see nbdkit-captive(1)).
109 If it was a loadable shared library it would be even more reusable.
110 API would allow you to create an nbdkit instance, configure it (same
111 as the current command line), start it serving on a socket, etc.
112 However perhaps the current ability to work well as a subprocess is
113 good enough? Also allowing multiple instances of nbdkit to be
114 loaded in the same process is probably impossible.
116 * Examine other fuzzers: https://gitlab.com/akihe/radamsa
118 * Analyze code with Coverity.
120 Suggestions for plugins
121 -----------------------
123 Note: qemu supports other formats such as libnfs, iscsi, gluster and
124 ceph/rbd, and while similar plugins could be written for nbdkit there
125 is no compelling reason unless the result is better than qemu-nbd.
126 For the majority of users it would be better if they were directed to
127 qemu-nbd for these use cases.
131 https://lists.gnu.org/archive/html/qemu-devel/2017-11/msg02971.html
132 is a partial solution but it needs cleaning up.
134 nbdkit-floppy-plugin:
136 * Add boot sector support. In theory this is easy (eg. using
137 SYSLINUX), but the practical reality of making a fully bootable
138 floppy is rather more complex.
140 * Add multiple dir merging.
142 nbdkit-linuxdisk-plugin:
144 * Add multiple dir merging (in e2fsprogs mke2fs).
146 Suggestions for filters
147 -----------------------
149 * tar plugin should really be a filter
151 * gzip plugin should really be a filter
153 * libarchive could be used to implement a general tar/zip filter
155 * LUKS encrypt/decrypt filter, bonus points if compatible with qemu
156 LUKS-encrypted disk images
158 * masking plugin features for testing clients (see 'nozero' and 'fua'
159 filters for examples)
161 * nbdkit-cache-filter should handle ENOSPC errors automatically by
162 reclaiming blocks from the cache
164 * zstd filter was requested as a way to do what we currently do with
165 xz but saving many hours on compression (at the cost of hundreds of
167 https://github.com/facebook/zstd/issues/395#issuecomment-535875379
171 * allow other kinds of traffic shaping such as VBR
173 * limit traffic per client (ie. per IP address)
175 * split large requests to avoid long, lumpy sleeps when request size
176 is much larger than rate limit
180 * allow user to specify which errors cause a retry and which ones are
181 passed through; for example there's probably no point retrying on
184 * implement a softer mode (retry-reopen=no) where we don't reopen the
185 plugin, we just retry the data command that failed
187 * there are all kinds of extra complications possible here,
188 eg. specifying a pattern of retrying and reopening:
189 retry-method=RRRORRRRRORRRRR meaning to retry the data command 3
190 times, reopen, retry 5 times, etc.
197 Things like blacklisting or whitelisting IP addresses can be done
198 using external wrappers (TCP wrappers, systemd).
200 However it might be nice to have a configurable filter for preventing
201 valid but not sensible requests. The server already filters invalid
202 requests. This would be like seccomp, and could be implemented using
203 an eBPF-based parser. Unfortunately actual eBPF is difficult to use
204 for userspace processes. The "standard" isn't solidly defined - the
205 Linux kernel implementation is the standard - and Linux has by far the
206 best implementation, particularly around bytecode verification and
207 JITting. There is a userspace VM (ubpf) but it has very limited
208 capabilities compared to Linux.
213 Filters allow certain types of composition, but others would not be
214 possible, for example RAIDing over multiple nbd sources. Because the
215 plugin API limits us to loading a single plugin to the server, the
216 best way to do this (and the most robust) is to compose multiple
217 nbdkit processes. Perhaps libnbd will prove useful for this purpose.
222 * Figure out how to get 'make distcheck' working. VPATH builds are
223 working, but various pkg-config results that try to stick
224 bash-completion and ocaml add-ons into their system-wide home do
225 not play nicely with --prefix builds for a non-root user.
232 * Consider supporting a more idiomatic style for writing Rust plugins.
234 * Better documentation.
238 * There is no attempt to ‘make install’ or otherwise package the
239 crate. Since it looks as if Rust code is normally distributed as
240 source it's not clear what that would even mean.
245 From time to time we may update the plugin protocol. This section
246 collects ideas for things which might be fixed in the next version of
249 Note that we keep the old protocol(s) around so that source
250 compatibility is retained. Plugins must opt in to the new protocol
251 using ‘#define NBDKIT_API_VERSION <version>’.
253 * All methods taking a ‘count’ field should be uint64_t (instead of
254 uint32_t). Although the NBD protocol does not support 64 bit
255 lengths, it might do in future.
257 * pread could be changed to allow it to support Structured Replies
258 (SRs). This could mean allowing it to return partial data, holes,
259 zeroes, etc. For a client that negotiates SR coupled with a plugin
260 that supports .extents, the v2 protocol would allow us to at least
261 synthesize NBD_REPLY_TYPE_OFFSET_HOLE for less network traffic, even
262 though the plugin will still have to fully populate the .pread
263 buffer; the v3 protocol should make sparse reads more direct.
265 * Parameters should be systematized so that they aren't just (key,
266 value) strings. nbdkit should know the possible keys for the plugin
267 and filters, and the type of the values, and both check and parse
270 * Modify open() API so it takes an export name parameter.