Network Block Device  @PACKAGE_VERSION@
nbd-client.c
Go to the documentation of this file.
1 /*
2  * Open connection for network block device
3  *
4  * Copyright 1997,1998 Pavel Machek, distribute under GPL
5  * <pavel@atrey.karlin.mff.cuni.cz>
6  * Copyright (c) 2002 - 2011 Wouter Verhelst <w@uter.be>
7  *
8  * Version 1.0 - 64bit issues should be fixed, now
9  * Version 1.1 - added bs (blocksize) option (Alexey Guzeev, aga@permonline.ru)
10  * Version 1.2 - I added new option '-d' to send the disconnect request
11  * Version 2.0 - Version synchronised with server
12  * Version 2.1 - Check for disconnection before INIT_PASSWD is received
13  * to make errormsg a bit more helpful in case the server can't
14  * open the exported file.
15  * 16/03/2010 - Add IPv6 support.
16  * Kitt Tientanopajai <kitt@kitty.in.th>
17  * Neutron Soutmun <neo.neutron@gmail.com>
18  * Suriya Soutmun <darksolar@gmail.com>
19  */
20 
21 #include "config.h"
22 #include "lfs.h"
23 
24 #include <sys/ioctl.h>
25 #include <sys/socket.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28 #include <netinet/tcp.h>
29 #include <netinet/in.h>
30 #include <netdb.h>
31 #include "netdb-compat.h"
32 #include <stdio.h>
33 #include <fcntl.h>
34 #include <syslog.h>
35 #include <stdlib.h>
36 #include <sys/mount.h>
37 #include <sys/mman.h>
38 #include <signal.h>
39 #include <errno.h>
40 #include <getopt.h>
41 #include <stdarg.h>
42 
43 #include <linux/ioctl.h>
44 #define MY_NAME "nbd_client"
45 #include "cliserv.h"
46 
47 #ifdef WITH_SDP
48 #include <sdp_inet.h>
49 #endif
50 
51 #define NBDC_DO_LIST 1
52 
53 int check_conn(char* devname, int do_print) {
54  char buf[256];
55  char* p;
56  int fd;
57  int len;
58 
59  if( (p=strrchr(devname, '/')) ) {
60  devname=p+1;
61  }
62  if((p=strchr(devname, 'p'))) {
63  /* We can't do checks on partitions. */
64  *p='\0';
65  }
66  snprintf(buf, 256, "/sys/block/%s/pid", devname);
67  if((fd=open(buf, O_RDONLY))<0) {
68  if(errno==ENOENT) {
69  return 1;
70  } else {
71  return 2;
72  }
73  }
74  len=read(fd, buf, 256);
75  if(len >= 0)
76  buf[len]='\0';
77  if(do_print) printf("%s\n", buf);
78  return 0;
79 }
80 
81 int opennet(char *name, char* portstr, int sdp) {
82  int sock;
83  struct addrinfo hints;
84  struct addrinfo *ai = NULL;
85  struct addrinfo *rp = NULL;
86  int e;
87 
88  memset(&hints,'\0',sizeof(hints));
89  hints.ai_family = AF_UNSPEC;
90  hints.ai_socktype = SOCK_STREAM;
91  hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV;
92  hints.ai_protocol = IPPROTO_TCP;
93 
94  e = getaddrinfo(name, portstr, &hints, &ai);
95 
96  if(e != 0) {
97  fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(e));
98  freeaddrinfo(ai);
99  return -1;
100  }
101 
102  if(sdp) {
103 #ifdef WITH_SDP
104  if (ai->ai_family == AF_INET)
105  ai->ai_family = AF_INET_SDP;
106  else (ai->ai_family == AF_INET6)
107  ai->ai_family = AF_INET6_SDP;
108 #else
109  err("Can't do SDP: I was not compiled with SDP support!");
110 #endif
111  }
112 
113  for(rp = ai; rp != NULL; rp = rp->ai_next) {
114  sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
115 
116  if(sock == -1)
117  continue; /* error */
118 
119  if(connect(sock, rp->ai_addr, rp->ai_addrlen) != -1)
120  break; /* success */
121 
122  close(sock);
123  }
124 
125  if (rp == NULL) {
126  err_nonfatal("Socket failed: %m");
127  return -1;
128  }
129 
130  setmysockopt(sock);
131 
132  freeaddrinfo(ai);
133  return sock;
134 }
135 
136 void ask_list(int sock) {
137  uint32_t opt;
138  uint32_t opt_server;
139  uint32_t len;
140  uint32_t reptype;
141  uint64_t magic;
142  const int BUF_SIZE = 1024;
143  char buf[BUF_SIZE];
144 
145  magic = ntohll(opts_magic);
146  if (write(sock, &magic, sizeof(magic)) < 0)
147  err("Failed/2.2: %m");
148 
149  /* Ask for the list */
150  opt = htonl(NBD_OPT_LIST);
151  if(write(sock, &opt, sizeof(opt)) < 0) {
152  err("writing list option failed: %m");
153  }
154  /* Send the length (zero) */
155  len = htonl(0);
156  if(write(sock, &len, sizeof(len)) < 0) {
157  err("writing length failed: %m");
158  }
159  /* newline, move away from the "Negotiation:" line */
160  printf("\n");
161  do {
162  memset(buf, 0, 1024);
163  if(read(sock, &magic, sizeof(magic)) < 0) {
164  err("Reading magic from server: %m");
165  }
166  if(read(sock, &opt_server, sizeof(opt_server)) < 0) {
167  err("Reading option: %m");
168  }
169  if(read(sock, &reptype, sizeof(reptype)) <0) {
170  err("Reading reply from server: %m");
171  }
172  if(read(sock, &len, sizeof(len)) < 0) {
173  err("Reading length from server: %m");
174  }
175  magic=ntohll(magic);
176  len=ntohl(len);
177  reptype=ntohl(reptype);
178  if(magic != rep_magic) {
179  err("Not enough magic from server");
180  }
181  if(reptype & NBD_REP_FLAG_ERROR) {
182  switch(reptype) {
183  case NBD_REP_ERR_POLICY:
184  fprintf(stderr, "\nE: listing not allowed by server.\n");
185  break;
186  default:
187  fprintf(stderr, "\nE: unexpected error from server.\n");
188  break;
189  }
190  if(len > 0 && len < BUF_SIZE) {
191  if(len=read(sock, buf, len) < 0) {
192  fprintf(stderr, "\nE: could not read error message from server\n");
193  }
194  buf[len] = '\0';
195  fprintf(stderr, "Server said: %s\n", buf);
196  }
197  exit(EXIT_FAILURE);
198  } else {
199  if(len) {
200  if(reptype != NBD_REP_SERVER) {
201  err("Server sent us a reply we don't understand!");
202  }
203  if(read(sock, &len, sizeof(len)) < 0) {
204  fprintf(stderr, "\nE: could not read export name length from server\n");
205  exit(EXIT_FAILURE);
206  }
207  len=ntohl(len);
208  if (len >= BUF_SIZE) {
209  fprintf(stderr, "\nE: export name on server too long\n");
210  exit(EXIT_FAILURE);
211  }
212  if(read(sock, buf, len) < 0) {
213  fprintf(stderr, "\nE: could not read export name from server\n");
214  exit(EXIT_FAILURE);
215  }
216  buf[len] = 0;
217  printf("%s\n", buf);
218  }
219  }
220  } while(reptype != NBD_REP_ACK);
221  opt=htonl(NBD_OPT_ABORT);
222  len=htonl(0);
223  magic=htonll(opts_magic);
224  if (write(sock, &magic, sizeof(magic)) < 0)
225  err("Failed/2.2: %m");
226  if (write(sock, &opt, sizeof(opt)) < 0)
227  err("Failed writing abort");
228  if (write(sock, &len, sizeof(len)) < 0)
229  err("Failed writing length");
230 }
231 
232 void negotiate(int sock, u64 *rsize64, u32 *flags, char* name, uint32_t needed_flags, uint32_t client_flags, uint32_t do_opts) {
233  u64 magic, size64;
234  uint16_t tmp;
235  char buf[256] = "\0\0\0\0\0\0\0\0\0";
236 
237  printf("Negotiation: ");
238  if (read(sock, buf, 8) < 0)
239  err("Failed/1: %m");
240  if (strlen(buf)==0)
241  err("Server closed connection");
242  if (strcmp(buf, INIT_PASSWD))
243  err("INIT_PASSWD bad");
244  printf(".");
245  if (read(sock, &magic, sizeof(magic)) < 0)
246  err("Failed/2: %m");
247  magic = ntohll(magic);
248  if(name) {
249  uint32_t opt;
250  uint32_t namesize;
251 
252  if (magic != opts_magic) {
253  if(magic == cliserv_magic) {
254  err("It looks like you're trying to connect to an oldstyle server with a named export. This won't work.");
255  }
256  }
257  printf(".");
258  if(read(sock, &tmp, sizeof(uint16_t)) < 0) {
259  err("Failed reading flags: %m");
260  }
261  *flags = ((u32)ntohs(tmp));
262  if((needed_flags & *flags) != needed_flags) {
263  /* There's currently really only one reason why this
264  * check could possibly fail, but we may need to change
265  * this error message in the future... */
266  fprintf(stderr, "\nE: Server does not support listing exports\n");
267  exit(EXIT_FAILURE);
268  }
269 
270  client_flags = htonl(client_flags);
271  if (write(sock, &client_flags, sizeof(client_flags)) < 0)
272  err("Failed/2.1: %m");
273 
274  if(do_opts & NBDC_DO_LIST) {
275  ask_list(sock);
276  exit(EXIT_SUCCESS);
277  }
278 
279  /* Write the export name that we're after */
280  magic = htonll(opts_magic);
281  if (write(sock, &magic, sizeof(magic)) < 0)
282  err("Failed/2.2: %m");
283 
284  opt = ntohl(NBD_OPT_EXPORT_NAME);
285  if (write(sock, &opt, sizeof(opt)) < 0)
286  err("Failed/2.3: %m");
287  namesize = (u32)strlen(name);
288  namesize = ntohl(namesize);
289  if (write(sock, &namesize, sizeof(namesize)) < 0)
290  err("Failed/2.4: %m");
291  if (write(sock, name, strlen(name)) < 0)
292  err("Failed/2.4: %m");
293  } else {
294  if (magic != cliserv_magic) {
295  if(magic != opts_magic)
296  err("Not enough cliserv_magic");
297  else
298  err("It looks like you're trying to connect to a newstyle server with the oldstyle protocol. Try the -N option.");
299  }
300  printf(".");
301  }
302 
303  if (read(sock, &size64, sizeof(size64)) <= 0) {
304  if (!errno)
305  err("Server closed connection");
306  err("Failed/3: %m\n");
307  }
308  size64 = ntohll(size64);
309 
310  if ((size64>>12) > (uint64_t)~0UL) {
311  printf("size = %luMB", (unsigned long)(size64>>20));
312  err("Exported device is too big for me. Get 64-bit machine :-(\n");
313  } else
314  printf("size = %luMB", (unsigned long)(size64>>20));
315 
316  if(!name) {
317  if (read(sock, flags, sizeof(*flags)) < 0)
318  err("Failed/4: %m\n");
319  *flags = ntohl(*flags);
320  } else {
321  if(read(sock, &tmp, sizeof(tmp)) < 0)
322  err("Failed/4: %m\n");
323  *flags |= (uint32_t)ntohs(tmp);
324  }
325 
326  if (read(sock, &buf, 124) < 0)
327  err("Failed/5: %m\n");
328  printf("\n");
329 
330  *rsize64 = size64;
331 }
332 
333 void setsizes(int nbd, u64 size64, int blocksize, u32 flags) {
334  unsigned long size;
335  int read_only = (flags & NBD_FLAG_READ_ONLY) ? 1 : 0;
336 
337  if (size64>>12 > (uint64_t)~0UL)
338  err("Device too large.\n");
339  else {
340  if (ioctl(nbd, NBD_SET_BLKSIZE, 4096UL) < 0)
341  err("Ioctl/1.1a failed: %m\n");
342  size = (unsigned long)(size64>>12);
343  if (ioctl(nbd, NBD_SET_SIZE_BLOCKS, size) < 0)
344  err("Ioctl/1.1b failed: %m\n");
345  if (ioctl(nbd, NBD_SET_BLKSIZE, (unsigned long)blocksize) < 0)
346  err("Ioctl/1.1c failed: %m\n");
347  fprintf(stderr, "bs=%d, sz=%llu bytes\n", blocksize, 4096ULL*size);
348  }
349 
350  ioctl(nbd, NBD_CLEAR_SOCK);
351 
352  /* ignore error as kernel may not support */
353  ioctl(nbd, NBD_SET_FLAGS, (unsigned long) flags);
354 
355  if (ioctl(nbd, BLKROSET, (unsigned long) &read_only) < 0)
356  err("Unable to set read-only attribute for device");
357 }
358 
359 void set_timeout(int nbd, int timeout) {
360  if (timeout) {
361  if (ioctl(nbd, NBD_SET_TIMEOUT, (unsigned long)timeout) < 0)
362  err("Ioctl NBD_SET_TIMEOUT failed: %m\n");
363  fprintf(stderr, "timeout=%d\n", timeout);
364  }
365 }
366 
367 void finish_sock(int sock, int nbd, int swap) {
368  if (ioctl(nbd, NBD_SET_SOCK, sock) < 0)
369  err("Ioctl NBD_SET_SOCK failed: %m\n");
370 
371  if (swap)
372  mlockall(MCL_CURRENT | MCL_FUTURE);
373 }
374 
375 static int
376 oom_adjust(const char *file, const char *value)
377 {
378  int fd, rc;
379  size_t len;
380 
381  fd = open(file, O_WRONLY);
382  if (fd < 0)
383  return -1;
384  len = strlen(value);
385  rc = write(fd, value, len) != (ssize_t) len;
386  close(fd);
387  return rc ? -1 : 0;
388 }
389 
390 void usage(char* errmsg, ...) {
391  if(errmsg) {
392  char tmp[256];
393  va_list ap;
394  va_start(ap, errmsg);
395  snprintf(tmp, 256, "ERROR: %s\n\n", errmsg);
396  vfprintf(stderr, tmp, ap);
397  va_end(ap);
398  } else {
399  fprintf(stderr, "nbd-client version %s\n", PACKAGE_VERSION);
400  }
401  fprintf(stderr, "Usage: nbd-client host port nbd_device [-block-size|-b block size] [-timeout|-t timeout] [-swap|-s] [-sdp|-S] [-persist|-p] [-nofork|-n] [-systemd-mark|-m]\n");
402  fprintf(stderr, "Or : nbd-client -name|-N name host [port] nbd_device [-block-size|-b block size] [-timeout|-t timeout] [-swap|-s] [-sdp|-S] [-persist|-p] [-nofork|-n]\n");
403  fprintf(stderr, "Or : nbd-client -d nbd_device\n");
404  fprintf(stderr, "Or : nbd-client -c nbd_device\n");
405  fprintf(stderr, "Or : nbd-client -h|--help\n");
406  fprintf(stderr, "Or : nbd-client -l|--list host\n");
407  fprintf(stderr, "Default value for blocksize is 1024 (recommended for ethernet)\n");
408  fprintf(stderr, "Allowed values for blocksize are 512,1024,2048,4096\n"); /* will be checked in kernel :) */
409  fprintf(stderr, "Note, that kernel 2.4.2 and older ones do not work correctly with\n");
410  fprintf(stderr, "blocksizes other than 1024 without patches\n");
411  fprintf(stderr, "Default value for port with -N is 10809. Note that port must always be numeric\n");
412 }
413 
414 void disconnect(char* device) {
415  int nbd = open(device, O_RDWR);
416 
417  if (nbd < 0)
418  err("Cannot open NBD: %m\nPlease ensure the 'nbd' module is loaded.");
419  printf("disconnect, ");
420  if (ioctl(nbd, NBD_DISCONNECT)<0)
421  err("Ioctl failed: %m\n");
422  printf("sock, ");
423  if (ioctl(nbd, NBD_CLEAR_SOCK)<0)
424  err("Ioctl failed: %m\n");
425  printf("done\n");
426 }
427 
428 int main(int argc, char *argv[]) {
429  char* port=NULL;
430  int sock, nbd;
431  int blocksize=1024;
432  char *hostname=NULL;
433  char *nbddev=NULL;
434  int swap=0;
435  int cont=0;
436  int timeout=0;
437  int sdp=0;
438  int G_GNUC_UNUSED nofork=0; // if -dNOFORK
439  u64 size64;
440  u32 flags;
441  int c;
442  int nonspecial=0;
443  char* name=NULL;
444  uint32_t needed_flags=0;
445  uint32_t cflags=0;
446  uint32_t opts=0;
447  sigset_t block, old;
448  struct sigaction sa;
449  struct option long_options[] = {
450  { "block-size", required_argument, NULL, 'b' },
451  { "check", required_argument, NULL, 'c' },
452  { "disconnect", required_argument, NULL, 'd' },
453  { "help", no_argument, NULL, 'h' },
454  { "list", no_argument, NULL, 'l' },
455  { "name", required_argument, NULL, 'N' },
456  { "nofork", no_argument, NULL, 'n' },
457  { "persist", no_argument, NULL, 'p' },
458  { "sdp", no_argument, NULL, 'S' },
459  { "swap", no_argument, NULL, 's' },
460  { "systemd-mark", no_argument, NULL, 'm' },
461  { "timeout", required_argument, NULL, 't' },
462  { 0, 0, 0, 0 },
463  };
464 
465  logging();
466 
467  while((c=getopt_long_only(argc, argv, "-b:c:d:hlnN:pSst:", long_options, NULL))>=0) {
468  switch(c) {
469  case 1:
470  // non-option argument
471  if(strchr(optarg, '=')) {
472  // old-style 'bs=' or 'timeout='
473  // argument
474  fprintf(stderr, "WARNING: old-style command-line argument encountered. This is deprecated.\n");
475  if(!strncmp(optarg, "bs=", 3)) {
476  optarg+=3;
477  goto blocksize;
478  }
479  if(!strncmp(optarg, "timeout=", 8)) {
480  optarg+=8;
481  goto timeout;
482  }
483  usage("unknown option %s encountered", optarg);
484  exit(EXIT_FAILURE);
485  }
486  switch(nonspecial++) {
487  case 0:
488  // host
489  hostname=optarg;
490  break;
491  case 1:
492  // port
493  if(!strtol(optarg, NULL, 0)) {
494  // not parseable as a number, assume it's the device and we have a name
495  nbddev = optarg;
496  nonspecial++;
497  } else {
498  port = optarg;
499  }
500  break;
501  case 2:
502  // device
503  nbddev = optarg;
504  break;
505  default:
506  usage("too many non-option arguments specified");
507  exit(EXIT_FAILURE);
508  }
509  break;
510  case 'b':
511  blocksize:
512  blocksize=(int)strtol(optarg, NULL, 0);
513  break;
514  case 'c':
515  return check_conn(optarg, 1);
516  case 'd':
517  disconnect(optarg);
518  exit(EXIT_SUCCESS);
519  case 'h':
520  usage(NULL);
521  exit(EXIT_SUCCESS);
522  case 'l':
523  needed_flags |= NBD_FLAG_FIXED_NEWSTYLE;
524  cflags |= NBD_FLAG_C_FIXED_NEWSTYLE;
525  opts |= NBDC_DO_LIST;
526  name="";
527  nbddev="";
528  port = NBD_DEFAULT_PORT;
529  break;
530  case 'm':
531  argv[0][0] = '@';
532  break;
533  case 'n':
534  nofork=1;
535  break;
536  case 'N':
537  name=optarg;
538  if(!port) {
539  port = NBD_DEFAULT_PORT;
540  }
541  break;
542  case 'p':
543  cont=1;
544  break;
545  case 's':
546  swap=1;
547  break;
548  case 'S':
549  sdp=1;
550  break;
551  case 't':
552  timeout:
553  timeout=strtol(optarg, NULL, 0);
554  break;
555  default:
556  fprintf(stderr, "E: option eaten by 42 mice\n");
557  exit(EXIT_FAILURE);
558  }
559  }
560 
561  if((!port && !name) || !hostname || !nbddev) {
562  usage("not enough information specified");
563  exit(EXIT_FAILURE);
564  }
565 
566  sock = opennet(hostname, port, sdp);
567  if (sock < 0)
568  exit(EXIT_FAILURE);
569 
570  negotiate(sock, &size64, &flags, name, needed_flags, cflags, opts);
571 
572  nbd = open(nbddev, O_RDWR);
573  if (nbd < 0)
574  err("Cannot open NBD: %m\nPlease ensure the 'nbd' module is loaded.");
575 
576  setsizes(nbd, size64, blocksize, flags);
577  set_timeout(nbd, timeout);
578  finish_sock(sock, nbd, swap);
579  if (swap) {
580  /* try linux >= 2.6.36 interface first */
581  if (oom_adjust("/proc/self/oom_score_adj", "-1000")) {
582  /* fall back to linux <= 2.6.35 interface */
583  oom_adjust("/proc/self/oom_adj", "-17");
584  }
585  }
586 
587  /* Go daemon */
588 
589 #ifndef NOFORK
590  if(!nofork) {
591  if (daemon(0,0) < 0)
592  err("Cannot detach from terminal");
593  }
594 
595  memset(&sa, 0, sizeof(sa));
596  sa.sa_handler = SIG_IGN;
597  sigaction(SIGCHLD, &sa, NULL);
598 #endif
599  do {
600 #ifndef NOFORK
601 
602  sigfillset(&block);
603  sigdelset(&block, SIGKILL);
604  sigdelset(&block, SIGTERM);
605  sigdelset(&block, SIGPIPE);
606  sigprocmask(SIG_SETMASK, &block, &old);
607 
608  if (!fork()) {
609  /* Due to a race, the kernel NBD driver cannot
610  * call for a reread of the partition table
611  * in the handling of the NBD_DO_IT ioctl().
612  * Therefore, this is done in the first open()
613  * of the device. We therefore make sure that
614  * the device is opened at least once after the
615  * connection was made. This has to be done in a
616  * separate process, since the NBD_DO_IT ioctl()
617  * does not return until the NBD device has
618  * disconnected.
619  */
620  while(check_conn(nbddev, 0)) {
621  sleep(1);
622  }
623  open(nbddev, O_RDONLY);
624  exit(0);
625  }
626 #endif
627 
628  if (ioctl(nbd, NBD_DO_IT) < 0) {
629  int error = errno;
630  fprintf(stderr, "nbd,%d: Kernel call returned: %d", getpid(), error);
631  if(error==EBADR) {
632  /* The user probably did 'nbd-client -d' on us.
633  * quit */
634  cont=0;
635  } else {
636  if(cont) {
637  u64 new_size;
638  u32 new_flags;
639 
640  close(sock); close(nbd);
641  for (;;) {
642  fprintf(stderr, " Reconnecting\n");
643  sock = opennet(hostname, port, sdp);
644  if (sock >= 0)
645  break;
646  sleep (1);
647  }
648  nbd = open(nbddev, O_RDWR);
649  if (nbd < 0)
650  err("Cannot open NBD: %m");
651  negotiate(sock, &new_size, &new_flags, name, needed_flags, cflags, opts);
652  if (size64 != new_size) {
653  err("Size of the device changed. Bye");
654  }
655  setsizes(nbd, size64, blocksize,
656  new_flags);
657 
658  set_timeout(nbd, timeout);
659  finish_sock(sock,nbd,swap);
660  }
661  }
662  } else {
663  /* We're on 2.4. It's not clearly defined what exactly
664  * happened at this point. Probably best to quit, now
665  */
666  fprintf(stderr, "Kernel call returned.");
667  cont=0;
668  }
669  } while(cont);
670  printf("sock, ");
671  ioctl(nbd, NBD_CLEAR_SOCK);
672  printf("done\n");
673  return 0;
674 }
void setsizes(int nbd, u64 size64, int blocksize, u32 flags)
Definition: nbd-client.c:333
void disconnect(char *device)
Definition: nbd-client.c:414
#define NBD_REP_FLAG_ERROR
Definition: cliserv.h:159
#define NBD_OPT_LIST
Definition: cliserv.h:154
#define NBD_CLEAR_SOCK
Definition: nbd.h:24
#define NBD_SET_SOCK
Definition: nbd.h:20
u64 ntohll(u64 a)
Definition: cliserv.h:138
void finish_sock(int sock, int nbd, int swap)
Definition: nbd-client.c:367
void setmysockopt(int sock)
Definition: cliserv.h:64
#define NBD_REP_ERR_POLICY
Definition: cliserv.h:161
static u64 rep_magic
Definition: cliserv.h:59
#define NBD_SET_SIZE_BLOCKS
Definition: nbd.h:27
void err_nonfatal(const char *s)
Definition: cliserv.h:92
void usage(char *errmsg,...)
Definition: nbd-client.c:390
#define NBD_OPT_EXPORT_NAME
Definition: cliserv.h:152
#define NBD_REP_ACK
Definition: cliserv.h:157
#define NBD_OPT_ABORT
Definition: cliserv.h:153
static u64 cliserv_magic
Definition: cliserv.h:57
#define NBDC_DO_LIST
Definition: nbd-client.c:51
#define AI_NUMERICSERV
Definition: netdb-compat.h:21
#define NBD_DISCONNECT
Definition: nbd.h:28
#define NBD_SET_TIMEOUT
Definition: nbd.h:29
int check_conn(char *devname, int do_print)
Definition: nbd-client.c:53
#define NBD_FLAG_C_FIXED_NEWSTYLE
Definition: cliserv.h:168
void err(const char *s) G_GNUC_NORETURN
Definition: cliserv.h:120
void ask_list(int sock)
Definition: nbd-client.c:136
#define NBD_FLAG_READ_ONLY
Definition: nbd.h:45
#define G_GNUC_UNUSED
Definition: cliserv.h:88
#define NBD_SET_FLAGS
Definition: nbd.h:30
void set_timeout(int nbd, int timeout)
Definition: nbd-client.c:359
#define NBD_SET_BLKSIZE
Definition: nbd.h:21
int main(int argc, char **argv)
#define htonll
Definition: cliserv.h:146
static int oom_adjust(const char *file, const char *value)
Definition: nbd-client.c:376
#define NBD_REP_SERVER
Definition: cliserv.h:158
#define NBD_DEFAULT_PORT
Definition: cliserv.h:148
#define PACKAGE_VERSION
Definition: config.h:157
int opennet(char *name, char *portstr, int sdp)
Definition: nbd-client.c:81
static u64 opts_magic
Definition: cliserv.h:58
#define NBD_FLAG_FIXED_NEWSTYLE
Definition: cliserv.h:166
#define INIT_PASSWD
Definition: cliserv.h:60
__be32 magic
Definition: nbd.h:37
#define NBD_DO_IT
Definition: nbd.h:23
void negotiate(int sock, u64 *rsize64, u32 *flags, char *name, uint32_t needed_flags, uint32_t client_flags, uint32_t do_opts)
Definition: nbd-client.c:232
void logging(void)
Definition: cliserv.h:125
__be32 len
Definition: nbd.h:41