[PATCH] nbd-client: support newstyle protocol, -b, -d
Denys Vlasenko
vda.linux at googlemail.com
Wed Oct 24 13:53:44 UTC 2018
Apologies for the delay.
On Tue, Oct 9, 2018 at 1:42 AM Elvira Khabirova
<lineprinter at altlinux.org> wrote:
> Recognize the "newstyle" protocol and switch to it automatically.
> Add options for setting blocksize (-b) and for disconnecting
> a nbd device (-d).
>
> Signed-off-by: Elvira Khabirova <lineprinter at altlinux.org>
> ---
> networking/nbd-client.c | 168 +++++++++++++++++++++++++++++++++-------
> 1 file changed, 140 insertions(+), 28 deletions(-)
>
> diff --git a/networking/nbd-client.c b/networking/nbd-client.c
> index bedb01a1c..9e718ff93 100644
> --- a/networking/nbd-client.c
> +++ b/networking/nbd-client.c
> @@ -27,17 +27,17 @@
> #define NBD_SET_SIZE_BLOCKS _IO(0xab, 7)
> #define NBD_DISCONNECT _IO(0xab, 8)
> #define NBD_SET_TIMEOUT _IO(0xab, 9)
> +#define NBD_SET_FLAGS _IO(0xab, 10)
>
> //usage:#define nbdclient_trivial_usage
> -//usage: "HOST PORT BLOCKDEV"
> +//usage: "{ [-b BLKSIZE] [-N name] HOST PORT | -d } BLOCKDEV"
> //usage:#define nbdclient_full_usage "\n\n"
> //usage: "Connect to HOST and provide a network block device on BLOCKDEV"
>
> //TODO: more compat with nbd-client version 2.9.13 -
> //Usage: nbd-client [bs=blocksize] [timeout=sec] host port nbd_device [-swap] [-persist] [-nofork]
> -//Or : nbd-client -d nbd_device
> //Or : nbd-client -c nbd_device
> -//Default value for blocksize is 1024 (recommended for ethernet)
> +//Default value for blocksize is 4096
> //Allowed values for blocksize are 512,1024,2048,4096
> //Note, that kernel 2.4.2 and older ones do not work correctly with
> //blocksizes other than 1024 without patches
> @@ -45,37 +45,90 @@
> int nbdclient_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
> int nbdclient_main(int argc UNUSED_PARAM, char **argv)
> {
> - unsigned long timeout = 0;
> #if BB_MMU
> int nofork = 0;
> #endif
> - char *host, *port, *device;
> + char *host, *port, *device, *name;
> + unsigned blksize, size_blocks;
> + unsigned timeout;
> + unsigned opt;
> +
> + uint16_t handshake_flags;
> + uint32_t client_flags = 0;
> +
> struct nbd_header_t {
> uint64_t magic1; // "NBDMAGIC"
> - uint64_t magic2; // 0x420281861253 big endian
> + uint64_t magic2; // old style: 0x420281861253 big endian
> + // new style: 0x49484156454F5054 (IHAVEOPT)
> + } nbd_header;
> +
> + struct old_nbd_header_t {
> uint64_t devsize;
> uint32_t flags;
> char data[124];
> - } nbd_header;
> + } old_nbd_header;
>
> - BUILD_BUG_ON(offsetof(struct nbd_header_t, data) != 8+8+8+4);
> + struct new_nbd_header_t {
> + uint64_t devsize;
> + uint16_t transmission_flags;
> + char data[124];
> + } new_nbd_header;
>
> - // Parse command line stuff (just a stub now)
> - if (!argv[1] || !argv[2] || !argv[3] || argv[4])
> - bb_show_usage();
> + struct nbd_opt_t {
> + uint64_t magic;
> + uint32_t opt;
> + uint32_t len;
> + } nbd_opts;
> +
> + BUILD_BUG_ON(offsetof(struct old_nbd_header_t, data) != 8+4);
> + BUILD_BUG_ON(offsetof(struct new_nbd_header_t, data) != 8+2);
>
> #if !BB_MMU
> bb_daemonize_or_rexec(DAEMON_CLOSE_EXTRA_FDS, argv);
> #endif
>
> - host = argv[1];
> - port = argv[2];
> - device = argv[3];
> + // Parse args
> + opt = getopt32(argv, "b:+t:+N:d", &blksize, &timeout, &name);
-t is not documented in --help.
Many man pages list only long options, a-la:
SYNOPSIS
nbd-client host [ port ] nbd-device [ -connections num ] [ -sdp ] [ -swap ]
[ -persist ] [ -nofork ] [ -nonetlink ] [ -systemd-mark ] [
-block-size block size ]
[ -timeout seconds ] [ -name name ] [ -certfile certfile ] [
-keyfile keyfile ]
[ -cacertfile cacertfile ] [ -tlshostname hostname ]
nbd-client nbd-device
nbd-client -d nbd-device
nbd-client -c nbd-device
nbd-client -l host [ port ]
nbd-client [ -netlink ] -l host
Because of this, I assume a lot of scripts would use long opts :/
We probably much better if we accept long opts.
> + if (!(opt & 0x1)) {
> + blksize = 4096;
> + }
> +
> + if (!(opt & 0x2)) {
> + timeout = 0;
> + }
> +
> + if (!(opt & 0x4)) {
> + name = NULL;
> + }
Assign the values unconditionally before option parsing. Less generated code.
> + nbd_opts.len = htonl(strlen(name));
> + xwrite(sock, &nbd_opts,
> + sizeof(nbd_opts.magic) +
> + sizeof(nbd_opts.opt) +
> + sizeof(nbd_opts.len));
> + xwrite(sock, name, strlen(name));
two times strlen()...
I applied a modified version of the patch,
please let me know whether it works.
Thanks!
More information about the busybox
mailing list