Skip to content
Snippets Groups Projects
Commit 105a7940 authored by Simon McVittie's avatar Simon McVittie
Browse files

launcher: Allow details and readiness to be moved to another fd


bwrap(1) holds stdin, stdout and stderr open, so we need to do this
on a different fd.

Resolves: pressure-vessel#6
Signed-off-by: default avatarSimon McVittie <smcv@collabora.com>
parent 838ff625
No related branches found
No related tags found
No related merge requests found
...@@ -12,6 +12,7 @@ pressure-vessel-launcher - server to launch processes in a container ...@@ -12,6 +12,7 @@ pressure-vessel-launcher - server to launch processes in a container
**pressure-vessel-launcher** **pressure-vessel-launcher**
[**--replace**] [**--replace**]
[**--verbose**] [**--verbose**]
[**--info-fd**] *N*
{**--bus-name** *NAME*|**--socket** *SOCKET*|**--socket-directory** *PATH*} {**--bus-name** *NAME*|**--socket** *SOCKET*|**--socket-directory** *PATH*}
# DESCRIPTION # DESCRIPTION
...@@ -52,6 +53,11 @@ D-Bus session bus, and executes arbitrary commands as subprocesses. ...@@ -52,6 +53,11 @@ D-Bus session bus, and executes arbitrary commands as subprocesses.
readable, meaning either data is available or end-of-file has been readable, meaning either data is available or end-of-file has been
reached. reached.
**--info-fd** *FD*
: Print details of the server on *FD* (see **OUTPUT** below).
This fd will be closed (reach end-of-file) when the server is ready.
The default is standard output, equivalent to **--info-fd=1**.
**--replace** **--replace**
: When used with **--bus-name**, allow other : When used with **--bus-name**, allow other
**pressure-vessel-launcher** processes to take over the bus name, **pressure-vessel-launcher** processes to take over the bus name,
...@@ -64,7 +70,9 @@ D-Bus session bus, and executes arbitrary commands as subprocesses. ...@@ -64,7 +70,9 @@ D-Bus session bus, and executes arbitrary commands as subprocesses.
# OUTPUT # OUTPUT
**pressure-vessel-launcher** prints zero or more lines of **pressure-vessel-launcher** prints zero or more lines of
structured text on standard output, and then closes standard output: structured text on the file descriptor specified by **--info-fd**,
and then closes both the **--info-fd** and standard output. The default
**--info-fd** is standard output.
**socket=**PATH **socket=**PATH
: The launcher is listening on *PATH*, and can be contacted by : The launcher is listening on *PATH*, and can be contacted by
...@@ -86,11 +94,12 @@ structured text on standard output, and then closes standard output: ...@@ -86,11 +94,12 @@ structured text on standard output, and then closes standard output:
(such as **dbus-send --session**) to the session bus and sending (such as **dbus-send --session**) to the session bus and sending
method calls to _NAME_. method calls to _NAME_.
Clients must wait until after standard output has been closed, or wait Clients must wait until after either the **--info-fd** or standard output
for the bus name to appear, before connecting by bus name. has been closed, or wait for the bus name to appear, before connecting
by bus name.
Clients must wait until after standard output has been closed before Clients must wait until after either the **--info-fd** or standard output
connecting by socket name. has been closed before connecting by socket name.
Unstructured diagnostic messages are printed on standard error, Unstructured diagnostic messages are printed on standard error,
which remains open throughout. which remains open throughout.
...@@ -211,13 +220,15 @@ instead of fifos. ...@@ -211,13 +220,15 @@ instead of fifos.
mkfifo "${tmpdir}/ready-fifo" mkfifo "${tmpdir}/ready-fifo"
pressure-vessel-wrap \ pressure-vessel-wrap \
--filesystem="${tmpdir}" \ --filesystem="${tmpdir}" \
--pass-fd=3
... \ ... \
-- \ -- \
pressure-vessel-launcher \ pressure-vessel-launcher \
--exit-on-readable=0 \ --exit-on-readable=0 \
--info-fd=3 \
--socket="${tmpdir}/launcher" \ --socket="${tmpdir}/launcher" \
< "${tmpdir}/exit-fifo" \ < "${tmpdir}/exit-fifo" \
> "${tmpdir}/ready-fifo" \ 3> "${tmpdir}/ready-fifo" \
& &
launcher_pid="$!" launcher_pid="$!"
sleep infinity > "${tmpdir}/exit-fifo" & sleep infinity > "${tmpdir}/exit-fifo" &
......
...@@ -57,12 +57,27 @@ typedef GDBusServer AutoDBusServer; ...@@ -57,12 +57,27 @@ typedef GDBusServer AutoDBusServer;
G_DEFINE_AUTOPTR_CLEANUP_FUNC(AutoDBusServer, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(AutoDBusServer, g_object_unref)
static FILE *original_stdout = NULL; static FILE *original_stdout = NULL;
static FILE *info_fh = NULL;
static GDBusConnection *session_bus = NULL; static GDBusConnection *session_bus = NULL;
static GHashTable *client_pid_data_hash = NULL; static GHashTable *client_pid_data_hash = NULL;
static guint name_owner_id = 0; static guint name_owner_id = 0;
static GMainLoop *main_loop; static GMainLoop *main_loop;
static PvLauncher1 *launcher; static PvLauncher1 *launcher;
/*
* Close the --info-fd, and also close standard output (if different).
*/
static void
close_info_fh (void)
{
if (info_fh == original_stdout)
original_stdout = NULL;
else
g_clear_pointer (&original_stdout, fclose);
g_clear_pointer (&info_fh, fclose);
}
static void static void
skeleton_died_cb (gpointer data) skeleton_died_cb (gpointer data)
{ {
...@@ -558,10 +573,10 @@ on_name_acquired (GDBusConnection *connection, ...@@ -558,10 +573,10 @@ on_name_acquired (GDBusConnection *connection,
if (*ret == EX_UNAVAILABLE) if (*ret == EX_UNAVAILABLE)
{ {
*ret = 0; *ret = 0;
g_assert (original_stdout != NULL); g_assert (info_fh != NULL);
fprintf (original_stdout, "bus_name=%s\n", name); fprintf (info_fh, "bus_name=%s\n", name);
fflush (original_stdout); fflush (info_fh);
g_clear_pointer (&original_stdout, fclose); close_info_fh ();
} }
} }
...@@ -963,6 +978,7 @@ set_up_exit_on_readable (int fd, ...@@ -963,6 +978,7 @@ set_up_exit_on_readable (int fd,
static gchar *opt_bus_name = NULL; static gchar *opt_bus_name = NULL;
static gint opt_exit_on_readable_fd = -1; static gint opt_exit_on_readable_fd = -1;
static gint opt_info_fd = -1;
static gboolean opt_replace = FALSE; static gboolean opt_replace = FALSE;
static gchar *opt_socket = NULL; static gchar *opt_socket = NULL;
static gchar *opt_socket_directory = NULL; static gchar *opt_socket_directory = NULL;
...@@ -980,6 +996,11 @@ static GOptionEntry options[] = ...@@ -980,6 +996,11 @@ static GOptionEntry options[] =
"Exit when data is available for reading or when end-of-file is " "Exit when data is available for reading or when end-of-file is "
"reached on this fd, usually 0 for stdin.", "reached on this fd, usually 0 for stdin.",
"FD" }, "FD" },
{ "info-fd", '\0',
G_OPTION_FLAG_NONE, G_OPTION_ARG_INT, &opt_info_fd,
"Indicate readiness and print details of how to connect on this "
"file descriptor instead of stdout.",
"FD" },
{ "replace", '\0', { "replace", '\0',
G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_replace, G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_replace,
"Replace a previous instance with the same bus name. " "Replace a previous instance with the same bus name. "
...@@ -1076,6 +1097,24 @@ main (int argc, ...@@ -1076,6 +1097,24 @@ main (int argc,
goto out; goto out;
} }
if (opt_info_fd > 0) /* < 0 means unset, and 0 is stdout itself */
{
info_fh = fdopen (opt_info_fd, "w");
if (info_fh == NULL)
{
glnx_null_throw_errno_prefix (error,
"Unable to create a stdio wrapper for fd %d",
opt_info_fd);
ret = EX_OSERR;
goto out;
}
}
else
{
info_fh = original_stdout;
}
if (opt_exit_on_readable_fd >= 0) if (opt_exit_on_readable_fd >= 0)
{ {
if (!set_up_exit_on_readable (opt_exit_on_readable_fd, if (!set_up_exit_on_readable (opt_exit_on_readable_fd,
...@@ -1261,16 +1300,16 @@ main (int argc, ...@@ -1261,16 +1300,16 @@ main (int argc,
} }
if (opt_socket != NULL) if (opt_socket != NULL)
fprintf (original_stdout, "socket=%s\n", opt_socket); fprintf (info_fh, "socket=%s\n", opt_socket);
if (server != NULL) if (server != NULL)
fprintf (original_stdout, "dbus_address=%s\n", fprintf (info_fh, "dbus_address=%s\n",
g_dbus_server_get_client_address (server)); g_dbus_server_get_client_address (server));
if (opt_bus_name == NULL) if (opt_bus_name == NULL)
{ {
fflush (original_stdout); fflush (info_fh);
g_clear_pointer (&original_stdout, fclose); close_info_fh ();
} }
g_debug ("Entering main loop"); g_debug ("Entering main loop");
...@@ -1307,7 +1346,7 @@ out: ...@@ -1307,7 +1346,7 @@ out:
ret = EX_UNAVAILABLE; ret = EX_UNAVAILABLE;
g_clear_error (&local_error); g_clear_error (&local_error);
g_clear_pointer (&original_stdout, fclose); close_info_fh ();
g_debug ("Exiting with status %d", ret); g_debug ("Exiting with status %d", ret);
return ret; return ret;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment