#きょうのsystemd : Ubuntuで新しいめのsystemdを使おうとしてコケた話

はじめに

きょうは何だか翻訳の気分ではないし、自分の文章を書きたいので、寄り道をする。

翻訳が増えることを期待してくれた方には申し訳ない。

新しいめのsystemdを試したい

systemd 235では、以前に紹介したような機能が搭載された。

popopopoon.hatenadiary.jp

例えば、「Ubuntuでちょっとこれを使ってみたいな」と思ったとしよう、というのが本稿のスタート地点である。

ところで、先月リリースされたばかりのUbuntu 17.10のsystemdのバージョンは234である。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 17.10
Release:        17.10
Codename:       artful
$ systemctl --version
systemd 234
+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN2 +IDN default-hierarchy=hybrid

というわけで、systemd 235のパッケージをビルドして、インストールしようというわけだ。

比較的正しい手順

@MurabitoL さんが「比較的正しい手順」を教えてくれた。

こちらに従うのが良いだろう。

おことわり

本稿の作業を最後までおこなうと、ディストリビューション標準のパッケージ、しかも、システムの根幹に関わるsystemdのパッケージを上書きインストールすることになる。

壊れてもいい環境か、本番環境を壊してもいいという覚悟かのいずれかをもって臨んでほしい。

パッケージビルド

流れは以下の記事の「すでにソースパッケージがある場合」に沿っている。

gihyo.jp

Ubuntuの条件

systemd 235のビルドではmesonというビルドシステムが使われるようなのだが、Ubuntu 17.04でインストールできるmesonはsystemd 235で指定されているバージョンに届かないようだ。 Ubuntu 16.04でインストールできるmesonもバージョンが足りないことは想像に難くない*1

一方、Ubuntu 17.10でインストールできるmesonはバージョンの要件を満たしているようである。

したがって、要件を満たすmesonを自前でビルド・インストールするか、Ubuntu 17.10を使うかのどちらかの選択となる。

おそらく、仮想マシンなり、任意のシステムコンテナなりで作業しているであろうから、素直に後者ということで話を進める。

ビルドに必要なパッケージをインストールする

さて、systemdのビルドに必要なパッケージをインストールする。

デフォルトではソースパッケージをレポジトリから取ってくるようになっていないはずなので、これを有効にする。

$ sudo sed -i /etc/apt/sources.list -e 's/# deb-src/deb-src/'

そして、パッケージリストを更新する。ついでに、アップグレードもしておこう。

$ sudo apt update
$ sudo apt upgrade

systemdのパッケージビルドに必要なパッケージをインストールする

$ sudo apt -y install fakeroot
$ sudo apt -y build-dep systemd

どこからソースコードを取ってくるのが良いか?

Ubuntu 17.10で提供されているsystemd 234のパッケージ・ビルドに必要なものが整ったところで、ディストロ提供のsystemdのソースをダウンロードしてみるフリをする。

$ apt source --dry-run systemd
パッケージリストを読み込んでいます... 完了                                      
注意: 'systemd' パッケージは以下の場所の 'Git' バージョン制御システムで保守されています:
https://anonscm.debian.org/git/pkg-systemd/systemd.git
パッケージの最新の (まだリリースされていないかもしれない) 更新を取得するには、
git clone https://anonscm.debian.org/git/pkg-systemd/systemd.git
を使用してください。
4,948 kB のソースアーカイブを取得する必要があります。                                                 
ソース systemd を取得

我々がビルドしたいのは234ではなく235なので、注意に従うことにする*2

ソースコードを取得する

インストールされていなければ、gitをインストールする

$ sudo apt install git

任意の場所で指示通り、git cloneする

$ git clone https://anonscm.debian.org/git/pkg-systemd/systemd.git

一旦、クローンしたURLをブラウザで開いてみる。

pkg-systemd/systemd - systemd packaging

'Tag'の欄に'debian/235-2'というのが見える。今回はこれをビルド・インストールしてみる。

ここで、クローンしたgitのローカルレポジトリに移動する。

$ cd systemd

さっき確認したタグでチェックアウトする。メッセージが表示されるが、ビルドだけなら特に気にしなくて良い。

$ git checkout refs/tags/debian/235-2

