core: set $JOURNAL_STREAM to the dev_t/ino_t of the journal stream of executed services
This permits services to detect whether their stdout/stderr is connected to the journal, and if so talk to the journal directly, thus permitting carrying of metadata. As requested by the gtk folks: #2473
This commit is contained in:
+43
-7
@@ -454,7 +454,10 @@ static int setup_output(
|
||||
int fileno,
|
||||
int socket_fd,
|
||||
const char *ident,
|
||||
uid_t uid, gid_t gid) {
|
||||
uid_t uid,
|
||||
gid_t gid,
|
||||
dev_t *journal_stream_dev,
|
||||
ino_t *journal_stream_ino) {
|
||||
|
||||
ExecOutput o;
|
||||
ExecInput i;
|
||||
@@ -464,6 +467,8 @@ static int setup_output(
|
||||
assert(context);
|
||||
assert(params);
|
||||
assert(ident);
|
||||
assert(journal_stream_dev);
|
||||
assert(journal_stream_ino);
|
||||
|
||||
if (fileno == STDOUT_FILENO && params->stdout_fd >= 0) {
|
||||
|
||||
@@ -543,6 +548,17 @@ static int setup_output(
|
||||
if (r < 0) {
|
||||
log_unit_error_errno(unit, r, "Failed to connect %s to the journal socket, ignoring: %m", fileno == STDOUT_FILENO ? "stdout" : "stderr");
|
||||
r = open_null_as(O_WRONLY, fileno);
|
||||
} else {
|
||||
struct stat st;
|
||||
|
||||
/* If we connected this fd to the journal via a stream, patch the device/inode into the passed
|
||||
* parameters, but only then. This is useful so that we can set $JOURNAL_STREAM that permits
|
||||
* services to detect whether they are connected to the journal or not. */
|
||||
|
||||
if (fstat(fileno, &st) >= 0) {
|
||||
*journal_stream_dev = st.st_dev;
|
||||
*journal_stream_ino = st.st_ino;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
|
||||
@@ -1286,6 +1302,8 @@ static int build_environment(
|
||||
const char *home,
|
||||
const char *username,
|
||||
const char *shell,
|
||||
dev_t journal_stream_dev,
|
||||
ino_t journal_stream_ino,
|
||||
char ***ret) {
|
||||
|
||||
_cleanup_strv_free_ char **our_env = NULL;
|
||||
@@ -1295,7 +1313,7 @@ static int build_environment(
|
||||
assert(c);
|
||||
assert(ret);
|
||||
|
||||
our_env = new0(char*, 11);
|
||||
our_env = new0(char*, 12);
|
||||
if (!our_env)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -1367,8 +1385,15 @@ static int build_environment(
|
||||
our_env[n_env++] = x;
|
||||
}
|
||||
|
||||
if (journal_stream_dev != 0 && journal_stream_ino != 0) {
|
||||
if (asprintf(&x, "JOURNAL_STREAM=" DEV_FMT ":" INO_FMT, journal_stream_dev, journal_stream_ino) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
our_env[n_env++] = x;
|
||||
}
|
||||
|
||||
our_env[n_env++] = NULL;
|
||||
assert(n_env <= 11);
|
||||
assert(n_env <= 12);
|
||||
|
||||
*ret = our_env;
|
||||
our_env = NULL;
|
||||
@@ -1481,10 +1506,12 @@ static int exec_child(
|
||||
_cleanup_strv_free_ char **our_env = NULL, **pass_env = NULL, **accum_env = NULL, **final_argv = NULL;
|
||||
_cleanup_free_ char *mac_selinux_context_net = NULL;
|
||||
const char *username = NULL, *home = NULL, *shell = NULL, *wd;
|
||||
dev_t journal_stream_dev = 0;
|
||||
ino_t journal_stream_ino = 0;
|
||||
bool needs_mount_namespace;
|
||||
uid_t uid = UID_INVALID;
|
||||
gid_t gid = GID_INVALID;
|
||||
int i, r;
|
||||
bool needs_mount_namespace;
|
||||
|
||||
assert(unit);
|
||||
assert(command);
|
||||
@@ -1584,13 +1611,13 @@ static int exec_child(
|
||||
return r;
|
||||
}
|
||||
|
||||
r = setup_output(unit, context, params, STDOUT_FILENO, socket_fd, basename(command->path), uid, gid);
|
||||
r = setup_output(unit, context, params, STDOUT_FILENO, socket_fd, basename(command->path), uid, gid, &journal_stream_dev, &journal_stream_ino);
|
||||
if (r < 0) {
|
||||
*exit_status = EXIT_STDOUT;
|
||||
return r;
|
||||
}
|
||||
|
||||
r = setup_output(unit, context, params, STDERR_FILENO, socket_fd, basename(command->path), uid, gid);
|
||||
r = setup_output(unit, context, params, STDERR_FILENO, socket_fd, basename(command->path), uid, gid, &journal_stream_dev, &journal_stream_ino);
|
||||
if (r < 0) {
|
||||
*exit_status = EXIT_STDERR;
|
||||
return r;
|
||||
@@ -1729,7 +1756,16 @@ static int exec_child(
|
||||
}
|
||||
}
|
||||
|
||||
r = build_environment(context, params, n_fds, home, username, shell, &our_env);
|
||||
r = build_environment(
|
||||
context,
|
||||
params,
|
||||
n_fds,
|
||||
home,
|
||||
username,
|
||||
shell,
|
||||
journal_stream_dev,
|
||||
journal_stream_ino,
|
||||
&our_env);
|
||||
if (r < 0) {
|
||||
*exit_status = EXIT_MEMORY;
|
||||
return r;
|
||||
|
||||
Reference in New Issue
Block a user