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