Skip to content

Commit

Permalink
qemu-storage-daemon: add --pidfile option
Browse files Browse the repository at this point in the history
Daemons often have a --pidfile option where the pid is written to a file
so that scripts can stop the daemon by sending a signal.

The pid file also acts as a lock to prevent multiple instances of the
daemon from launching for a given pid file.

QEMU, qemu-nbd, qemu-ga, virtiofsd, and qemu-pr-helper all support the
--pidfile option. Add it to qemu-storage-daemon too.

Reported-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20210302142746.170535-1-stefanha@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
  • Loading branch information
stefanhaRH authored and kevmw committed Mar 8, 2021
1 parent 501a4b3 commit 03d2b41
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
14 changes: 14 additions & 0 deletions docs/tools/qemu-storage-daemon.rst
Expand Up @@ -118,6 +118,20 @@ Standard options:
List object properties with ``<type>,help``. See the :manpage:`qemu(1)`
manual page for a description of the object properties.

.. option:: --pidfile PATH

is the path to a file where the daemon writes its pid. This allows scripts to
stop the daemon by sending a signal::

$ kill -SIGTERM $(<path/to/qsd.pid)

A file lock is applied to the file so only one instance of the daemon can run
with a given pid file path. The daemon unlinks its pid file when terminating.

The pid file is written after chardevs, exports, and NBD servers have been
created but before accepting connections. The daemon has started successfully
when the pid file is written and clients may begin connecting.

Examples
--------
Launch the daemon with QMP monitor socket ``qmp.sock`` so clients can execute
Expand Down
36 changes: 36 additions & 0 deletions storage-daemon/qemu-storage-daemon.c
Expand Up @@ -59,6 +59,7 @@
#include "sysemu/runstate.h"
#include "trace/control.h"

static const char *pid_file;
static volatile bool exit_requested = false;

void qemu_system_killed(int signal, pid_t pid)
Expand Down Expand Up @@ -115,6 +116,8 @@ static void help(void)
" See the qemu(1) man page for documentation of the\n"
" objects that can be added.\n"
"\n"
" --pidfile <path> write process ID to a file after startup\n"
"\n"
QEMU_HELP_BOTTOM "\n",
error_get_progname());
}
Expand All @@ -126,6 +129,7 @@ enum {
OPTION_MONITOR,
OPTION_NBD_SERVER,
OPTION_OBJECT,
OPTION_PIDFILE,
};

extern QemuOptsList qemu_chardev_opts;
Expand Down Expand Up @@ -178,6 +182,7 @@ static void process_options(int argc, char *argv[])
{"monitor", required_argument, NULL, OPTION_MONITOR},
{"nbd-server", required_argument, NULL, OPTION_NBD_SERVER},
{"object", required_argument, NULL, OPTION_OBJECT},
{"pidfile", required_argument, NULL, OPTION_PIDFILE},
{"trace", required_argument, NULL, 'T'},
{"version", no_argument, NULL, 'V'},
{0, 0, 0, 0}
Expand Down Expand Up @@ -289,6 +294,9 @@ static void process_options(int argc, char *argv[])
qobject_unref(args);
break;
}
case OPTION_PIDFILE:
pid_file = optarg;
break;
case 1:
error_report("Unexpected argument");
exit(EXIT_FAILURE);
Expand All @@ -299,6 +307,27 @@ static void process_options(int argc, char *argv[])
loc_set_none();
}

static void pid_file_cleanup(void)
{
unlink(pid_file);
}

static void pid_file_init(void)
{
Error *err = NULL;

if (!pid_file) {
return;
}

if (!qemu_write_pidfile(pid_file, &err)) {
error_reportf_err(err, "cannot create PID file: ");
exit(EXIT_FAILURE);
}

atexit(pid_file_cleanup);
}

int main(int argc, char *argv[])
{
#ifdef CONFIG_POSIX
Expand Down Expand Up @@ -326,6 +355,13 @@ int main(int argc, char *argv[])
qemu_init_main_loop(&error_fatal);
process_options(argc, argv);

/*
* Write the pid file after creating chardevs, exports, and NBD servers but
* before accepting connections. This ordering is documented. Do not change
* it.
*/
pid_file_init();

while (!exit_requested) {
main_loop_wait(false);
}
Expand Down

0 comments on commit 03d2b41

Please sign in to comment.