次のコマンドでdebian/235-2と見えていればOKだ。

$ git branch

ビルドする

ここからは簡単なはずであった。先に挙げた記事にあるとおり、ビルドのコマンドを叩く。

$ dpkg-buildpackage -r -uc -b

うーん、エラーでコケる。

$ ./configure
[...]
Meson encountered an error in file meson.build, line 2387, column 8:
File src/test/test-helper.c does not exist.

これがヒントになる。gitで調べると

$ git status src/test/test-helper.c
On branch master
Your branch is up-to-date with 'origin/master'.

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        deleted:    src/test/test-helper.c

no changes added to commit (use "git add" and/or "git commit -a")

なぜか消えている。復活させる*3

$ git checkout src/test/test-helper.c

再度、ビルドを走らせる。

$ dpkg-buildpackage -r -uc -b

今度はビルドが走る。お茶を飲みながら待つ。

インストールする

ビルドが終わると、systemdディレクトリの1つ上の階層に*.debができているはずである。

$ cd ..
$ *.deb
-rw-r--r-- 1 popo popo  105316 11月  8 21:59 libnss-myhostname_235-2_amd64.deb
-rw-r--r-- 1 popo popo  174338 11月  8 21:59 libnss-mymachines_235-2_amd64.deb
-rw-r--r-- 1 popo popo  173768 11月  8 21:58 libnss-resolve_235-2_amd64.deb
-rw-r--r-- 1 popo popo  171718 11月  8 21:58 libnss-systemd_235-2_amd64.deb
-rw-r--r-- 1 popo popo  174736 11月  8 21:59 libpam-systemd_235-2_amd64.deb
-rw-r--r-- 1 popo popo  249148 11月  8 21:58 libsystemd-dev_235-2_amd64.deb
-rw-r--r-- 1 popo popo  267560 11月  8 21:58 libsystemd0_235-2_amd64.deb
-rw-r--r-- 1 popo popo   93654 11月  8 21:58 libudev-dev_235-2_amd64.deb
-rw-r--r-- 1 popo popo  125620 11月  8 21:58 libudev1_235-2_amd64.deb
-rw-r--r-- 1 popo popo  297980 11月  8 21:58 systemd-container_235-2_amd64.deb
-rw-r--r-- 1 popo popo  116260 11月  8 21:58 systemd-coredump_235-2_amd64.deb
-rw-r--r-- 1 popo popo  129242 11月  8 21:58 systemd-journal-remote_235-2_amd64.deb
-rw-r--r-- 1 popo popo   83696 11月  8 21:58 systemd-sysv_235-2_amd64.deb
-rw-r--r-- 1 popo popo 3111888 11月  8 21:58 systemd-tests_235-2_amd64.deb
-rw-r--r-- 1 popo popo 2933620 11月  8 21:58 systemd_235-2_amd64.deb
-rw-r--r-- 1 popo popo 1156966 11月  8 21:58 udev_235-2_amd64.deb

これらを全部インストールしようとする。

$ sudo dpkg -i *.deb
処理中にエラーが発生しました:
 systemd-coredump_235-2_amd64.deb

と出るが、普通*4に使う分には特に問題がないことは確認しているので、気にしない。

再起動する*5

$ sudo reboot

バージョンを確認する。

$ systemctl --version
systemd 235
+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN2 +IDN default-hierarchy=hybrid

IPアカウンティングで遊んでみる。

