Merge pull request #3955 from keszybz/fix-preset-all

Fix preset-all
This commit is contained in:
Lennart Poettering 2016-08-19 19:10:30 +02:00 committed by GitHub
commit a457bd26cc
15 changed files with 125 additions and 62 deletions

View File

@ -575,7 +575,16 @@ dist_userunit_DATA = \
units/user/default.target \
units/user/exit.target \
units/user/graphical-session.target \
units/user/graphical-session-pre.target
units/user/graphical-session-pre.target \
units/user/bluetooth.target \
units/user/busnames.target \
units/user/paths.target \
units/user/printer.target \
units/user/shutdown.target \
units/user/smartcard.target \
units/user/sockets.target \
units/user/sound.target \
units/user/timers.target
nodist_userunit_DATA = \
units/user/systemd-exit.service
@ -634,6 +643,10 @@ EXTRA_DIST += \
units/rc-local.service.in \
units/halt-local.service.in
GENERAL_ALIASES += \
$(systemunitdir)/reboot.target $(pkgsysconfdir)/system/ctrl-alt-del.target \
$(systemunitdir)/machines.target $(pkgsysconfdir)/system/multi-user.target.wants/machines.target
# automake is broken and can't handle files with a dash in front
# http://debbugs.gnu.org/cgi/bugreport.cgi?bug=14728#8
units-install-hook:
@ -6292,19 +6305,6 @@ SYSTEM_UNIT_ALIASES += \
reboot.target ctrl-alt-del.target \
getty@.service autovt@.service
USER_UNIT_ALIASES += \
$(systemunitdir)/shutdown.target shutdown.target \
$(systemunitdir)/sockets.target sockets.target \
$(systemunitdir)/timers.target timers.target \
$(systemunitdir)/paths.target paths.target \
$(systemunitdir)/bluetooth.target bluetooth.target \
$(systemunitdir)/printer.target printer.target \
$(systemunitdir)/sound.target sound.target \
$(systemunitdir)/smartcard.target smartcard.target
USER_UNIT_ALIASES += \
$(systemunitdir)/busnames.target busnames.target
GENERAL_ALIASES += \
$(systemunitdir)/remote-fs.target $(pkgsysconfdir)/system/multi-user.target.wants/remote-fs.target \
$(systemunitdir)/getty@.service $(pkgsysconfdir)/system/getty.target.wants/getty@tty1.service \

View File

@ -1092,7 +1092,8 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
enabled and disabled, or only enabled, or only disabled.</para>
<para>If the unit carries no install information, it will be silently ignored
by this command.</para>
by this command. <replaceable>NAME</replaceable> must be the real unit name,
any alias names are ignored silently.</para>
<para>For more information on the preset policy format, see
<citerefentry><refentrytitle>systemd.preset</refentrytitle><manvolnum>5</manvolnum></citerefentry>.

View File

@ -98,6 +98,10 @@
Empty lines and lines whose first non-whitespace character is # or
; are ignored.</para>
<para>Presets must refer to the "real" unit file, and not to any aliases. See
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for a description of unit aliasing.</para>
<para>Two different directives are understood:
<literal>enable</literal> may be used to enable units by default,
<literal>disable</literal> to disable units by default.</para>

View File

