diff options
-rw-r--r-- | man/machinectl.xml | 18 | ||||
-rw-r--r-- | man/systemd-nspawn.xml | 3 | ||||
-rw-r--r-- | man/systemd-run.xml | 8 | ||||
-rw-r--r-- | man/systemd-tmpfiles.xml | 10 | ||||
-rw-r--r-- | man/tmpfiles.d.xml | 81 | ||||
-rw-r--r-- | src/basic/terminal-util.c | 19 | ||||
-rw-r--r-- | src/core/main.c | 2 | ||||
-rw-r--r-- | src/machine/machinectl.c | 7 | ||||
-rw-r--r-- | src/nspawn/nspawn.c | 7 | ||||
-rw-r--r-- | src/run/run.c | 7 | ||||
-rw-r--r-- | src/tmpfiles/tmpfiles.c | 88 |
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; |