$ unset LANG
$ sudo systemd-run -p IPAccounting=yes --wait ping -c 5 localhost
Running as unit: run-u14.service
Finished with result: success
Main processes terminated with: code=exited/status=0
Service runtime: 4.096s
IP traffic received: 520B
IP traffic sent: 520B
$ journalctl -u run-u14.service 
-- Logs begin at Wed 2017-11-08 22:06:05 JST, end at Wed 2017-11-08 22:10:14 JST. --
Nov 08 22:10:10 systemd systemd[1]: Started /bin/ping -c 5 localhost.
Nov 08 22:10:10 systemd ping[931]: PING localhost(localhost (::1)) 56 data bytes
Nov 08 22:10:10 systemd ping[931]: 64 bytes from localhost (::1): icmp_seq=1 ttl=64 time=0.035 ms
Nov 08 22:10:11 systemd ping[931]: 64 bytes from localhost (::1): icmp_seq=2 ttl=64 time=0.055 ms
Nov 08 22:10:12 systemd ping[931]: 64 bytes from localhost (::1): icmp_seq=3 ttl=64 time=0.068 ms
Nov 08 22:10:13 systemd ping[931]: 64 bytes from localhost (::1): icmp_seq=4 ttl=64 time=0.056 ms
Nov 08 22:10:14 systemd ping[931]: 64 bytes from localhost (::1): icmp_seq=5 ttl=64 time=0.057 ms
Nov 08 22:10:14 systemd ping[931]: --- localhost ping statistics ---
Nov 08 22:10:14 systemd ping[931]: 5 packets transmitted, 5 received, 0% packet loss, time 4092ms
Nov 08 22:10:14 systemd ping[931]: rtt min/avg/max/mdev = 0.035/0.054/0.068/0.011 ms
Nov 08 22:10:14 systemd systemd[1]: run-u14.service: Received 520B IP traffic, sent 520B IP traffic

ヒャッハー

追記(コケる件について)

エラーについて報告する必要があるかもしれないので、メモ。

1回目のdpkg-buildpackage -r -uc -bは最後に以下のようなダイイングメッセージを残して死ぬ。