@ -144,21 +144,31 @@
<option>false</option> and <option>off</option> are
equivalent.</para>
<para>Time span values encoded in unit files can be written in
various formats. A stand-alone number specifies a time in seconds.
If suffixed with a time unit, the unit is honored. A concatenation
of multiple values with units is supported, in which case the
values are added up. Example: "50" refers to 50 seconds; "2min
200ms" refers to 2 minutes plus 200 milliseconds, i.e. 120200ms.
The following time units are understood: s, min, h, d, w, ms, us.
For details see
<para>Time span values encoded in unit files can be written in various formats. A stand-alone number specifies a
time in seconds. If suffixed with a time unit, the unit is honored. A concatenation of multiple values with units
is supported, in which case the values are added up. Example: <literal>50</literal> refers to 50 seconds;
<literal>2min 200ms</literal> refers to 2 minutes and 200 milliseconds, i.e. 120200 ms. The following time units
are understood: <literal>s</literal>, <literal>min</literal>, <literal>h</literal>, <literal>d</literal>,
<literal>w</literal>, <literal>ms</literal>, <literal>us</literal>. For details see
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
<para>Empty lines and lines starting with # or ; are
ignored. This may be used for commenting. Lines ending
in a backslash are concatenated with the following
line while reading and the backslash is replaced by a
space character. This may be used to wrap long lines.</para>
<para>Empty lines and lines starting with <literal>#</literal> or <literal>;</literal> are ignored. This may be
used for commenting. Lines ending in a backslash are concatenated with the following line while reading and the
backslash is replaced by a space character. This may be used to wrap long lines.</para>
<para>Units can be aliased (have an alternative name), by creating a symlink from the new name to the existing name
in one of the unit search paths. For example, <filename>systemd-networkd.service</filename> has the alias
<filename>dbus-org.freedesktop.network1.service</filename>, created during installation as the symlink
<filename>/usr/lib/systemd/system/dbus-org.freedesktop.network1.service</filename>. In addition, unit files may
specify aliases through the <varname>Alias=</varname> directive in the [Install] section; those aliases are only
effective when the unit is enabled. When the unit is enabled, symlinks will be created for those names, and removed
when the unit is disabled. For example, <filename>reboot.target</filename> specifies
<varname>Alias=ctrl-alt-del.target</varname>, so when enabled it will be invoked whenever CTRL+ALT+DEL is
pressed. Alias names may be used in commands like <command>enable</command>, <command>disable</command>,
<command>start</command>, <command>stop</command>, <command>status</command>, …, and in unit dependency directives
<varname>Wants=</varname>, <varname>Requires=</varname>, <varname>Before=</varname>, <varname>After=</varname>, …,
with the limitation that aliases specified through <varname>Alias=</varname> are only effective when the unit is
enabled. Aliases cannot be used with the <command>preset</command> command.</para>
<para>Along with a unit file <filename>foo.service</filename>, the
directory <filename>foo.service.wants/</filename> may exist. All

View File

