summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-04-20 20:26:34 +0200
committerLennart Poettering <lennart@poettering.net>2016-04-20 20:26:34 +0200
commitf15ab461ec10cb0164b9e6110957012d052415ea (patch)
tree51bac2b0baf064fc0ec93133e88656e46a3ca71a
parent129baf1bbfe3174a667c1ae73de131c503c025ea (diff)
parentdf8dee85da5fa41e95dd7f536e67fcc6940a6488 (diff)
Merge pull request #3074 from keszybz/tmpfiles
systemd-tmpfiles improvements, nspawn -E, honouring $TERM in pid1
-rw-r--r--man/machinectl.xml18
-rw-r--r--man/systemd-nspawn.xml3
-rw-r--r--man/systemd-run.xml8
-rw-r--r--man/systemd-tmpfiles.xml10
-rw-r--r--man/tmpfiles.d.xml81
-rw-r--r--src/basic/terminal-util.c19
-rw-r--r--src/core/main.c2
-rw-r--r--src/machine/machinectl.c7
-rw-r--r--src/nspawn/nspawn.c7
-rw-r--r--src/run/run.c7
-rw-r--r--src/tmpfiles/tmpfiles.c88
11 files changed, 142 insertions, 108 deletions
diff --git a/man/machinectl.xml b/man/machinectl.xml
index a77d2419af..43a3b98840 100644
--- a/man/machinectl.xml
+++ b/man/machinectl.xml
@@ -195,16 +195,14 @@
</varlistentry>
<varlistentry>
- <term><option>--setenv=</option></term>
-
- <listitem><para>When used with the <command>shell</command>
- command, sets an environment variable to pass to the executed
- shell. Takes a pair of environment variable name and value,
- separated by <literal>=</literal> as argument. This switch
- may be used multiple times to set multiple environment
- variables. Note that this switch is not supported for the
- <command>login</command> command (see
- below).</para></listitem>
+ <term><option>-E <replaceable>NAME</replaceable>=<replaceable>VALUE</replaceable></option></term>
+ <term><option>--setenv=<replaceable>NAME</replaceable>=<replaceable>VALUE</replaceable></option></term>
+
+ <listitem><para>When used with the <command>shell</command> command, sets an environment
+ variable to pass to the executed shell. Takes an environment variable name and value,
+ separated by <literal>=</literal>. This switch may be used multiple times to set multiple
+ environment variables. Note that this switch is not supported for the
+ <command>login</command> command (see below).</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index 8a004af1a2..6732b9d7be 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -737,7 +737,8 @@
</varlistentry>
<varlistentry>
- <term><option>--setenv=</option></term>
+ <term><option>-E <replaceable>NAME</replaceable>=<replaceable>VALUE</replaceable></option></term>
+ <term><option>--setenv=<replaceable>NAME</replaceable>=<replaceable>VALUE</replaceable></option></term>
<listitem><para>Specifies an environment variable assignment
to pass to the init process in the container, in the format
diff --git a/man/systemd-run.xml b/man/systemd-run.xml
index 473f83eac6..245daae946 100644
--- a/man/systemd-run.xml
+++ b/man/systemd-run.xml
@@ -226,11 +226,11 @@
</varlistentry>
<varlistentry>
- <term><option>--setenv=</option></term>
+ <term><option>-E <replaceable>NAME</replaceable>=<replaceable>VALUE</replaceable></option></term>
+ <term><option>--setenv=<replaceable>NAME</replaceable>=<replaceable>VALUE</replaceable></option></term>
- <listitem><para>Runs the service process with the specified
- environment variables set. Also see
- <varname>Environment=</varname> in
+ <listitem><para>Runs the service process with the specified environment variable set.
+ Also see <varname>Environment=</varname> in
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
</listitem>
</varlistentry>
diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml
index 447a7eaa17..c1aab51551 100644
--- a/man/systemd-tmpfiles.xml
+++ b/man/systemd-tmpfiles.xml
@@ -75,11 +75,11 @@
<citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
</para>
- <para>If invoked with no arguments, it applies all directives from
- all configuration files. If one or more absolute filenames are passed on
- the command line, only the directives in these files are applied.
- If only the basename of a configuration file is specified, all
- configuration directories as specified in
+ <para>If invoked with no arguments, it applies all directives from all configuration
+ files. If one or more absolute filenames are passed on the command line, only the
+ directives in these files are applied. If <literal>-</literal> is specified instead
+ of a filename, directives are read from standard input. If only the basename of a
+ configuration file is specified, all configuration directories as specified in
<citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
are searched for a matching file.</para>
</refsect1>
diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml
index 3b6b1e3f11..957475d2bd 100644
--- a/man/tmpfiles.d.xml
+++ b/man/tmpfiles.d.xml
@@ -157,13 +157,23 @@
<varlistentry>
<term><varname>d</varname></term>
- <listitem><para>Create a directory if it does not exist yet.
- </para></listitem>
+ <listitem><para>Create a directory. The mode and ownership will be adjusted if
+ specified and the directory already exists. Contents of this directory are subject
+ to time based cleanup if the time argument is specified.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>D</varname></term>
- <listitem><para>Create or empty a directory.</para></listitem>
+ <listitem><para>Similar to <varname>d</varname>, but in addition the contents
+ of the directory will be removed when <option>--remove</option> is used.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>e</varname></term>
+ <listitem><para>Similar to <varname>d</varname>, but the directory will not be
+ created if it does not exist. Lines of this type accept shell-style globs in
+ place of normal path names.</para></listitem>
</varlistentry>
<varlistentry>
@@ -577,7 +587,7 @@
unconditionally.</para>
<para>The age field only applies to lines starting with
- <varname>d</varname>, <varname>D</varname>,
+ <varname>d</varname>, <varname>D</varname>, <varname>e</varname>,
<varname>v</varname>, <varname>q</varname>,
<varname>Q</varname>, <varname>C</varname>, <varname>x</varname>
and <varname>X</varname>. If omitted or set to
@@ -612,22 +622,63 @@
</refsect1>
<refsect1>
- <title>Example</title>
+ <title>Examples</title>
<example>
- <title>/etc/tmpfiles.d/screen.conf example</title>
- <para><command>screen</command> needs two directories created at
- boot with specific modes and ownership.</para>
+ <title>Create directories with specific mode and ownership</title>
+ <para>
+ <citerefentry><refentrytitle>screen</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ needs two directories created at boot with specific modes and ownership:</para>
+
+ <programlisting># /usr/lib/tmpfiles.d/screen.conf
+d /run/screens 1777 root screen 10d
+d /run/uscreens 0755 root screen 10d12h
+</programlisting>
+
+ <para>Contents of <filename>/run/screens</filename> and /run/uscreens will
+ cleaned up after 10 and 10½ days, respectively.</para>
+ </example>
- <programlisting>d /run/screens 1777 root root 10d
-d /run/uscreens 0755 root root 10d12h
-t /run/screen - - - - user.name="John Smith" security.SMACK64=screen</programlisting>
+ <example>
+ <title>Create a directory with a SMACK attribute</title>
+ <programlisting>D /run/cups - - - -
+t /run/cups - - - - security.SMACK64=printing user.attr-with-spaces="foo bar"
+ </programlisting>
+
+ <para>The direcory will be owned by root and have default mode. It's contents are
+ not subject to time based cleanup, but will be obliterated when
+ <command>systemd-tmpfiles --remove</command> runs.</para>
</example>
+
<example>
- <title>/etc/tmpfiles.d/abrt.conf example</title>
- <para><command>abrt</command> needs a directory created at boot with specific mode and ownership and its content should be preserved.</para>
+ <title>Create a directory and prevent its contents from cleanup</title>
+ <para>
+ <citerefentry><refentrytitle>abrt</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ needs a directory created at boot with specific mode and ownership and its content
+ should be preserved from the automatic cleanup applied to the contents of
+ <filename>/var/tmp</filename>:</para>
+
+ <programlisting># /usr/lib/tmpfiles.d/tmp.conf
+d /var/tmp 1777 root root 30d
+</programlisting>
+
+ <programlisting># /usr/lib/tmpfiles.d/abrt.conf
+d /var/tmp/abrt 0755 abrt abrt -
+</programlisting>
+ </example>
- <programlisting>d /var/tmp/abrt 0755 abrt abrt
-x /var/tmp/abrt/*</programlisting>
+ <example>
+ <title>Apply clean up during boot and based on time</title>
+
+ <programlisting># /usr/lib/tmpfiles.d/dnf.conf
+r! /var/cache/dnf/*/*/download_lock.pid
+r! /var/cache/dnf/*/*/metadata_lock.pid
+r! /var/lib/dnf/rpmdb_lock.pid
+e /var/chache/dnf/ - - - 30d
+</programlisting>
+
+ <para>The lock files will be removed during boot. Any files and directories in
+ <filename>/var/chache/dnf/</filename> will be removed after they have not been
+ accessed in 30 days.</para>
</example>
</refsect1>
diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c
index 0a9d2bbdef..9521b79daa 100644
--- a/src/basic/terminal-util.c
+++ b/src/basic/terminal-util.c
@@ -1135,14 +1135,19 @@ int open_terminal_in_namespace(pid_t pid, const char *name, int mode) {
}
bool colors_enabled(void) {
- const char *colors;
+ static int enabled = -1;
- colors = getenv("SYSTEMD_COLORS");
- if (!colors) {
- if (streq_ptr(getenv("TERM"), "dumb"))
- return false;
- return on_tty();
+ if (_unlikely_(enabled < 0)) {
+ const char *colors;
+
+ colors = getenv("SYSTEMD_COLORS");
+ if (colors)
+ enabled = parse_boolean(colors) != 0;
+ else if (streq_ptr(getenv("TERM"), "dumb"))
+ enabled = false;
+ else
+ enabled = on_tty();
}
- return parse_boolean(colors) != 0;
+ return enabled;
}
diff --git a/src/core/main.c b/src/core/main.c
index 2912608435..8dfb3928de 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1338,7 +1338,7 @@ int main(int argc, char *argv[]) {
saved_argv = argv;
saved_argc = argc;
- log_show_color(isatty(STDERR_FILENO) > 0);
+ log_show_color(colors_enabled());
log_set_upgrade_syslog_to_journal(true);
/* Disable the umask logic */
diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c
index 35177aa29e..c370ed57ec 100644
--- a/src/machine/machinectl.c
+++ b/src/machine/machinectl.c
@@ -2402,7 +2402,7 @@ static int help(int argc, char *argv[], void *userdata) {
" --kill-who=WHO Who to send signal to\n"
" -s --signal=SIGNAL Which signal to send\n"
" --uid=USER Specify user ID to invoke shell as\n"
- " --setenv=VAR=VALUE Add an environment variable for shell\n"
+ " -E --setenv=VAR=VALUE Add an environment variable for shell\n"
" --read-only Create read-only bind mount\n"
" --mkdir Create directory before bind mounting, if missing\n"
" -n --lines=INTEGER Number of journal entries to show\n"
@@ -2470,7 +2470,6 @@ static int parse_argv(int argc, char *argv[]) {
ARG_FORCE,
ARG_FORMAT,
ARG_UID,
- ARG_SETENV,
};
static const struct option options[] = {
@@ -2496,7 +2495,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "force", no_argument, NULL, ARG_FORCE },
{ "format", required_argument, NULL, ARG_FORMAT },
{ "uid", required_argument, NULL, ARG_UID },
- { "setenv", required_argument, NULL, ARG_SETENV },
+ { "setenv", required_argument, NULL, 'E' },
{}
};
@@ -2624,7 +2623,7 @@ static int parse_argv(int argc, char *argv[]) {
arg_uid = optarg;
break;
- case ARG_SETENV:
+ case 'E':
if (!env_assignment_is_valid(optarg)) {
log_error("Environment assignment invalid: %s", optarg);
return -EINVAL;
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 8c1672ba0c..a07f148ef6 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -250,7 +250,7 @@ static void help(void) {
" the container\n"
" --overlay-ro=PATH[:PATH...]:PATH\n"
" Similar, but creates a read-only overlay mount\n"
- " --setenv=NAME=VALUE Pass an environment variable to PID 1\n"
+ " -E --setenv=NAME=VALUE Pass an environment variable to PID 1\n"
" --share-system Share system namespaces with host\n"
" --register=BOOLEAN Register container as machine\n"
" --keep-unit Do not register a scope for the machine, reuse\n"
@@ -333,7 +333,6 @@ static int parse_argv(int argc, char *argv[]) {
ARG_TMPFS,
ARG_OVERLAY,
ARG_OVERLAY_RO,
- ARG_SETENV,
ARG_SHARE_SYSTEM,
ARG_REGISTER,
ARG_KEEP_UNIT,
@@ -374,7 +373,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "overlay-ro", required_argument, NULL, ARG_OVERLAY_RO },
{ "machine", required_argument, NULL, 'M' },
{ "slice", required_argument, NULL, 'S' },
- { "setenv", required_argument, NULL, ARG_SETENV },
+ { "setenv", required_argument, NULL, 'E' },
{ "selinux-context", required_argument, NULL, 'Z' },
{ "selinux-apifs-context", required_argument, NULL, 'L' },
{ "quiet", no_argument, NULL, 'q' },
@@ -711,7 +710,7 @@ static int parse_argv(int argc, char *argv[]) {
break;
}
- case ARG_SETENV: {
+ case 'E': {
char **n;
if (!env_assignment_is_valid(optarg)) {
diff --git a/src/run/run.c b/src/run/run.c
index c0aa2c5924..1993a424ca 100644
--- a/src/run/run.c
+++ b/src/run/run.c
@@ -103,7 +103,7 @@ static void help(void) {
" --uid=USER Run as system user\n"
" --gid=GROUP Run as system group\n"
" --nice=NICE Nice level\n"
- " --setenv=NAME=VALUE Set environment\n"
+ " -E --setenv=NAME=VALUE Set environment\n"
" -t --pty Run service on pseudo tty\n"
" -q --quiet Suppress information messages during runtime\n\n"
"Timer options:\n\n"
@@ -136,7 +136,6 @@ static int parse_argv(int argc, char *argv[]) {
ARG_EXEC_USER,
ARG_EXEC_GROUP,
ARG_NICE,
- ARG_SETENV,
ARG_ON_ACTIVE,
ARG_ON_BOOT,
ARG_ON_STARTUP,
@@ -165,7 +164,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "uid", required_argument, NULL, ARG_EXEC_USER },
{ "gid", required_argument, NULL, ARG_EXEC_GROUP },
{ "nice", required_argument, NULL, ARG_NICE },
- { "setenv", required_argument, NULL, ARG_SETENV },
+ { "setenv", required_argument, NULL, 'E' },
{ "property", required_argument, NULL, 'p' },
{ "tty", no_argument, NULL, 't' }, /* deprecated */
{ "pty", no_argument, NULL, 't' },
@@ -266,7 +265,7 @@ static int parse_argv(int argc, char *argv[]) {
arg_nice_set = true;
break;
- case ARG_SETENV:
+ case 'E':
if (strv_extend(&arg_environment, optarg) < 0)
return log_oom();
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index efd264b34d..2053d35a67 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -94,6 +94,7 @@ typedef enum ItemType {
/* These ones take globs */
WRITE_FILE = 'w',
+ EMPTY_DIRECTORY = 'e',
SET_XATTR = 't',
RECURSIVE_SET_XATTR = 'T',
SET_ACL = 'a',
@@ -179,6 +180,7 @@ static bool needs_glob(ItemType t) {
IGNORE_DIRECTORY_PATH,
REMOVE_PATH,
RECURSIVE_REMOVE_PATH,
+ EMPTY_DIRECTORY,
ADJUST_MODE,
RELABEL_PATH,
RECURSIVE_RELABEL_PATH,
@@ -195,6 +197,7 @@ static bool takes_ownership(ItemType t) {
CREATE_FILE,
TRUNCATE_FILE,
CREATE_DIRECTORY,
+ EMPTY_DIRECTORY,
TRUNCATE_DIRECTORY,
CREATE_SUBVOLUME,
CREATE_SUBVOLUME_INHERIT_QUOTA,
@@ -1217,7 +1220,6 @@ static int create_item(Item *i) {
case CREATE_SUBVOLUME:
case CREATE_SUBVOLUME_INHERIT_QUOTA:
case CREATE_SUBVOLUME_NEW_QUOTA:
-
RUN_WITH_UMASK(0000)
mkdir_parents_label(i->path, 0755);
@@ -1276,11 +1278,11 @@ static int create_item(Item *i) {
if (IN_SET(i->type, CREATE_SUBVOLUME_NEW_QUOTA, CREATE_SUBVOLUME_INHERIT_QUOTA)) {
r = btrfs_subvol_auto_qgroup(i->path, 0, i->type == CREATE_SUBVOLUME_NEW_QUOTA);
if (r == -ENOTTY)
- log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" because of unsupported file system or because directory is not a subvolume: %m", i->path);
+ log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" (unsupported fs or dir not a subvolume): %m", i->path);
else if (r == -EROFS)
- log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" because of read-only file system: %m", i->path);
+ log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" (fs is read-only).", i->path);
else if (r == -ENOPROTOOPT)
- log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" because quota support is disabled: %m", i->path);
+ log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" (quota support is disabled).", i->path);
else if (r < 0)
q = log_error_errno(r, "Failed to adjust quota for subvolume \"%s\": %m", i->path);
else if (r > 0)
@@ -1289,6 +1291,9 @@ static int create_item(Item *i) {
log_debug("Quota for subvolume \"%s\" already in place, no change made.", i->path);
}
+ /* fall through */
+
+ case EMPTY_DIRECTORY:
r = path_set_perms(i, i->path);
if (q < 0)
return q;
@@ -1298,7 +1303,6 @@ static int create_item(Item *i) {
break;
case CREATE_FIFO:
-
RUN_WITH_UMASK(0000) {
mac_selinux_create_file_prepare(i->path, S_IFIFO);
r = mkfifo(i->path, i->mode);
@@ -1535,47 +1539,20 @@ static int remove_item_instance(Item *i, const char *instance) {
}
static int remove_item(Item *i) {
- int r = 0;
-
assert(i);
log_debug("Running remove action for entry %c %s", (char) i->type, i->path);
switch (i->type) {
- case CREATE_FILE:
- case TRUNCATE_FILE:
- case CREATE_DIRECTORY:
- case CREATE_SUBVOLUME:
- case CREATE_SUBVOLUME_INHERIT_QUOTA:
- case CREATE_SUBVOLUME_NEW_QUOTA:
- case CREATE_FIFO:
- case CREATE_SYMLINK:
- case CREATE_CHAR_DEVICE:
- case CREATE_BLOCK_DEVICE:
- case IGNORE_PATH:
- case IGNORE_DIRECTORY_PATH:
- case ADJUST_MODE:
- case RELABEL_PATH:
- case RECURSIVE_RELABEL_PATH:
- case WRITE_FILE:
- case COPY_FILES:
- case SET_XATTR:
- case RECURSIVE_SET_XATTR:
- case SET_ACL:
- case RECURSIVE_SET_ACL:
- case SET_ATTRIBUTE:
- case RECURSIVE_SET_ATTRIBUTE:
- break;
-
case REMOVE_PATH:
case TRUNCATE_DIRECTORY:
case RECURSIVE_REMOVE_PATH:
- r = glob_item(i, remove_item_instance, false);
- break;
- }
+ return glob_item(i, remove_item_instance, false);
- return r;
+ default:
+ return 0;
+ }
}
static int clean_item_instance(Item *i, const char* instance) {
@@ -1630,8 +1607,6 @@ static int clean_item_instance(Item *i, const char* instance) {
}
static int clean_item(Item *i) {
- int r = 0;
-
assert(i);
log_debug("Running clean action for entry %c %s", (char) i->type, i->path);
@@ -1641,19 +1616,17 @@ static int clean_item(Item *i) {
case CREATE_SUBVOLUME:
case CREATE_SUBVOLUME_INHERIT_QUOTA:
case CREATE_SUBVOLUME_NEW_QUOTA:
+ case EMPTY_DIRECTORY:
case TRUNCATE_DIRECTORY:
case IGNORE_PATH:
case COPY_FILES:
clean_item_instance(i, i->path);
- break;
+ return 0;
case IGNORE_DIRECTORY_PATH:
- r = glob_item(i, clean_item_instance, false);
- break;
+ return glob_item(i, clean_item_instance, false);
default:
- break;
+ return 0;
}
-
- return r;
}
static int process_item_array(ItemArray *array);
@@ -1879,6 +1852,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
case CREATE_SUBVOLUME:
case CREATE_SUBVOLUME_INHERIT_QUOTA:
case CREATE_SUBVOLUME_NEW_QUOTA:
+ case EMPTY_DIRECTORY:
case TRUNCATE_DIRECTORY:
case CREATE_FIFO:
case IGNORE_PATH:
@@ -2198,7 +2172,8 @@ static int parse_argv(int argc, char *argv[]) {
}
static int read_config_file(const char *fn, bool ignore_enoent) {
- _cleanup_fclose_ FILE *f = NULL;
+ _cleanup_fclose_ FILE *_f = NULL;
+ FILE *f;
char line[LINE_MAX];
Iterator iterator;
unsigned v = 0;
@@ -2207,16 +2182,23 @@ static int read_config_file(const char *fn, bool ignore_enoent) {
assert(fn);
- r = search_and_fopen_nulstr(fn, "re", arg_root, conf_file_dirs, &f);
- if (r < 0) {
- if (ignore_enoent && r == -ENOENT) {
- log_debug_errno(r, "Failed to open \"%s\": %m", fn);
- return 0;
- }
+ if (streq(fn, "-")) {
+ log_debug("Reading config from stdin.");
+ fn = "<stdin>";
+ f = stdin;
+ } else {
+ r = search_and_fopen_nulstr(fn, "re", arg_root, conf_file_dirs, &_f);
+ if (r < 0) {
+ if (ignore_enoent && r == -ENOENT) {
+ log_debug_errno(r, "Failed to open \"%s\", ignoring: %m", fn);
+ return 0;
+ }
- return log_error_errno(r, "Failed to open '%s', ignoring: %m", fn);
+ return log_error_errno(r, "Failed to open '%s': %m", fn);
+ }
+ log_debug("Reading config file \"%s\".", fn);
+ f = _f;
}
- log_debug("Reading config file \"%s\".", fn);
FOREACH_LINE(line, f, break) {
char *l;