unblock: systemd/215-12

Martin Pitt mpitt at debian.org
Mon Feb 16 16:16:32 GMT 2015


Package: release.debian.org
Severity: normal
User: release.debian.org at packages.debian.org
Usertags: unblock

systemd 215-12 hit unstable three days ago with some RC/important/safe
So far there have been no regression reports. At the time of this
writing there are now no RC bugs left \o/

I attach the full debdiff between 215-11 and -12, but as usual I also
link to the individual commits on anonscm. Unfortunately the latter
are a bit noisy, as the implementation of the fixes was discussed
several times and changed a bit.

Note that there are zero changes for udev and hence the udebs (for
d-i).

Annotated changelog:

| systemd (215-12) unstable; urgency=medium
| 
|   [ Martin Pitt ]
|   * debian/udev.README.Debian: Trim the parts which are obsolete, wrong, or
|     described in manpages. Only keep the Debian specific bits.
|     (Part of #776546)

  http://anonscm.debian.org/cgit/pkg-systemd/systemd.git/commit/?id=a76b454

|   * Actually install udev's README.Debian when building for Debian.
|     (Closes: #776546)

  http://anonscm.debian.org/cgit/pkg-systemd/systemd.git/commit/?id=d26405c8

Documentation cleanup. Note that this was requested/pre-approved by Niels.

|   * Only start logind if dbus is installed. This fixes the noisy startup
|     failure in environments without dbus such as LXC containers or servers.
|     (part of #772700)

  http://anonscm.debian.org/cgit/pkg-systemd/systemd.git/commit/?id=a7d7679
  http://anonscm.debian.org/cgit/pkg-systemd/systemd.git/commit/?id=0d601f8
    (update/cleanup)

|   * Add getty-static.service unit which starts getty at .service on tty 2 to 6 if
|     dbus is not installed, and hence logind cannot auto-start them on demand.
|     (Closes: #772700)

  http://anonscm.debian.org/cgit/pkg-systemd/systemd.git/commit/?id=c4b5782f0
  http://anonscm.debian.org/cgit/pkg-systemd/systemd.git/commit/?id=965ef72
    (cleanup of the previous two commits)

RC bug (with 3 duplicates). This restores VT functionality on systems
without dbus (i. e. mainly servers) as it is under sysvinit, and
quiesces logind failures there.

|   * Add unit-config autopkgtest to check systemd unit/sysv init enabling and
|     disabling via systemctl. This avoids bugs like #777613 (did not affect
|     unstable).

  http://anonscm.debian.org/cgit/pkg-systemd/systemd.git/commit/?id=ec551e56

I used this to verify that 215 was not affected. I'd like to keep this
in master, just to have it available for post-release bug
fixes/verification.

|   * cgroup: Don't trim cgroup trees created by someone else, just the ones
|     that systemd itself created. This avoids cleaning up empty cgroups from
|     e.g. LXC. (Closes: #777601)

  http://anonscm.debian.org/cgit/pkg-systemd/systemd.git/commit/?id=255ae60
  http://anonscm.debian.org/cgit/pkg-systemd/systemd.git/commit/?id=59d9202
    (followup fix due to git pilot error on my side, sorry)

RC bug. This looks fairly intrusive (not at all in patch size, that's
just a two-liner; but in effect), but as long as there is more than
just systemd writing to /sys/fs/cgroups this errs on the safe side:
now systemd will never cleanup empty cgroups that it didn't create by
itself (realized_mask); before it cleaned up all controllers which
are supported by the kernel (cgroup_supported).

|   * boot-and-services autopkgtest: Add CgroupsTest to check cgroup
|     creation/cleanup behaviour. This reproduces #777601 and verifies the fix
|     for it.

  http://anonscm.debian.org/cgit/pkg-systemd/systemd.git/commit/?id=f1a42bae

tests == ♥  :-)

|   * rules: Fix by-path of mmc RPMB partitions and don't blkid them. Avoids
|     kernel buffer I/O errors and timeouts. (LP: #1333140)

  http://anonscm.debian.org/cgit/pkg-systemd/systemd.git/commit/?id=21c55fb

This is https://launchpad.net/bugs/1333140 . Not quite RC, but a
trivial patch which just blacklists mmcblk*-rpmb devices from getting
touched by udev rules; they are rather mimosic and can't really opened
or detected with blkid and other tools.

|   * Document systemctl --failed option. (Closes: #767267)

  http://anonscm.debian.org/cgit/pkg-systemd/systemd.git/commit/?id=8b3d324

Documentation (manpage) only, and an useful option.

|   [ Michael Biebl ]
|   * core: Don't fail to run services in --user instances if $HOME is missing.
|     (Closes: #759320)

  http://anonscm.debian.org/cgit/pkg-systemd/systemd.git/commit/?id=e0b3ce3b

Not release critical, but causes annoyingly long delays during
shutdown, and quite a simple fix.

|   [ Didier Roche ]
|   * default-display-manager-generator: Avoid unnecessary /dev/null symlink and
|     warning if there is no display-manager.service unit.

  http://anonscm.debian.org/cgit/pkg-systemd/systemd.git/commit/?id=496110f3a

This fixes a corner case to avoid a useless warning, and this is a
simple patch. This whole logic is tested by
debian/tests/display-managers which which covers all scenarios we ran
into so far, and it's still passing fine.

Thanks for considering! Please let me know if you have any doubt or
questions.

While you are at it, would you mind having a look at #755722? I'd be
interested in your opinion whether for jessie we should (1) ignore the
problem, (2) apply the sysv behaviour compatible hwclock.service, or
(3) boldly go and enable timesyncd.

Thanks,

Martin

unblock systemd/215-12

-- 
Martin Pitt                        | http://www.piware.de
Ubuntu Developer (www.ubuntu.com)  | Debian Developer  (www.debian.org)
-------------- next part --------------
diff --git a/debian/changelog b/debian/changelog
index 5239419..6d81277 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,7 +1,44 @@
+systemd (215-12) unstable; urgency=medium
+
+  [ Martin Pitt ]
+  * debian/udev.README.Debian: Trim the parts which are obsolete, wrong, or
+    described in manpages. Only keep the Debian specific bits.
+    (Part of #776546)
+  * Actually install udev's README.Debian when building for Debian.
+    (Closes: #776546)
+  * Only start logind if dbus is installed. This fixes the noisy startup
+    failure in environments without dbus such as LXC containers or servers.
+    (part of #772700)
+  * Add getty-static.service unit which starts getty at .service on tty 2 to 6 if
+    dbus is not installed, and hence logind cannot auto-start them on demand.
+    (Closes: #772700)
+  * Add unit-config autopkgtest to check systemd unit/sysv init enabling and
+    disabling via systemctl. This avoids bugs like #777613 (did not affect
+    unstable).
+  * cgroup: Don't trim cgroup trees created by someone else, just the ones
+    that systemd itself created. This avoids cleaning up empty cgroups from
+    e.g. LXC. (Closes: #777601)
+  * boot-and-services autopkgtest: Add CgroupsTest to check cgroup
+    creation/cleanup behaviour. This reproduces #777601 and verifies the fix
+    for it.
+  * rules: Fix by-path of mmc RPMB partitions and don't blkid them. Avoids
+    kernel buffer I/O errors and timeouts. (LP: #1333140)
+  * Document systemctl --failed option. (Closes: #767267)
+
+  [ Michael Biebl ]
+  * core: Don't fail to run services in --user instances if $HOME is missing.
+    (Closes: #759320)
+
+  [ Didier Roche ]
+  * default-display-manager-generator: Avoid unnecessary /dev/null symlink and
+    warning if there is no display-manager.service unit.
+
+ -- Martin Pitt <mpitt at debian.org>  Fri, 13 Feb 2015 12:08:31 +0100
+
 systemd (215-11) unstable; urgency=medium
 
   [ Martin Pitt ]
-  * escape-beef-up-new-systemd-escape-tool.patch: Avoid creating a danling
+  * escape-beef-up-new-systemd-escape-tool.patch: Avoid creating a dangling
     symlink, to work around regression in recent patch (see #776257).
   * Order ifup at .service and networking.service after network-pre.target.
     (Closes: #766938)
diff --git a/debian/extra/getty-static.service b/debian/extra/getty-static.service
new file mode 100644
index 0000000..8636be5
--- /dev/null
+++ b/debian/extra/getty-static.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=getty on tty2-tty6 if dbus and logind are not available
+ConditionPathExists=/dev/tty2
+ConditionPathExists=!/lib/systemd/system/dbus.service
+
+[Service]
+Type=oneshot
+ExecStart=/bin/systemctl --no-block start getty at tty2.service getty at tty3.service getty at tty4.service getty at tty5.service getty at tty6.service
+RemainAfterExit=true
+
diff --git a/debian/patches/Only-start-logind-if-dbus-is-installed.patch b/debian/patches/Only-start-logind-if-dbus-is-installed.patch
new file mode 100644
index 0000000..86a948f
--- /dev/null
+++ b/debian/patches/Only-start-logind-if-dbus-is-installed.patch
@@ -0,0 +1,24 @@
+From: Martin Pitt <martin.pitt at ubuntu.com>
+Date: Mon, 9 Feb 2015 10:53:43 +0100
+Subject: Only start logind if dbus is installed
+
+logind fails to start in environments without dbus, such as LXC containers or
+servers. Add a startup condition to avoid the very noisy startup failure.
+
+Part of #772700
+---
+ units/systemd-logind.service.in | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in
+index f087e99..07f65c4 100644
+--- a/units/systemd-logind.service.in
++++ b/units/systemd-logind.service.in
+@@ -12,6 +12,7 @@ Documentation=http://www.freedesktop.org/wiki/Software/systemd/logind
+ Documentation=http://www.freedesktop.org/wiki/Software/systemd/multiseat
+ Wants=user.slice
+ After=nss-user-lookup.target user.slice
++ConditionPathExists=/lib/systemd/system/dbus.service
+ 
+ # Ask for the dbus socket. If running over kdbus, the socket will
+ # not be actually used.
diff --git a/debian/patches/Prefer-etc-X11-default-display-manager-if-present.patch b/debian/patches/Prefer-etc-X11-default-display-manager-if-present.patch
index 13a660b..9eb5cbc 100644
--- a/debian/patches/Prefer-etc-X11-default-display-manager-if-present.patch
+++ b/debian/patches/Prefer-etc-X11-default-display-manager-if-present.patch
@@ -5,10 +5,10 @@ Subject: Prefer /etc/X11/default-display-manager if present
 Add a generator to ensure /etc/X11/default-display-manager is controlling
 which display-manager is started.
 ---
- Makefile.am                                        |  11 ++-
+ Makefile.am                                        |  11 +-
  src/default-display-manager-generator/Makefile     |  24 +++++
- .../default-display-manager-generator.c            | 103 +++++++++++++++++++++
- 3 files changed, 137 insertions(+), 1 deletion(-)
+ .../default-display-manager-generator.c            | 112 +++++++++++++++++++++
+ 3 files changed, 146 insertions(+), 1 deletion(-)
  create mode 100644 src/default-display-manager-generator/Makefile
  create mode 100644 src/default-display-manager-generator/default-display-manager-generator.c
 
@@ -73,10 +73,10 @@ index 0000000..3a4bbbe
 +.PHONY: all clean
 diff --git a/src/default-display-manager-generator/default-display-manager-generator.c b/src/default-display-manager-generator/default-display-manager-generator.c
 new file mode 100644
-index 0000000..930a67e
+index 0000000..3e476b5
 --- /dev/null
 +++ b/src/default-display-manager-generator/default-display-manager-generator.c
-@@ -0,0 +1,103 @@
+@@ -0,0 +1,112 @@
 +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 +
 +/***
@@ -99,6 +99,7 @@ index 0000000..930a67e
 +***/
 +
 +#include <errno.h>
++#include <stdbool.h>
 +#include <unistd.h>
 +
 +#include "fileio.h"
@@ -122,6 +123,7 @@ index 0000000..930a67e
 +
 +        _cleanup_free_ char *default_dm_path = NULL, *enabled_dm_unit = NULL;
 +        const char *default_dm = NULL, *in_mem_symlink = NULL, *target_unit_path = NULL;
++        bool dm_service_exists = true;
 +        int r;
 +
 +        r = read_full_file(default_dm_file, &default_dm_path, NULL);
@@ -132,8 +134,10 @@ index 0000000..930a67e
 +        default_dm = strstrip(basename(default_dm_path));
 +
 +        r = readlink_value(dm_service_unit, &enabled_dm_unit);
-+        if (r < 0)
++        if (r < 0) {
 +                enabled_dm_unit = strdup("");
++                dm_service_exists = false;
++        }
 +
 +        /* all is fine if the info matches */
 +        if (streq(strappenda(default_dm, ".service"), enabled_dm_unit))
@@ -143,6 +147,11 @@ index 0000000..930a67e
 +
 +        /* we only create the alias symlink for non sysvinit services */
 +        if (access(target_unit_path, F_OK) < 0 && (errno == ENOENT)) {
++                /* if the dm service was already disabled, nothing to be done */
++                if (!dm_service_exists) {
++                        log_debug("No %s file, nothing to mask", dm_service_unit);
++                        return 0;
++                }
 +                log_warning("%s is not a systemd unit, we disable the systemd enabled display manager", target_unit_path);
 +                target_unit_path = "/dev/null";
 +        } else {
diff --git a/debian/patches/cgroup-don-t-trim-cgroup-trees-created-by-someone-el.patch b/debian/patches/cgroup-don-t-trim-cgroup-trees-created-by-someone-el.patch
new file mode 100644
index 0000000..dbc90da
--- /dev/null
+++ b/debian/patches/cgroup-don-t-trim-cgroup-trees-created-by-someone-el.patch
@@ -0,0 +1,41 @@
+From: Michal Sekletar <msekleta at redhat.com>
+Date: Fri, 19 Sep 2014 17:14:10 +0200
+Subject: cgroup: don't trim cgroup trees created by someone else
+
+In cases when there is a cgroup tree in a controller hierarchy which was
+not created by us, but it looks like it was (i.e. cgroup path is the
+same as the one in systemd's named hierarchy) we shouldn't delete it.
+
+Origin: http://lists.freedesktop.org/archives/systemd-devel/2014-September/023276.html
+Bug-Debian: https://bugs.debian.org/777601
+---
+ src/core/cgroup.c        | 2 +-
+ src/shared/cgroup-util.c | 2 --
+ 2 files changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/src/core/cgroup.c b/src/core/cgroup.c
+index cd67963..91f2550 100644
+--- a/src/core/cgroup.c
++++ b/src/core/cgroup.c
+@@ -780,7 +780,7 @@ void unit_destroy_cgroup(Unit *u) {
+         if (!u->cgroup_path)
+                 return;
+ 
+-        r = cg_trim_everywhere(u->manager->cgroup_supported, u->cgroup_path, !unit_has_name(u, SPECIAL_ROOT_SLICE));
++        r = cg_trim_everywhere(u->cgroup_realized_mask, u->cgroup_path, !unit_has_name(u, SPECIAL_ROOT_SLICE));
+         if (r < 0)
+                 log_debug("Failed to destroy cgroup %s: %s", u->cgroup_path, strerror(-r));
+ 
+diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
+index c1c4d40..7bb2f67 100644
+--- a/src/shared/cgroup-util.c
++++ b/src/shared/cgroup-util.c
+@@ -1619,8 +1619,6 @@ int cg_create_everywhere(CGroupControllerMask supported, CGroupControllerMask ma
+         NULSTR_FOREACH(n, mask_names) {
+                 if (mask & bit)
+                         cg_create(n, path);
+-                else if (supported & bit)
+-                        cg_trim(n, path, true);
+ 
+                 bit <<= 1;
+         }
diff --git a/debian/patches/core-don-t-fail-to-run-services-in-user-instances-if.patch b/debian/patches/core-don-t-fail-to-run-services-in-user-instances-if.patch
new file mode 100644
index 0000000..b98a739
--- /dev/null
+++ b/debian/patches/core-don-t-fail-to-run-services-in-user-instances-if.patch
@@ -0,0 +1,86 @@
+From 72794f914b58fface4749d7bb8c451142b2e7d1b Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Thu, 12 Feb 2015 12:21:16 +0100
+Subject: [PATCH] core: don't fail to run services in --user instances if $HOME
+ is missing
+
+Otherwise we cannot even invoke systemd-exit.service anymore, thus not
+even exit.
+
+https://bugs.freedesktop.org/show_bug.cgi?id=83100
+https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=759320
+
+(cherry picked from commit 4c08c8242a687e00b289e948ccd07b96f0bc4866)
+
+exec: also evaluate working_directory_missing_ok when not applying chroots
+
+(cherry picked from commit cf1d0302aeaf4e44a6a643fb41e5525fdd04b1d5)
+---
+ src/core/execute.c | 10 ++++++----
+ src/core/execute.h |  1 +
+ src/core/unit.c    |  4 ++++
+ 3 files changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/src/core/execute.c b/src/core/execute.c
+index 88d094e..b6cb6f6 100644
+--- a/src/core/execute.c
++++ b/src/core/execute.c
+@@ -1611,7 +1611,8 @@ int exec_spawn(ExecCommand *command,
+                                         goto fail_child;
+                                 }
+ 
+-                        if (chdir(context->working_directory ? context->working_directory : "/") < 0) {
++                        if (chdir(context->working_directory ?: "/") < 0 &&
++                            !context->working_directory_missing_ok) {
+                                 err = -errno;
+                                 r = EXIT_CHDIR;
+                                 goto fail_child;
+@@ -1620,14 +1621,15 @@ int exec_spawn(ExecCommand *command,
+                         _cleanup_free_ char *d = NULL;
+ 
+                         if (asprintf(&d, "%s/%s",
+-                                     context->root_directory ? context->root_directory : "",
+-                                     context->working_directory ? context->working_directory : "") < 0) {
++                                     context->root_directory ?: "",
++                                     context->working_directory ?: "") < 0) {
+                                 err = -ENOMEM;
+                                 r = EXIT_MEMORY;
+                                 goto fail_child;
+                         }
+ 
+-                        if (chdir(d) < 0) {
++                        if (chdir(d) < 0 &&
++                            !context->working_directory_missing_ok) {
+                                 err = -errno;
+                                 r = EXIT_CHDIR;
+                                 goto fail_child;
+diff --git a/src/core/execute.h b/src/core/execute.h
+index 9d05d3a..9cef482 100644
+--- a/src/core/execute.h
++++ b/src/core/execute.h
+@@ -97,6 +97,7 @@ struct ExecContext {
+ 
+         struct rlimit *rlimit[_RLIMIT_MAX];
+         char *working_directory, *root_directory;
++        bool working_directory_missing_ok;
+ 
+         mode_t umask;
+         int oom_score_adjust;
+diff --git a/src/core/unit.c b/src/core/unit.c
+index 0e4ebfd..c585ea6 100644
+--- a/src/core/unit.c
++++ b/src/core/unit.c
+@@ -2887,6 +2887,10 @@ int unit_patch_contexts(Unit *u) {
+                         r = get_home_dir(&ec->working_directory);
+                         if (r < 0)
+                                 return r;
++
++                        /* Allow user services to run, even if the
++                         * home directory is missing */
++                        ec->working_directory_missing_ok = true;
+                 }
+ 
+                 if (u->manager->running_as == SYSTEMD_USER &&
+-- 
+2.1.4
+
diff --git a/debian/patches/man-document-failed.patch b/debian/patches/man-document-failed.patch
new file mode 100644
index 0000000..8f5cf99
--- /dev/null
+++ b/debian/patches/man-document-failed.patch
@@ -0,0 +1,29 @@
+From: =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Fri, 7 Nov 2014 18:11:53 -0500
+Subject: man: document --failed
+
+https://bugs.debian.org/767267
+---
+ man/systemctl.xml | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/man/systemctl.xml b/man/systemctl.xml
+index a1f170e..36c11b4 100644
+--- a/man/systemctl.xml
++++ b/man/systemctl.xml
+@@ -320,6 +320,15 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+       <xi:include href="user-system-options.xml" xpointer="system" />
+ 
+       <varlistentry>
++        <term><option>--failed</option></term>
++
++        <listitem>
++          <para>List units in failed state. This is equivalent to
++          <option>--state=failed</option>.</para>
++        </listitem>
++      </varlistentry>
++
++      <varlistentry>
+         <term><option>--no-wall</option></term>
+ 
+         <listitem>
diff --git a/debian/patches/rules-Fix-by-path-of-mmc-RPMB-partitions-and-don-t-b.patch b/debian/patches/rules-Fix-by-path-of-mmc-RPMB-partitions-and-don-t-b.patch
new file mode 100644
index 0000000..9e9b5d9
--- /dev/null
+++ b/debian/patches/rules-Fix-by-path-of-mmc-RPMB-partitions-and-don-t-b.patch
@@ -0,0 +1,31 @@
+From: Martin Pitt <martin.pitt at ubuntu.com>
+Date: Wed, 11 Feb 2015 15:26:52 +0100
+Subject: rules: Fix by-path of mmc RPMB partitions and don't blkid them
+
+Linux 3.10+ exposes RPMB (Replay Protected Memory Block) partitions of MMC
+devices [1] ; trying to read them with blkid or other unspecific means will
+cause kernel buffer I/O errors and timeouts.
+
+Blacklist those to prevent creating wrong by-path links and
+blkid'ing those.
+
+[1] http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=090d25fe224c0
+
+https://launchpad.net/bugs/1333140
+---
+ rules/60-persistent-storage.rules | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/rules/60-persistent-storage.rules b/rules/60-persistent-storage.rules
+index 475b151..25b44a5 100644
+--- a/rules/60-persistent-storage.rules
++++ b/rules/60-persistent-storage.rules
+@@ -14,7 +14,7 @@ ACTION=="add", SUBSYSTEM=="module", KERNEL=="block", ATTR{parameters/events_dfl_
+ SUBSYSTEM!="block", GOTO="persistent_storage_end"
+ 
+ # skip rules for inappropriate block devices
+-KERNEL=="fd*|mtd*|nbd*|gnbd*|btibm*|dm-*|md*|zram*", GOTO="persistent_storage_end"
++KERNEL=="fd*|mtd*|nbd*|gnbd*|btibm*|dm-*|md*|zram*|mmcblk[0-9]*rpmb", GOTO="persistent_storage_end"
+ 
+ # ignore partitions that span the entire disk
+ TEST=="whole_disk", GOTO="persistent_storage_end"
diff --git a/debian/patches/series b/debian/patches/series
index 5a15547..5e7b67b 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -133,6 +133,8 @@ sysv-generator-Replace-Provides-symlinks-with-real-u.patch
 journal-Fix-syslog-forwarding-without-CAP_SYS_ADMIN.patch
 logind-handle-closing-sessions-over-daemon-restarts.patch
 logind-fix-sd_eviocrevoke-ioctl-call.patch
+rules-Fix-by-path-of-mmc-RPMB-partitions-and-don-t-b.patch
+man-document-failed.patch
 
 ## Debian specific patches:
 Add-back-support-for-Debian-specific-config-files.patch
@@ -182,3 +184,6 @@ udev-re-enable-mount-propagation-for-udevd.patch
 Add-env-variable-for-machine-ID-path.patch
 Prefer-etc-X11-default-display-manager-if-present.patch
 Fix-usr-remount-failure-for-split-usr.patch
+Only-start-logind-if-dbus-is-installed.patch
+cgroup-don-t-trim-cgroup-trees-created-by-someone-el.patch
+core-don-t-fail-to-run-services-in-user-instances-if.patch
diff --git a/debian/rules b/debian/rules
index 57ac4ab..4f79678 100755
--- a/debian/rules
+++ b/debian/rules
@@ -183,7 +183,7 @@ override_dh_install:
 		debian/systemd/lib/lsb/init-functions.d/40-systemd
 	install --mode=644 debian/tmpfiles.d/debian.conf \
 		debian/systemd/usr/lib/tmpfiles.d/
-	install --mode=644 debian/debian-fixup.service debian/ifup at .service \
+	install --mode=644 debian/debian-fixup.service debian/ifup at .service debian/extra/getty-static.service \
 		debian/systemd/lib/systemd/system/
 	install -D --mode=644 debian/extra/network-pre.conf \
 		debian/systemd/lib/systemd/system/networking.service.d/network-pre.conf
@@ -239,6 +239,8 @@ endif
 # use symlinked doc directories as the old udev package did
 override_dh_installdocs:
 	dh_installdocs -pudev -plibudev-dev --link-doc=libudev1
+	# we have to manually install udev's README for the above
+	install -D --mode 644 debian/udev.README.Debian debian/libudev1/usr/share/doc/libudev1/README.Debian
 	dh_installdocs -pgir1.2-gudev-1.0 -plibgudev-1.0-dev --link-doc=libgudev-1.0-0
 	dh_installdocs --remaining-packages
 
diff --git a/debian/systemd.links b/debian/systemd.links
index 6808824..74ab5a7 100644
--- a/debian/systemd.links
+++ b/debian/systemd.links
@@ -75,8 +75,9 @@
 # We have the journal to handle kernel messages from early boot
 /dev/null /lib/systemd/system/bootlogs.service
 
-# Run fixups early
+# Enable Debian specific units
 /lib/systemd/system/debian-fixup.service /lib/systemd/system/sysinit.target.wants/debian-fixup.service
+/lib/systemd/system/getty-static.service /lib/systemd/system/getty.target.wants/getty-static.service
 
 # Compat symlink
 /lib/systemd/systemd /bin/systemd
diff --git a/debian/tests/boot-and-services b/debian/tests/boot-and-services
index ecc5f8c..748e21d 100755
--- a/debian/tests/boot-and-services
+++ b/debian/tests/boot-and-services
@@ -10,6 +10,7 @@ import subprocess
 import tempfile
 import shutil
 import time
+from glob import glob
 
 
 class ServicesTest(unittest.TestCase):
@@ -155,6 +156,107 @@ poweroff\n''')
         self.assertIn(b'Requesting system poweroff', out)
 
 
+class CgroupsTest(unittest.TestCase):
+    '''Check cgroup setup'''
+
+    @classmethod
+    def setUpClass(kls):
+        kls.controllers = []
+        for controller in glob('/sys/fs/cgroup/*'):
+            if not os.path.islink(controller):
+                kls.controllers.append(controller)
+
+    def setUp(self):
+        self.service = 'testsrv.service'
+        self.service_file = '/run/systemd/system/' + self.service
+
+    def tearDown(self):
+        subprocess.call(['systemctl', 'stop', self.service],
+                        stderr=subprocess.PIPE)
+        try:
+            os.unlink(self.service_file)
+        except OSError:
+            pass
+        subprocess.check_call(['systemctl', 'daemon-reload'])
+
+    def create_service(self, extra_service=''):
+        '''Create test service unit'''
+
+        with open(self.service_file, 'w') as f:
+            f.write('''[Unit]
+Description=test service
+[Service]
+ExecStart=/bin/sleep 500
+%s
+''' % extra_service)
+        subprocess.check_call(['systemctl', 'daemon-reload'])
+
+    def assertNoControllers(self):
+        '''Assert that no cgroup controllers exist for test service'''
+
+        cs = glob('/sys/fs/cgroup/*/system.slice/%s' % self.service)
+        self.assertEqual(cs, [])
+
+    def assertController(self, name):
+        '''Assert that cgroup controller exists for test service'''
+
+        c = '/sys/fs/cgroup/%s/system.slice/%s' % (name, self.service)
+        self.assertTrue(os.path.isdir(c))
+
+    def assertNoController(self, name):
+        '''Assert that cgroup controller does not exist for test service'''
+
+        c = '/sys/fs/cgroup/%s/system.slice/%s' % (name, self.service)
+        self.assertFalse(os.path.isdir(c))
+
+    def test_simple(self):
+        '''simple service'''
+
+        self.create_service()
+        self.assertNoControllers()
+        subprocess.check_call(['systemctl', 'start', self.service])
+        self.assertController('systemd')
+        subprocess.check_call(['systemctl', 'stop', self.service])
+        self.assertNoControllers()
+
+    def test_cpushares(self):
+        '''service with CPUShares'''
+
+        self.create_service('CPUShares=1000')
+        self.assertNoControllers()
+        subprocess.check_call(['systemctl', 'start', self.service])
+        self.assertController('systemd')
+        self.assertController('cpu,cpuacct')
+        subprocess.check_call(['systemctl', 'stop', self.service])
+        self.assertNoControllers()
+
+    def test_custom_cgroup_cleanup(self):
+        '''cgroup cleanup does not touch manually created cgroups'''
+
+        # reproduces https://bugs.debian.org/777601
+        self.create_service()
+        os.mkdir('/sys/fs/cgroup/blkio/aux')
+        os.mkdir('/sys/fs/cgroup/perf_event/aux')
+        self.addCleanup(os.rmdir, '/sys/fs/cgroup/blkio/aux')
+        self.addCleanup(os.rmdir, '/sys/fs/cgroup/perf_event/aux')
+        subprocess.check_call(['systemctl', 'start', self.service])
+        self.assertController('systemd')
+        self.assertTrue(os.path.exists('/sys/fs/cgroup/blkio/aux'))
+        self.assertTrue(os.path.exists('/sys/fs/cgroup/perf_event/aux'))
+
+        subprocess.check_call(['systemctl', 'daemon-reload'])
+        time.sleep(1)
+        subprocess.check_call(['systemctl', 'restart', self.service])
+        time.sleep(1)
+        self.assertTrue(os.path.exists('/sys/fs/cgroup/blkio/aux'))
+        self.assertTrue(os.path.exists('/sys/fs/cgroup/perf_event/aux'))
+
+        subprocess.check_call(['systemctl', 'stop', self.service])
+        self.assertNoControllers()
+        self.assertTrue(os.path.exists('/sys/fs/cgroup/blkio/aux'))
+        self.assertTrue(os.path.exists('/sys/fs/cgroup/perf_event/aux'))
+
+
 def boot_with_systemd():
     '''Reboot with systemd as init
 
diff --git a/debian/tests/control b/debian/tests/control
index cd03367..20bd49f 100644
--- a/debian/tests/control
+++ b/debian/tests/control
@@ -1,6 +1,10 @@
 Tests: timedated hostnamed localed-locale localed-x11-keymap logind
 Depends: systemd, libpam-systemd, acl
-Restrictions: needs-root isolation-machine
+Restrictions: needs-root, isolation-machine
+
+Tests: unit-config
+Depends: systemd, python3
+Restrictions: needs-root, allow-stderr
 
 Tests: build-login
 Depends: libsystemd-login-dev, build-essential, pkg-config
diff --git a/debian/tests/unit-config b/debian/tests/unit-config
new file mode 100755
index 0000000..1031640
--- /dev/null
+++ b/debian/tests/unit-config
@@ -0,0 +1,272 @@
+#!/usr/bin/python3
+# autopkgtest check: enable/disable/configure units
+# (C) 2015 Canonical Ltd.
+# Author: Martin Pitt <martin.pitt at ubuntu.com>
+
+import unittest
+import subprocess
+import os
+import sys
+from glob import glob
+
+
+class EnableTests(unittest.TestCase):
+    def tearDown(self):
+        # remove all traces from our test unit
+        f = glob('/lib/systemd/system/test_enable*.service')
+        f += glob('/lib/systemd/system/*/test_enable*.service')
+        f += glob('/etc/systemd/system/test_enable*.service')
+        f += glob('/etc/systemd/system/*/test_enable*.service')
+        f += glob('/etc/init.d/test_enable*')
+        f += glob('/etc/rc?.d/???test_enable*')
+        [os.unlink(i) for i in f]
+
+    def create_unit(self, suffix='', dir='/lib', enable=False):
+        '''Create a test unit'''
+
+        unit = os.path.join(dir, 'systemd', 'system',
+                            'test_enable%s.service' % suffix)
+        with open(unit, 'w') as f:
+            f.write('''[Unit]
+Description=Testsuite unit %s
+[Service]
+ExecStart=/bin/echo hello
+[Install]
+WantedBy=multi-user.target
+''' % suffix)
+
+        if enable:
+            os.symlink(unit, '/etc/systemd/system/multi-user.target.wants/' +
+                       os.path.basename(unit))
+
+        return unit
+
+    def create_sysv(self, suffix='', enable=False):
+        '''Create a test SysV script'''
+
+        script = '/etc/init.d/test_enable%s' % suffix
+        with open(script, 'w') as f:
+            f.write('''/bin/sh
+### BEGIN INIT INFO
+# Provides:          test_enable%s
+# Required-Start:    $remote_fs $syslog
+# Required-Stop:     $remote_fs $syslog
+# Default-Start:     2 3 4 5
+# Default-Stop:      0 1 6
+# Short-Description: Testsuite script%s
+### END INIT INFO
+
+echo hello
+''' % (suffix, suffix))
+        os.chmod(script, 0o755)
+
+        if enable:
+            subprocess.check_call(['update-rc.d', os.path.basename(script),
+                                   'defaults'])
+            subprocess.check_call(['update-rc.d', os.path.basename(script),
+                                   'enable'])
+
+    def assertEnabled(self, enabled, unit='test_enable.service'):
+        '''assert that given unit has expected state'''
+
+        systemctl = subprocess.Popen(['systemctl', 'is-enabled', unit],
+                                     stdout=subprocess.PIPE,
+                                     universal_newlines=True)
+        out = systemctl.communicate()[0].strip()
+        if enabled:
+            self.assertEqual(systemctl.returncode, 0)
+            self.assertEqual(out, 'enabled')
+        else:
+            self.assertEqual(systemctl.returncode, 1)
+            self.assertEqual(out, 'disabled')
+
+    def test_unit_enable(self):
+        '''no sysv: enable unit'''
+
+        self.create_unit()
+        self.assertEnabled(False)
+        # also works without .service suffix
+        self.assertEnabled(False, unit='test_enable')
+
+        subprocess.check_call(['systemctl', 'enable', 'test_enable'])
+
+        self.assertEnabled(True)
+        # also works without .service suffix
+        self.assertEnabled(True, unit='test_enable')
+
+        l = '/etc/systemd/system/multi-user.target.wants/test_enable.service'
+        self.assertTrue(os.path.islink(l))
+        self.assertEqual(os.readlink(l),
+                         '/lib/systemd/system/test_enable.service')
+
+    def test_unit_disable(self):
+        '''no sysv: disable unit'''
+
+        self.create_unit(enable=True)
+        self.assertEnabled(True)
+        # also works without .service suffix
+        self.assertEnabled(True, unit='test_enable')
+
+        subprocess.check_call(['systemctl', 'disable', 'test_enable'])
+
+        self.assertEnabled(False)
+        # also works without .service suffix
+        self.assertEnabled(False, unit='test_enable')
+
+        l = '/etc/systemd/system/multi-user.target.wants/test_enable.service'
+        self.assertFalse(os.path.islink(l))
+
+    def test_unit_sysv_enable(self):
+        '''with sysv: enable unit'''
+
+        self.create_unit()
+        self.create_sysv()
+        self.assertEnabled(False)
+        # also works without .service suffix
+        self.assertEnabled(False, unit='test_enable')
+
+        subprocess.check_call(['systemctl', 'enable', 'test_enable'])
+
+        self.assertEnabled(True)
+        # also works without .service suffix
+        self.assertEnabled(True, unit='test_enable')
+
+        l = '/etc/systemd/system/multi-user.target.wants/test_enable.service'
+        self.assertTrue(os.path.islink(l))
+        self.assertEqual(os.readlink(l),
+                         '/lib/systemd/system/test_enable.service')
+
+        # enabled the sysv script
+        l = glob('/etc/rc2.d/S??test_enable')
+        self.assertEqual(len(l), 1, 'expect one symlink in %s' % repr(l))
+        self.assertEqual(os.readlink(l[0]), '../init.d/test_enable')
+
+    def test_unit_sysv_disable(self):
+        '''with sysv: disable unit'''
+
+        self.create_unit(enable=True)
+        self.create_sysv(enable=True)
+        self.assertEnabled(True)
+        # also works without .service suffix
+        self.assertEnabled(True, unit='test_enable')
+
+        subprocess.check_call(['systemctl', 'disable', 'test_enable'])
+
+        self.assertEnabled(False)
+        # also works without .service suffix
+        self.assertEnabled(False, unit='test_enable')
+
+        l = '/etc/systemd/system/multi-user.target.wants/test_enable.service'
+        self.assertFalse(os.path.islink(l))
+
+        # disabled the sysv script
+        l = glob('/etc/rc2.d/S??test_enable')
+        self.assertEqual(l, [])
+
+    def test_unit_alias_enable(self):
+        '''no sysv: enable unit with an alias'''
+
+        u = self.create_unit()
+        with open(u, 'a') as f:
+            f.write('Alias=test_enablea.service\n')
+
+        self.assertEnabled(False)
+
+        subprocess.check_call(['systemctl', 'enable', 'test_enable'])
+
+        self.assertEnabled(True)
+
+        # enablement symlink
+        l = '/etc/systemd/system/multi-user.target.wants/test_enable.service'
+        self.assertTrue(os.path.islink(l))
+        self.assertEqual(os.readlink(l),
+                         '/lib/systemd/system/test_enable.service')
+
+        # alias symlink
+        l = '/etc/systemd/system/test_enablea.service'
+        self.assertTrue(os.path.islink(l))
+        self.assertEqual(os.readlink(l),
+                         '/lib/systemd/system/test_enable.service')
+
+    def test_unit_alias_disable(self):
+        '''no sysv: disable unit with an alias'''
+
+        u = self.create_unit()
+        with open(u, 'a') as f:
+            f.write('Alias=test_enablea.service\n')
+        os.symlink('/lib/systemd/system/test_enable.service',
+                   '/etc/systemd/system/test_enablea.service')
+
+        subprocess.check_call(['systemctl', 'disable', 'test_enable'])
+
+        self.assertEnabled(False)
+
+        # enablement symlink
+        l = '/etc/systemd/system/multi-user.target.wants/test_enable.service'
+        self.assertFalse(os.path.islink(l))
+
+        # alias symlink
+        l = '/etc/systemd/system/test_enablea.service'
+        self.assertFalse(os.path.islink(l))
+
+    def test_unit_sysv_alias_enable(self):
+        '''with sysv: enable unit with an alias'''
+
+        u = self.create_unit()
+        with open(u, 'a') as f:
+            f.write('Alias=test_enablea.service\n')
+        self.create_sysv()
+
+        self.assertEnabled(False)
+
+        subprocess.check_call(['systemctl', 'enable', 'test_enable'])
+
+        # enablement symlink
+        l = '/etc/systemd/system/multi-user.target.wants/test_enable.service'
+        self.assertTrue(os.path.islink(l))
+        self.assertEqual(os.readlink(l),
+                         '/lib/systemd/system/test_enable.service')
+
+        # alias symlink
+        l = '/etc/systemd/system/test_enablea.service'
+        self.assertTrue(os.path.islink(l))
+        self.assertEqual(os.readlink(l),
+                         '/lib/systemd/system/test_enable.service')
+
+        # enabled the sysv script
+        l = glob('/etc/rc2.d/S??test_enable')
+        self.assertEqual(len(l), 1, 'expect one symlink in %s' % repr(l))
+        self.assertEqual(os.readlink(l[0]), '../init.d/test_enable')
+
+        self.assertEnabled(True)
+
+    def test_unit_sysv_alias_disable(self):
+        '''with sysv: disable unit with an alias'''
+
+        u = self.create_unit(enable=True)
+        with open(u, 'a') as f:
+            f.write('Alias=test_enablea.service\n')
+        os.symlink('/lib/systemd/system/test_enable.service',
+                   '/etc/systemd/system/test_enablea.service')
+        self.create_sysv(enable=True)
+
+        subprocess.check_call(['systemctl', 'disable', 'test_enable'])
+
+        # enablement symlink
+        l = '/etc/systemd/system/multi-user.target.wants/test_enable.service'
+        self.assertFalse(os.path.islink(l))
+
+        # alias symlink
+        l = '/etc/systemd/system/test_enablea.service'
+        self.assertFalse(os.path.islink(l))
+
+        # disabled the sysv script
+        l = glob('/etc/rc2.d/S??test_enable')
+        self.assertEqual(l, [])
+
+        self.assertEnabled(False)
+
+
+if __name__ == '__main__':
+    unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout,
+                                                     verbosity=2))
diff --git a/debian/udev.README.Debian b/debian/udev.README.Debian
index 0136185..7a731ec 100644
--- a/debian/udev.README.Debian
+++ b/debian/udev.README.Debian
@@ -1,124 +1,5 @@
-How does udev work?
-~~~~~~~~~~~~~~~~~~~
-Short summary: when a driver is loaded it makes some information available
-in /sys/ and a message is sent to udevd which reads them and creates the
-appropriate devices.
-
-This means that:
-- modules cannot be loaded on demand when applications open their device,
-  because the device is not yet there!
-- since modules are not loaded on demand, if for some reason the drivers
-  cannot be automatically loaded at boot time you will have to add them
-  to /etc/modules.
-- some modules are not hardware drivers and cannot be loaded automatically
-  by udev, so they will have to be listed in /etc/modules as well.
-- some modules for less usual bus types lack the sysfs data needed to be
-  automatically loaded and must be loaded manually.
-  (See #334238 and #337004 for details.)
-
-udevd also manages the hotplug events and if needed dispatches them to
-other programs using RUN rules, as a replacement of the old /sbin/hotplug.
-
-
-Debugging early boot
-~~~~~~~~~~~~~~~~~~~~
-If the system hangs at boot time or fails to boot properly, it may be
-useful to examine in real time what is happening while "udevadm settle"
-is running. A simple way to do this is:
-
-* boot the system passing "init=/bin/bash" on the kernel command line
-* start a getty on tty2 (or the serial console) with a command like
-  "/sbin/getty 38400 tty2 &"
-* continue the boot process with "exec /sbin/init single"
-
-The open console can be used to check which processes are running and
-what they are waiting for.
-
-Setting the kernel command line options documented in udevd(8) may also
-help to identify system-wide troubles caused by specific kernel drivers.
-
-
-Required kernel support
-~~~~~~~~~~~~~~~~~~~~~~~
-The required kernel version and features are documented in the README
-file.
-
-
-Disabling udev
-~~~~~~~~~~~~~~
-You may configure in /etc/udev/udev.conf a directory other than /dev
-or add UDEV_DISABLED=yes to the kernel command line.
-
-
-Manually creating devices
-~~~~~~~~~~~~~~~~~~~~~~~~~
-Device nodes present in /lib/udev/devices/ will be copied to /dev/ at
-boot time.
-
-
-The /etc/udev/rules.d/ directory
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The files are read and processed in alphabetical order, and the directives
-of matching rules are applied in order.
-If a file with the same name is present in more than one of the
-/run/udev/rules.d/, /etc/udev/rules.d/ and /lib/udev/rules.d/ directories
-then the latter(s) file will be ignored.
-Since the order may be important, files have a specific name which
-must be considered when adding custom rules. So far have been defined:
-
- - 60: path_id and the other *_id programs are run. persistent links
-   are set.
-
- - 70: network interfaces are renamed and generated rules for persistent
-   links are processed.
-
- - 75: the rules generators are run if needed.
-
- - 80: drivers are loaded.
-
- - 91: the default permissions and owners are set.
-
- - 95: $REMOVE_CMD is run, and then processing of tty devices
-   is stopped with last_rule.
-
-The persistent-*.rules files are generated by the *-generator.rules files
-using the /lib/udev/write_*_rules scripts when new devices are detected.
-They set stable names for network interfaces and optical devices aliases.
-
-
-How to know the attributes of a device
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Try something like:
-udevadm info --attribute-walk --path=/sys/class/sound/pcmC0D0c/
-
-
-Devices timestamps
-~~~~~~~~~~~~~~~~~~
-Most devices will be created at the beginning of the boot process, and will
-have the creation time of the kernel clock at that moment.
-On systems whose system clock is set on local time instead of UTC, the
-kernel clock will be updated in a later phase of the boot process and for
-a few hours the devices will have a timestamp in the future.
-This is usually not a problem, but if it bothers you it can be fixed by
-running touch(1) in an init script.
-
-
-SCSI block and generic devices
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When you create a custom rule which matches SCSI devices by some sysfs
-attributes, do not forget that it will match not only the sdX device node
-you are probably looking for but also the SCSI generic device node sgX.
-To get the expected behaviour, you need to add KERNEL="sd*" to your rule.
-A typical example for an USB pen drive is:
-
-SUBSYSTEMS=="usb", KERNEL=="sd*", \
-	ATTRS{manufacturer}=="hardware vendor", ATTRS{product}=="model", \
-	SYMLINK+="pendrive%n"
-
-If a device does not report media changes (like e.g. many SD card readers)
-you will also need to add the OPTIONS+="all_partitions" attribute to the
-rule. This is not needed if you are using HAL.
-
+This documents udev integration Debian specifics. Please see man udev(7) and
+its referenced manpages for general documentation.
 
 Network Interfaces
 ~~~~~~~~~~~~~~~~~~
@@ -163,11 +44,3 @@ A possible solution is to configure /etc/nsswitch.conf like this:
   group:          files ldap [UNAVAIL=return]
 
 The nsswitch.conf syntax is documented in the glibc manual.
-
-
-Other documentation
-~~~~~~~~~~~~~~~~~~~
-http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html
-http://www.reactivated.net/udevrules.php
-http://www.kroah.com/linux/talks/suse_2005_driver_model/
-
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.alioth.debian.org/pipermail/pkg-systemd-maintainers/attachments/20150216/31eb6941/attachment-0001.sig>


More information about the Pkg-systemd-maintainers mailing list