@ -393,19 +393,40 @@ void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *chang
log_error_errno(r, "Failed to %s: %m.", verb);
}
/**
* Checks if two paths or symlinks from wd are the same, when root is the root of the filesystem.
* wc should be the full path in the host file system.
*/
static bool chroot_symlinks_same(const char *root, const char *wd, const char *a, const char *b) {
assert(path_is_absolute(wd));
/* This will give incorrect results if the paths are relative and go outside
* of the chroot. False negatives are possible. */
a = strjoina(path_is_absolute(a) ? root : wd, "/", a);
b = strjoina(path_is_absolute(b) ? root : wd, "/", b);
return path_equal_or_files_same(a, b);
}
static int create_symlink(
const LookupPaths *paths,
const char *old_path,
const char *new_path,
bool force,
UnitFileChange **changes,
unsigned *n_changes) {
_cleanup_free_ char *dest = NULL;
_cleanup_free_ char *dest = NULL, *dirname = NULL;
const char *rp;
int r;
assert(old_path);
assert(new_path);
rp = skip_root(paths, old_path);
if (rp)
old_path = rp;
/* Actually create a symlink, and remember that we did. Is
* smart enough to check if there's already a valid symlink in
* place.
@ -436,7 +457,11 @@ static int create_symlink(
return r;
}
if (path_equal(dest, old_path))
dirname = dirname_malloc(new_path);
if (!dirname)
return -ENOMEM;
if (chroot_symlinks_same(paths->root_dir, dirname, dest, old_path))
return 1;
if (!force) {
@ -620,7 +645,7 @@ static int remove_marked_symlinks(
fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
if (fd < 0)
return -errno;
return errno == ENOENT ? 0 : -errno;
do {
int q, cfd;
@ -903,6 +928,10 @@ static int install_info_may_process(
return 0;
}
/**
* Adds a new UnitFileInstallInfo entry under name in the InstallContext.will_process
* hashmap, or retrieves the existing one if already present.
*/
static int install_info_add(
InstallContext *c,
const char *name,
@ -1334,9 +1363,8 @@ static int install_info_follow(
}
/**
* Search for the unit file. If the unit name is a symlink,
* follow the symlink to the target, maybe more than once.
* Propagate the instance name if present.
* Search for the unit file. If the unit name is a symlink, follow the symlink to the
* target, maybe more than once. Propagate the instance name if present.
*/
static int install_info_traverse(
UnitFileScope scope,
@ -1421,6 +1449,10 @@ static int install_info_traverse(
return 0;
}
/**
* Call install_info_add() with name_or_path as the path (if name_or_path starts with "/")
* or the name (otherwise). root_dir is prepended to the path.
*/
static int install_info_add_auto(
InstallContext *c,
const LookupPaths *paths,
@ -1479,7 +1511,6 @@ static int install_info_symlink_alias(
STRV_FOREACH(s, i->aliases) {
_cleanup_free_ char *alias_path = NULL, *dst = NULL;
const char *rp;
q = install_full_printf(i, *s, &dst);
if (q < 0)
@ -1489,9 +1520,7 @@ static int install_info_symlink_alias(
if (!alias_path)
return -ENOMEM;
rp = skip_root(paths, i->path);
q = create_symlink(rp ?: i->path, alias_path, force, changes, n_changes);
q = create_symlink(paths, i->path, alias_path, force, changes, n_changes);
if (r == 0)
r = q;
}
@ -1535,7 +1564,6 @@ static int install_info_symlink_wants(
STRV_FOREACH(s, list) {
_cleanup_free_ char *path = NULL, *dst = NULL;
const char *rp;
q = install_full_printf(i, *s, &dst);
if (q < 0)
@ -1550,9 +1578,7 @@ static int install_info_symlink_wants(
if (!path)
return -ENOMEM;
rp = skip_root(paths, i->path);
q = create_symlink(rp ?: i->path, path, true, changes, n_changes);
q = create_symlink(paths, i->path, path, true, changes, n_changes);
if (r == 0)
r = q;
}
@ -1569,7 +1595,6 @@ static int install_info_symlink_link(
unsigned *n_changes) {
_cleanup_free_ char *path = NULL;
const char *rp;
int r;
assert(i);
@ -1587,9 +1612,7 @@ static int install_info_symlink_link(
if (!path)
return -ENOMEM;
rp = skip_root(paths, i->path);
return create_symlink(rp ?: i->path, path, force, changes, n_changes);
return create_symlink(paths, i->path, path, force, changes, n_changes);
}
static int install_info_apply(
@ -1663,6 +1686,17 @@ static int install_context_apply(
if (r < 0)
return r;
/* We can attempt to process a masked unit when a different unit
* that we were processing specifies it in DefaultInstance= or Also=. */
if (i->type == UNIT_FILE_TYPE_MASKED) {
unit_file_changes_add(changes, n_changes, UNIT_FILE_IS_MASKED, i->path, NULL);
if (r >= 0)
/* Assume that some *could* have been enabled here, avoid
* "empty [Install] section" warning. */
r += 1;
continue;
}
if (i->type != UNIT_FILE_TYPE_REGULAR)
continue;
@ -1765,7 +1799,7 @@ int unit_file_mask(
if (!path)
return -ENOMEM;
q = create_symlink("/dev/null", path, force, changes, n_changes);
q = create_symlink(&paths, "/dev/null", path, force, changes, n_changes);
if (q < 0 && r >= 0)
r = q;
}
@ -1925,14 +1959,12 @@ int unit_file_link(
r = 0;
STRV_FOREACH(i, todo) {
_cleanup_free_ char *new_path = NULL;
const char *old_path;
old_path = skip_root(&paths, *i);
new_path = path_make_absolute(basename(*i), config_path);
if (!new_path)
return -ENOMEM;
q = create_symlink(old_path ?: *i, new_path, force, changes, n_changes);
q = create_symlink(&paths, *i, new_path, force, changes, n_changes);
if (q < 0 && r >= 0)
r = q;
}
@ -1967,7 +1999,6 @@ int unit_file_revert(
unsigned *n_changes) {
_cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
/* _cleanup_(install_context_done) InstallContext c = {}; */
_cleanup_lookup_paths_free_ LookupPaths paths = {};
_cleanup_strv_free_ char **todo = NULL;
size_t n_todo = 0, n_allocated = 0;
@ -2312,7 +2343,7 @@ int unit_file_set_default(
_cleanup_lookup_paths_free_ LookupPaths paths = {};
_cleanup_(install_context_done) InstallContext c = {};
UnitFileInstallInfo *i;
const char *new_path, *old_path;
const char *new_path;
int r;
assert(scope >= 0);
@ -2335,10 +2366,8 @@ int unit_file_set_default(
if (r < 0)
return r;
old_path = skip_root(&paths, i->path);
new_path = strjoina(paths.persistent_config, "/" SPECIAL_DEFAULT_TARGET);
return create_symlink(old_path ?: i->path, new_path, force, changes, n_changes);
return create_symlink(&paths, i->path, new_path, force, changes, n_changes);
}
int unit_file_get_default(
@ -2685,19 +2714,26 @@ static int preset_prepare_one(
InstallContext *plus,
InstallContext *minus,
LookupPaths *paths,
UnitFilePresetMode mode,
const char *name,
Presets presets,
UnitFileChange **changes,
unsigned *n_changes) {
_cleanup_(install_context_done) InstallContext tmp = {};
UnitFileInstallInfo *i;
int r;
if (install_info_find(plus, name) ||
install_info_find(minus, name))
if (install_info_find(plus, name) || install_info_find(minus, name))
return 0;
r = install_info_discover(scope, &tmp, paths, name, SEARCH_FOLLOW_CONFIG_SYMLINKS, &i);
if (r < 0)
return r;
if (!streq(name, i->name)) {
log_debug("Skipping %s because is an alias for %s", name, i->name);
return 0;
}
r = query_presets(name, presets);
if (r < 0)
return r;
@ -2748,7 +2784,7 @@ int unit_file_preset(
return r;
STRV_FOREACH(i, files) {
r = preset_prepare_one(scope, &plus, &minus, &paths, mode, *i, presets, changes, n_changes);
r = preset_prepare_one(scope, &plus, &minus, &paths, *i, presets, changes, n_changes);
if (r < 0)
return r;
}
@ -2809,7 +2845,7 @@ int unit_file_preset_all(
continue;
/* we don't pass changes[] in, because we want to handle errors on our own */
r = preset_prepare_one(scope, &plus, &minus, &paths, mode, de->d_name, presets, NULL, 0);
r = preset_prepare_one(scope, &plus, &minus, &paths, de->d_name, presets, NULL, 0);
if (r == -ERFKILL)
r = unit_file_changes_add(changes, n_changes,
UNIT_FILE_IS_MASKED, de->d_name, NULL);

View File

@ -15,6 +15,7 @@ enable getty@.service
enable systemd-timesyncd.service
enable systemd-networkd.service
enable systemd-resolved.service
enable systemd-networkd-wait-online.service
disable console-getty.service
disable console-shell.service
@ -23,10 +24,12 @@ disable debug-shell.service
disable halt.target
disable kexec.target
disable poweroff.target
disable reboot.target
enable reboot.target
disable rescue.target
disable exit.target
disable syslog.socket
disable systemd-journal-gatewayd.*
disable systemd-networkd-wait-online.service
disable systemd-journal-remote.*
disable systemd-journal-upload.*

1
units/user/bluetooth.target Symbolic link
View File

@ -0,0 +1 @@
../bluetooth.target

1
units/user/busnames.target Symbolic link
View File

@ -0,0 +1 @@
../busnames.target

1
units/user/paths.target Symbolic link
View File

@ -0,0 +1 @@
../paths.target

1
units/user/printer.target Symbolic link
View File

@ -0,0 +1 @@
../printer.target

1
units/user/shutdown.target Symbolic link
View File

@ -0,0 +1 @@
../shutdown.target

1
units/user/smartcard.target Symbolic link
View File

@ -0,0 +1 @@
../smartcard.target

1
units/user/sockets.target Symbolic link
View File

@ -0,0 +1 @@
../sockets.target

1
units/user/sound.target Symbolic link
View File

@ -0,0 +1 @@
../sound.target

1
units/user/timers.target Symbolic link
View File

@ -0,0 +1 @@
../timers.target