56
57
static void open_plugin_so (const char *filename);
57
58
static void start_serving (void);
58
59
static void set_up_signals (void);
60
static void run_command (void);
59
61
static void change_user (void);
60
62
static void write_pidfile (void);
61
63
static void fork_into_background (void);
90
93
{ "port", 1, NULL, 'p' },
91
94
{ "read-only", 0, NULL, 'r' },
92
95
{ "readonly", 0, NULL, 'r' },
96
{ "run", 1, NULL, 0 },
93
97
{ "single", 0, NULL, 's' },
94
98
{ "stdin", 0, NULL, 's' },
95
99
{ "unix", 1, NULL, 'U' },
104
108
printf ("nbdkit [--dump-config] [-f] [-g GROUP] [-i IPADDR]\n"
105
" [-P PIDFILE] [-p PORT] [-r] [-s]\n"
109
" [-P PIDFILE] [-p PORT] [-r] [--run CMD] [-s]\n"
106
110
" [-U SOCKET] [-u USER] [-v] [-V]\n"
107
111
" PLUGIN [key=value [key=value [...]]]\n"
143
147
exit (EXIT_SUCCESS);
149
else if (strcmp (long_options[option_index].name, "run") == 0) {
146
154
fprintf (stderr, "%s: unknown long option: %s (%d)\n",
147
155
program_name, long_options[option_index].name, option_index);
148
156
exit (EXIT_FAILURE);
341
350
* TCP/IP and Unix sockets, or even multiple TCP/IP ports.
343
352
if ((port && unixsocket) || (port && listen_stdin) ||
344
(unixsocket && listen_stdin)) {
345
fprintf (stderr, "%s: -p, -U and -s options cannot appear at the same time\n",
353
(unixsocket && listen_stdin) || (listen_stdin && run)) {
355
"%s: -p, -U and -s options cannot appear at the same time\n",
347
357
exit (EXIT_FAILURE);
492
503
debug ("forked into background (new pid = %d)", getpid ());
517
/* Construct an nbd "URL". Unfortunately guestfish and qemu take
518
* different syntax, so try to guess which one we need.
520
if (strstr (run, "guestfish")) {
522
r = asprintf (&url, "nbd://localhost:%s", port);
525
r = asprintf (&url, "nbd://?socket=%s", unixsocket);
531
r = asprintf (&url, "nbd:localhost:%s", port);
533
r = asprintf (&url, "nbd:unix:%s", unixsocket);
542
/* Construct the final command including shell variables. */
543
/* XXX Escaping again. */
549
url, port ? port : "", unixsocket ? unixsocket : "", run);
557
/* Fork. Captive nbdkit runs as the child process. */
564
if (pid > 0) { /* Parent process is the run command. */
568
else if (WIFSIGNALED (r)) {
569
fprintf (stderr, "%s: external command was killed by signal %d\n",
570
program_name, WTERMSIG (r));
573
else if (WIFSTOPPED (r)) {
574
fprintf (stderr, "%s: external command was stopped by signal %d\n",
575
program_name, WSTOPSIG (r));
579
kill (pid, SIGTERM); /* Kill captive nbdkit. */
586
debug ("forked into background (new pid = %d)", getpid ());
496
590
parseuser (const char *id)