diff options
Diffstat (limited to 'qemu-nbd.c')
| -rw-r--r-- | qemu-nbd.c | 68 |
1 files changed, 48 insertions, 20 deletions
diff --git a/qemu-nbd.c b/qemu-nbd.c index 4276163564..5b2757920c 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -73,7 +73,6 @@ #define MBR_SIZE 512 -static int verbose; static char *srcpath; static SocketAddress *saddr; static int persistent = 0; @@ -272,9 +271,15 @@ static void *show_parts(void *arg) return NULL; } +struct NbdClientOpts { + char *device; + bool fork_process; + bool verbose; +}; + static void *nbd_client_thread(void *arg) { - char *device = arg; + struct NbdClientOpts *opts = arg; NBDExportInfo info = { .request_sizes = false, .name = g_strdup("") }; QIOChannelSocket *sioc; int fd = -1; @@ -298,10 +303,10 @@ static void *nbd_client_thread(void *arg) goto out; } - fd = open(device, O_RDWR); + fd = open(opts->device, O_RDWR); if (fd < 0) { /* Linux-only, we can use %m in printf. */ - error_report("Failed to open %s: %m", device); + error_report("Failed to open %s: %m", opts->device); goto out; } @@ -311,14 +316,18 @@ static void *nbd_client_thread(void *arg) } /* update partition table */ - pthread_create(&show_parts_thread, NULL, show_parts, device); + pthread_create(&show_parts_thread, NULL, show_parts, opts->device); - if (verbose) { + if (opts->verbose && !opts->fork_process) { fprintf(stderr, "NBD device %s is now connected to %s\n", - device, srcpath); + opts->device, srcpath); } else { /* Close stderr so that the qemu-nbd process exits. */ - dup2(STDOUT_FILENO, STDERR_FILENO); + if (dup2(STDOUT_FILENO, STDERR_FILENO) < 0) { + error_report("Could not set stderr to /dev/null: %s", + strerror(errno)); + exit(EXIT_FAILURE); + } } if (nbd_client(fd) < 0) { @@ -573,9 +582,9 @@ int main(int argc, char **argv) const char *tlshostname = NULL; bool imageOpts = false; bool writethrough = false; /* Client will flush as needed. */ + bool verbose = false; bool fork_process = false; bool list = false; - int old_stderr = -1; unsigned socket_activation; const char *pid_file_name = NULL; const char *selinux_label = NULL; @@ -738,7 +747,7 @@ int main(int argc, char **argv) } break; case 'v': - verbose = 1; + verbose = true; break; case 'V': version(argv[0]); @@ -928,19 +937,30 @@ int main(int argc, char **argv) error_report("Failed to fork: %s", strerror(errno)); exit(EXIT_FAILURE); } else if (pid == 0) { - close(stderr_fd[0]); + int saved_errno; - /* Remember parent's stderr if we will be restoring it. */ - if (fork_process) { - old_stderr = dup(STDERR_FILENO); - } + close(stderr_fd[0]); ret = qemu_daemon(1, 0); + saved_errno = errno; /* dup2 will overwrite error below */ /* Temporarily redirect stderr to the parent's pipe... */ - dup2(stderr_fd[1], STDERR_FILENO); + if (dup2(stderr_fd[1], STDERR_FILENO) < 0) { + char str[256]; + snprintf(str, sizeof(str), + "%s: Failed to link stderr to the pipe: %s\n", + g_get_prgname(), strerror(errno)); + /* + * We are unable to use error_report() here as we need to get + * stderr pointed to the parent's pipe. Write to that pipe + * manually. + */ + ret = write(stderr_fd[1], str, strlen(str)); + exit(EXIT_FAILURE); + } + if (ret < 0) { - error_report("Failed to daemonize: %s", strerror(errno)); + error_report("Failed to daemonize: %s", strerror(saved_errno)); exit(EXIT_FAILURE); } @@ -1125,8 +1145,13 @@ int main(int argc, char **argv) if (device) { #if HAVE_NBD_DEVICE int ret; + struct NbdClientOpts opts = { + .device = device, + .fork_process = fork_process, + .verbose = verbose, + }; - ret = pthread_create(&client_thread, NULL, nbd_client_thread, device); + ret = pthread_create(&client_thread, NULL, nbd_client_thread, &opts); if (ret != 0) { error_report("Failed to create client thread: %s", strerror(ret)); exit(EXIT_FAILURE); @@ -1152,8 +1177,11 @@ int main(int argc, char **argv) } if (fork_process) { - dup2(old_stderr, STDERR_FILENO); - close(old_stderr); + if (dup2(STDOUT_FILENO, STDERR_FILENO) < 0) { + error_report("Could not set stderr to /dev/null: %s", + strerror(errno)); + exit(EXIT_FAILURE); + } } state = RUNNING; |