Running command: /usr/bin/git --git-dir=/home/popo/systemd/.git ls-files :/*.[ch]
Died at /usr/share/perl5/Debian/Debhelper/Buildsystem/meson.pm line 61.
debian/rules:153: recipe for target 'override_dh_auto_configure' failed
make[1]: *** [override_dh_auto_configure] Error 2
make[1]: Leaving directory '/home/popo/systemd'
debian/rules:293: recipe for target 'binary' failed
make: *** [binary] Error 2
dpkg-buildpackage: error: fakeroot debian/rules binary gave error exit status 2

その時のgit statusは次の通り。

On branch master
Your branch is up-to-date with 'origin/master'.

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   man/journald.conf.xml
        modified:   man/rules/meson.build
        modified:   man/systemd-system.conf.xml
        modified:   meson.build
        modified:   po/POTFILES.in
        modified:   rules/50-udev-default.rules.in
        modified:   src/basic/cgroup-util.c
        modified:   src/basic/time-util.c
        modified:   src/core/cgroup.c
        modified:   src/core/dynamic-user.c
        modified:   src/core/dynamic-user.h
        modified:   src/core/execute.c
        modified:   src/core/locale-setup.c
        modified:   src/core/main.c
        modified:   src/core/mount-setup.c
        modified:   src/core/namespace.c
        modified:   src/core/system.conf
        modified:   src/core/unit.c
        modified:   src/fstab-generator/fstab-generator.c
        modified:   src/hostname/org.freedesktop.hostname1.service
        modified:   src/journal/journald-audit.c
        modified:   src/journal/journald-server.c
        modified:   src/journal/journald.conf
        modified:   src/libsystemd/sd-id128/sd-id128.c
        modified:   src/libsystemd/sd-login/sd-login.c
        modified:   src/locale/keymap-util.c
        modified:   src/locale/org.freedesktop.locale1.service
        modified:   src/login/logind-core.c
        modified:   src/login/org.freedesktop.login1.service
        modified:   src/login/pam_systemd.c
        modified:   src/shared/sleep-config.c
        modified:   src/systemctl/systemctl.c
        modified:   src/test/meson.build
        modified:   src/test/test-bpf.c
        modified:   src/test/test-cgroup-mask.c
        modified:   src/test/test-engine.c
        modified:   src/test/test-execute.c
        modified:   src/test/test-fs-util.c
        deleted:    src/test/test-helper.c
        modified:   src/test/test-helper.h
        modified:   src/test/test-path.c
        modified:   src/test/test-sched-prio.c
        modified:   src/test/test-unit-file.c
        modified:   src/test/test-unit-name.c
        modified:   src/timedate/org.freedesktop.timedate1.service
        modified:   src/timedate/timedated.c
        modified:   src/timesync/meson.build
        modified:   src/udev/udev-event.c
        modified:   src/udev/udev.conf
        modified:   sysctl.d/50-coredump.conf.in
        modified:   tmpfiles.d/legacy.conf
        modified:   tmpfiles.d/tmp.conf
        modified:   units/meson.build
        modified:   units/systemd-fsck-root.service.in
        modified:   units/systemd-fsck@.service.in
        modified:   units/systemd-logind.service.in
        modified:   units/user/graphical-session-pre.target

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        .pc/
        man/systemd-fsckd.service.xml
        src/fsckd/
        units/systemd-fsckd.service.in
        units/systemd-fsckd.socket

no changes added to commit (use "git add" and/or "git commit -a")

modifiedなのもよくわからないが、とりあえず、切り分けたところ、原因はdeletedになっているsrc/test/test-helper.cである。

本文の再掲となるが

$ ./configure
[...]
Meson encountered an error in file meson.build, line 2387, column 8:
File src/test/test-helper.c does not exist.

がヒントだった。

git checkout src/test/test-helper.cで復活させて、2回めのdpkg-buildpackage -r -uc -b後のgit statusは以下の通り

On branch master
Your branch is up-to-date with 'origin/master'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        debian/.debhelper/
        debian/debhelper-build-stamp
        debian/files
        debian/install/
        debian/libnss-myhostname.substvars
        debian/libnss-myhostname/
        debian/libnss-mymachines.substvars
        debian/libnss-mymachines/
        debian/libnss-resolve.substvars
        debian/libnss-resolve/
        debian/libnss-systemd.substvars
        debian/libnss-systemd/
        debian/libpam-systemd.substvars
        debian/libpam-systemd/
        debian/libsystemd-dev.substvars
        debian/libsystemd-dev/
        debian/libsystemd0.substvars
        debian/libsystemd0/
        debian/libudev-dev.postinst.debhelper
        debian/libudev-dev.postrm.debhelper
        debian/libudev-dev.preinst.debhelper
        debian/libudev-dev.prerm.debhelper
        debian/libudev-dev.substvars
        debian/libudev-dev/
        debian/libudev1-udeb.substvars
        debian/libudev1-udeb/
        debian/libudev1.substvars
        debian/libudev1/
        debian/shlibs.local
        debian/systemd-container.postinst.debhelper
        debian/systemd-container.postrm.debhelper
        debian/systemd-container.preinst.debhelper
        debian/systemd-container.prerm.debhelper
        debian/systemd-container.substvars
        debian/systemd-container/
        debian/systemd-coredump.substvars
        debian/systemd-coredump/
        debian/systemd-journal-remote.substvars
        debian/systemd-journal-remote/
        debian/systemd-sysv.substvars
        debian/systemd-sysv/
        debian/systemd-tests.substvars
        debian/systemd-tests/
        debian/systemd.postinst.debhelper
        debian/systemd.postrm.debhelper
        debian/systemd.preinst.debhelper
        debian/systemd.prerm.debhelper
        debian/systemd.substvars
        debian/systemd/
        debian/udev-udeb.substvars
        debian/udev-udeb/
        debian/udev.postinst.debhelper
        debian/udev.postrm.debhelper
        debian/udev.preinst.debhelper
        debian/udev.prerm.debhelper
        debian/udev.substvars
        debian/udev/

nothing added to commit but untracked files present (use "git add" to track)

modifiedはきれいに消えてる。というか、戻しているというのが正確か。

察しの良い方はお気づきだろうが、origin/masterでも再現する。

*1:確認してはいない

*2:当初はアップストリームのsystemdをgit cloneしてビルドするつもりだった。systemd-234のdebianディレクトリをこれに差し込んで、ちょっとファイルいじったりして、なんとかビルドできないか試した。しかし、うまくいかなかった。アップストリームのものではないという意味で「新しいめのsystemd」である。

*3:コケる原因はわかったし、ビルドもできるが、バリバリのワークアラウンドで納得はいかない。パッケージングのことはほとんどわからない。debian/controlあたりに問題があるんだろうか。そして、どこに報告すれば良いんだろう。というか、unstableなものを使ってる自信はあるので、報告すべきことなのだろうか。

*4:普通って何

*5:virt-managerkvmとの組み合わせでVMを立ててやったら、落ちきらなかったので、強制的に再起動をかけた。