summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@parabola.nu>2018-08-16 21:58:58 -0400
committerLuke Shumaker <lukeshu@parabola.nu>2018-08-16 21:58:58 -0400
commit1e21cd5b0c118c66cc22e0316a1edbdd9c95d217 (patch)
treec7652190fad3d331841322762b587e6f6919447a
parent4e73316c248bc4655f30032d70ea6cdef21fb604 (diff)
parent804d2901ed3c41c972412071bd65266a5851267f (diff)
Merge tag 'notsystemd/v233.1' into notsystemd/master
-rw-r--r--.github/CONTRIBUTING.md2
-rw-r--r--.gitignore11
-rw-r--r--.mailmap13
l---------.mkosi/Makefile1
-rw-r--r--.mkosi/mkosi.debian82
-rw-r--r--.mkosi/mkosi.fedora4
-rw-r--r--CODING_STYLE5
-rw-r--r--DISTRO_PORTING24
-rw-r--r--ENVIRONMENT.md66
-rw-r--r--HACKING4
-rw-r--r--Makefile-man.am51
-rw-r--r--Makefile.am396
-rw-r--r--NEWS442
-rw-r--r--README24
-rw-r--r--README.md4
-rw-r--r--TODO131
-rw-r--r--catalog/systemd.be.catalog.in10
-rw-r--r--catalog/systemd.be@latin.catalog.in10
-rw-r--r--catalog/systemd.bg.catalog.in10
-rw-r--r--catalog/systemd.catalog.in25
-rw-r--r--catalog/systemd.da.catalog.in10
-rw-r--r--catalog/systemd.fr.catalog.in31
-rw-r--r--catalog/systemd.hr.catalog.in10
-rw-r--r--catalog/systemd.hu.catalog.in10
-rw-r--r--catalog/systemd.it.catalog.in86
-rw-r--r--catalog/systemd.ko.catalog.in10
-rw-r--r--catalog/systemd.pl.catalog.in28
-rw-r--r--catalog/systemd.pt_BR.catalog.in10
-rw-r--r--catalog/systemd.ru.catalog.in37
-rw-r--r--catalog/systemd.sr.catalog.in10
-rw-r--r--catalog/systemd.zh_CN.catalog.in12
-rw-r--r--catalog/systemd.zh_TW.catalog.in10
-rw-r--r--coccinelle/strjoin.cocci16
-rw-r--r--configure.ac230
-rw-r--r--docs/sysvinit/README.in2
-rw-r--r--hwdb/20-OUI.hwdb4758
-rw-r--r--hwdb/20-acpi-vendor.hwdb18
-rw-r--r--hwdb/20-pci-vendor-model.hwdb920
-rw-r--r--hwdb/20-usb-vendor-model.hwdb473
-rw-r--r--hwdb/60-evdev.hwdb71
-rw-r--r--hwdb/60-keyboard.hwdb59
-rw-r--r--hwdb/60-sensor.hwdb54
-rw-r--r--hwdb/70-mouse.hwdb40
-rw-r--r--hwdb/70-pointingstick.hwdb13
-rw-r--r--hwdb/70-touchpad.hwdb8
-rwxr-xr-xhwdb/acpi-update.py4
-rwxr-xr-xhwdb/parse_hwdb.py42
-rwxr-xr-xman/50-xdg-data-dirs.sh12
-rwxr-xr-xman/90-rearrange-path.py40
-rw-r--r--man/bootctl.xml4
-rw-r--r--man/bootup.xml7
-rw-r--r--man/busctl.xml10
-rw-r--r--man/coredump.conf.xml2
-rw-r--r--man/coredumpctl.xml85
-rw-r--r--man/environment.d.xml122
-rw-r--r--man/file-hierarchy.xml2
-rw-r--r--man/hostnamectl.xml1
-rw-r--r--man/hwdb.xml90
-rw-r--r--man/journalctl.xml24
-rw-r--r--man/journald.conf.xml2
-rw-r--r--man/kernel-command-line.xml87
-rw-r--r--man/kernel-install.xml11
-rw-r--r--man/localectl.xml2
-rw-r--r--man/loginctl.xml36
-rw-r--r--man/machine-id.xml30
-rw-r--r--man/machine-info.xml1
-rw-r--r--man/machinectl.xml88
-rw-r--r--man/networkctl.xml6
-rw-r--r--man/nss-resolve.xml20
-rw-r--r--man/pam_systemd.xml44
-rw-r--r--man/resolved.conf.xml15
-rw-r--r--man/sd-bus.xml2
-rw-r--r--man/sd-id128.xml17
-rw-r--r--man/sd-login.xml2
-rw-r--r--man/sd_bus_error.xml6
-rw-r--r--man/sd_bus_error_add_map.xml2
-rw-r--r--man/sd_bus_message_append.xml4
-rw-r--r--man/sd_bus_path_encode.xml4
-rw-r--r--man/sd_event_add_defer.xml2
-rw-r--r--man/sd_event_source_set_prepare.xml9
-rw-r--r--man/sd_id128_get_machine.xml65
-rw-r--r--man/sd_is_fifo.xml34
-rw-r--r--man/sd_journal_add_match.xml2
-rw-r--r--man/sd_journal_get_catalog.xml2
-rw-r--r--man/sd_journal_get_data.xml4
-rw-r--r--man/sd_journal_get_fd.xml4
-rw-r--r--man/sd_journal_print.xml25
-rw-r--r--man/sd_listen_fds.xml2
-rw-r--r--man/sd_login_monitor_new.xml2
-rw-r--r--man/sd_notify.xml29
-rw-r--r--man/sd_watchdog_enabled.xml4
-rw-r--r--man/systemctl.xml211
-rw-r--r--man/systemd-analyze.xml17
-rw-r--r--man/systemd-ask-password-console.service.xml2
-rw-r--r--man/systemd-ask-password.xml45
-rw-r--r--man/systemd-cgls.xml21
-rw-r--r--man/systemd-coredump.xml47
-rw-r--r--man/systemd-cryptsetup@.service.xml7
-rw-r--r--man/systemd-debug-generator.xml2
-rw-r--r--man/systemd-delta.xml4
-rw-r--r--man/systemd-detect-virt.xml8
-rw-r--r--man/systemd-environment-d-generator.xml80
-rw-r--r--man/systemd-escape.xml4
-rw-r--r--man/systemd-firstboot.xml24
-rw-r--r--man/systemd-fsck@.service.xml8
-rw-r--r--man/systemd-fstab-generator.xml46
-rw-r--r--man/systemd-getty-generator.xml2
-rw-r--r--man/systemd-gpt-auto-generator.xml7
-rw-r--r--man/systemd-hostnamed.service.xml2
-rw-r--r--man/systemd-importd.service.xml2
-rw-r--r--man/systemd-inhibit.xml2
-rw-r--r--man/systemd-journal-gatewayd.service.xml10
-rw-r--r--man/systemd-journal-remote.xml2
-rw-r--r--man/systemd-localed.service.xml2
-rw-r--r--man/systemd-logind.service.xml16
-rw-r--r--man/systemd-machine-id-setup.xml2
-rw-r--r--man/systemd-machined.service.xml2
-rw-r--r--man/systemd-modules-load.service.xml4
-rw-r--r--man/systemd-mount.xml20
-rw-r--r--man/systemd-notify.xml30
-rw-r--r--man/systemd-nspawn.xml186
-rw-r--r--man/systemd-remount-fs.service.xml2
-rw-r--r--man/systemd-resolve.xml12
-rw-r--r--man/systemd-resolved.service.xml9
-rw-r--r--man/systemd-run.xml13
-rw-r--r--man/systemd-socket-activate.xml2
-rw-r--r--man/systemd-socket-proxyd.xml21
-rw-r--r--man/systemd-suspend.service.xml6
-rw-r--r--man/systemd-system.conf.xml10
-rw-r--r--man/systemd-timedated.service.xml2
-rw-r--r--man/systemd-timesyncd.service.xml6
-rw-r--r--man/systemd-tty-ask-password-agent.xml12
-rw-r--r--man/systemd-udevd.service.xml16
-rw-r--r--man/systemd-veritysetup-generator.xml122
-rw-r--r--man/systemd-veritysetup@.service.xml75
-rw-r--r--man/systemd-volatile-root.service.xml79
-rw-r--r--man/systemd.environment-generator.xml160
-rw-r--r--man/systemd.exec.xml470
-rw-r--r--man/systemd.generator.xml3
-rw-r--r--man/systemd.journal-fields.xml14
-rw-r--r--man/systemd.link.xml14
-rw-r--r--man/systemd.mount.xml73
-rw-r--r--man/systemd.netdev.xml54
-rw-r--r--man/systemd.network.xml260
-rw-r--r--man/systemd.nspawn.xml20
-rw-r--r--man/systemd.offline-updates.xml47
-rw-r--r--man/systemd.preset.xml2
-rw-r--r--man/systemd.resource-control.xml2
-rw-r--r--man/systemd.scope.xml2
-rw-r--r--man/systemd.service.xml99
-rw-r--r--man/systemd.slice.xml2
-rw-r--r--man/systemd.socket.xml8
-rw-r--r--man/systemd.special.xml74
-rw-r--r--man/systemd.swap.xml37
-rw-r--r--man/systemd.time.xml18
-rw-r--r--man/systemd.timer.xml2
-rw-r--r--man/systemd.unit.xml168
-rw-r--r--man/systemd.xml168
-rw-r--r--man/telinit.xml4
-rw-r--r--man/timedatectl.xml2
-rw-r--r--man/tmpfiles.d.xml28
-rwxr-xr-xmkosi.build10
-rw-r--r--po/LINGUAS1
-rw-r--r--po/ca.po525
-rw-r--r--po/cs.po199
-rw-r--r--po/hr.po2
-rw-r--r--[-rwxr-xr-x]po/id.po0
-rw-r--r--rules/50-udev-default.rules2
-rw-r--r--rules/60-block.rules2
-rw-r--r--rules/60-cdrom_id.rules4
-rw-r--r--rules/60-drm.rules5
-rw-r--r--rules/60-evdev.rules4
-rw-r--r--rules/60-persistent-storage.rules15
-rw-r--r--rules/60-sensor.rules10
-rw-r--r--rules/78-sound-card.rules7
-rw-r--r--rules/99-systemd.rules.in7
-rw-r--r--shell-completion/bash/coredumpctl3
-rw-r--r--shell-completion/bash/hostnamectl2
-rw-r--r--shell-completion/bash/journalctl7
-rw-r--r--shell-completion/bash/systemctl.in8
-rw-r--r--shell-completion/bash/systemd-analyze6
-rw-r--r--shell-completion/zsh/_coredumpctl3
-rw-r--r--shell-completion/zsh/_hostnamectl2
-rw-r--r--shell-completion/zsh/_journalctl4
-rw-r--r--shell-completion/zsh/_systemctl.in26
-rw-r--r--shell-completion/zsh/_systemd-analyze1
-rw-r--r--shell-completion/zsh/_systemd-run8
-rw-r--r--src/activate/activate.c2
-rw-r--r--src/analyze/analyze.c111
-rw-r--r--src/backlight/backlight.c4
-rw-r--r--src/basic/MurmurHash2.c6
-rw-r--r--src/basic/architecture.c3
-rw-r--r--src/basic/architecture.h20
-rw-r--r--src/basic/btrfs-util.c43
-rw-r--r--src/basic/btrfs-util.h4
-rw-r--r--src/basic/build.h5
-rw-r--r--src/basic/calendarspec.c336
-rw-r--r--src/basic/calendarspec.h4
-rw-r--r--src/basic/cgroup-util.c427
-rw-r--r--src/basic/cgroup-util.h13
-rw-r--r--src/basic/conf-files.c7
-rw-r--r--src/basic/copy.c133
-rw-r--r--src/basic/copy.h22
-rw-r--r--src/basic/def.h18
-rw-r--r--src/basic/dirent-util.c3
-rw-r--r--src/basic/env-util.c229
-rw-r--r--src/basic/env-util.h19
-rw-r--r--src/basic/exec-util.c360
-rw-r--r--src/basic/exec-util.h40
-rw-r--r--src/basic/extract-word.c6
-rw-r--r--src/basic/fd-util.c6
-rw-r--r--src/basic/fileio.c170
-rw-r--r--src/basic/fileio.h5
-rw-r--r--src/basic/format-util.h (renamed from src/basic/formats-util.h)6
-rw-r--r--src/basic/fs-util.c131
-rw-r--r--src/basic/fs-util.h22
-rw-r--r--src/basic/hexdecoct.c17
-rw-r--r--src/basic/hostname-util.c2
-rw-r--r--src/basic/in-addr-util.c55
-rw-r--r--src/basic/in-addr-util.h9
-rw-r--r--src/basic/journal-importer.c483
-rw-r--r--src/basic/journal-importer.h70
-rw-r--r--src/basic/khash.c275
-rw-r--r--src/basic/khash.h53
-rw-r--r--src/basic/log.c119
-rw-r--r--src/basic/log.h4
-rw-r--r--src/basic/missing.h57
-rw-r--r--src/basic/missing_syscall.h2
-rw-r--r--src/basic/mount-util.c60
-rw-r--r--src/basic/mount-util.h5
-rw-r--r--src/basic/nss-util.h6
-rw-r--r--src/basic/parse-util.c16
-rw-r--r--src/basic/parse-util.h2
-rw-r--r--src/basic/path-util.c82
-rw-r--r--src/basic/path-util.h19
-rw-r--r--src/basic/proc-cmdline.c147
-rw-r--r--src/basic/proc-cmdline.h33
-rw-r--r--src/basic/process-util.c164
-rw-r--r--src/basic/process-util.h4
-rw-r--r--src/basic/raw-clone.h4
-rw-r--r--src/basic/rlimit-util.c2
-rw-r--r--src/basic/rm-rf.c24
-rw-r--r--src/basic/rm-rf.h2
-rw-r--r--src/basic/socket-util.c101
-rw-r--r--src/basic/socket-util.h5
-rw-r--r--src/basic/special.h1
-rw-r--r--src/basic/stat-util.c40
-rw-r--r--src/basic/stat-util.h1
-rw-r--r--src/basic/string-util.c13
-rw-r--r--src/basic/string-util.h11
-rw-r--r--src/basic/terminal-util.c19
-rw-r--r--src/basic/time-util.c42
-rw-r--r--src/basic/time-util.h17
-rw-r--r--src/basic/unit-name.c4
-rw-r--r--src/basic/user-util.c14
-rw-r--r--src/basic/util.c163
-rw-r--r--src/basic/util.h4
-rw-r--r--src/basic/virt.c107
-rw-r--r--src/boot/bootctl.c210
-rw-r--r--src/boot/efi/boot.c6
-rw-r--r--src/boot/efi/stub.c4
-rw-r--r--src/cgls/cgls.c166
-rw-r--r--src/cgtop/cgtop.c94
-rw-r--r--src/core/automount.c89
-rw-r--r--src/core/busname.c2
-rw-r--r--src/core/cgroup.c94
-rw-r--r--src/core/dbus-execute.c178
-rw-r--r--src/core/dbus-job.c121
-rw-r--r--src/core/dbus-job.h4
-rw-r--r--src/core/dbus-manager.c285
-rw-r--r--src/core/dbus-manager.h2
-rw-r--r--src/core/dbus-service.c23
-rw-r--r--src/core/dbus-unit.c41
-rw-r--r--src/core/dbus.c46
-rw-r--r--src/core/device.c110
-rw-r--r--src/core/device.h3
-rw-r--r--src/core/execute.c997
-rw-r--r--src/core/execute.h32
-rw-r--r--src/core/hostname-setup.c6
-rw-r--r--src/core/ima-setup.c22
-rw-r--r--src/core/job.c311
-rw-r--r--src/core/job.h16
-rw-r--r--src/core/killall.c37
-rw-r--r--src/core/load-dropin.c116
-rw-r--r--src/core/load-dropin.h9
-rw-r--r--src/core/load-fragment-gperf.gperf.m436
-rw-r--r--src/core/load-fragment.c605
-rw-r--r--src/core/load-fragment.h2
-rw-r--r--src/core/locale-setup.c2
-rw-r--r--src/core/machine-id-setup.c12
-rw-r--r--src/core/macros.systemd.in4
-rw-r--r--src/core/main.c218
-rw-r--r--src/core/manager.c386
-rw-r--r--src/core/manager.h12
-rw-r--r--src/core/mount-setup.c36
-rw-r--r--src/core/mount.c325
-rw-r--r--src/core/namespace.c811
-rw-r--r--src/core/namespace.h49
-rw-r--r--src/core/org.freedesktop.systemd1.conf16
-rw-r--r--src/core/scope.c9
-rw-r--r--src/core/service.c126
-rw-r--r--src/core/service.h4
-rw-r--r--src/core/shutdown.c5
-rw-r--r--src/core/socket.c52
-rw-r--r--src/core/swap.c6
-rw-r--r--src/core/target.c5
-rw-r--r--src/core/timer.c8
-rw-r--r--src/core/transaction.c5
-rw-r--r--src/core/triggers.systemd.in22
-rw-r--r--src/core/umount.c52
-rw-r--r--src/core/unit-printf.c63
-rw-r--r--src/core/unit.c156
-rw-r--r--src/core/unit.h5
-rw-r--r--src/coredump/coredump.c560
-rw-r--r--src/coredump/coredumpctl.c349
-rw-r--r--src/coredump/stacktrace.c2
-rw-r--r--src/cryptsetup/cryptsetup-generator.c122
-rw-r--r--src/cryptsetup/cryptsetup.c170
-rw-r--r--src/debug-generator/debug-generator.c75
-rw-r--r--src/delta/delta.c62
l---------src/dissect/Makefile1
-rw-r--r--src/dissect/dissect.c294
l---------src/environment-d-generator/Makefile1
-rw-r--r--src/environment-d-generator/environment-d-generator.c107
-rw-r--r--src/escape/escape.c2
-rw-r--r--src/firstboot/firstboot.c14
-rw-r--r--src/fsck/fsck.c12
-rw-r--r--src/fstab-generator/fstab-generator.c276
-rw-r--r--src/gpt-auto-generator/gpt-auto-generator.c494
-rw-r--r--src/hibernate-resume/hibernate-resume-generator.c27
-rw-r--r--src/hostname/hostnamectl.c23
-rw-r--r--src/hostname/hostnamed.c11
-rw-r--r--src/hwdb/hwdb.c172
-rw-r--r--src/import/curl-util.c2
-rw-r--r--src/import/import-raw.c6
-rw-r--r--src/import/import-tar.c6
-rw-r--r--src/import/importd.c7
-rw-r--r--src/import/pull-common.c133
-rw-r--r--src/import/pull-common.h4
-rw-r--r--src/import/pull-job.c2
-rw-r--r--src/import/pull-raw.c273
-rw-r--r--src/import/pull-raw.h2
-rw-r--r--src/import/pull-tar.c88
-rw-r--r--src/import/pull.c14
-rw-r--r--src/initctl/initctl.c2
-rw-r--r--src/journal-remote/journal-gatewayd.c16
-rw-r--r--src/journal-remote/journal-remote-parse.c433
-rw-r--r--src/journal-remote/journal-remote-parse.h35
-rw-r--r--src/journal-remote/journal-remote-write.c33
-rw-r--r--src/journal-remote/journal-remote-write.h12
-rw-r--r--src/journal-remote/journal-remote.c25
-rw-r--r--src/journal-remote/journal-upload.c6
-rwxr-xr-xsrc/journal-remote/log-generator.py7
-rw-r--r--src/journal-remote/microhttpd-util.h16
-rw-r--r--src/journal/compress.c4
-rw-r--r--src/journal/journal-file.c121
-rw-r--r--src/journal/journalctl.c163
-rw-r--r--src/journal/journald-console.c6
-rw-r--r--src/journal/journald-kmsg.c5
-rw-r--r--src/journal/journald-native.c209
-rw-r--r--src/journal/journald-native.h5
-rw-r--r--src/journal/journald-server.c129
-rw-r--r--src/journal/journald-server.h6
-rw-r--r--src/journal/journald-syslog.c5
-rw-r--r--src/journal/journald-wall.c4
-rw-r--r--src/journal/journald.c10
-rw-r--r--src/journal/lookup3.c4
-rw-r--r--src/journal/sd-journal.c12
-rw-r--r--src/journal/test-compress.c6
-rw-r--r--src/kernel-install/kernel-install12
-rw-r--r--src/libsystemd-network/arp-util.c2
-rw-r--r--src/libsystemd-network/dhcp-internal.h9
-rw-r--r--src/libsystemd-network/dhcp-network.c24
-rw-r--r--src/libsystemd-network/dhcp-packet.c6
-rw-r--r--src/libsystemd-network/dhcp6-option.c2
-rw-r--r--src/libsystemd-network/lldp-network.c21
-rw-r--r--src/libsystemd-network/ndisc-router.c12
-rw-r--r--src/libsystemd-network/network-internal.c34
-rw-r--r--src/libsystemd-network/sd-dhcp-client.c58
-rw-r--r--src/libsystemd-network/sd-dhcp-lease.c24
-rw-r--r--src/libsystemd-network/sd-dhcp-server.c10
-rw-r--r--src/libsystemd-network/sd-dhcp6-lease.c2
-rw-r--r--src/libsystemd-network/sd-ipv4acd.c2
-rw-r--r--src/libsystemd-network/test-dhcp-client.c4
-rw-r--r--src/libsystemd-network/test-lldp.c10
-rw-r--r--src/libsystemd/libsystemd.pc.in2
-rw-r--r--src/libsystemd/libsystemd.sym6
-rw-r--r--src/libsystemd/sd-bus/bus-common-errors.c3
-rw-r--r--src/libsystemd/sd-bus/bus-common-errors.h1
-rw-r--r--src/libsystemd/sd-bus/bus-control.c4
-rw-r--r--src/libsystemd/sd-bus/bus-creds.c2
-rw-r--r--src/libsystemd/sd-bus/bus-dump.c2
-rw-r--r--src/libsystemd/sd-bus/bus-kernel.c20
-rw-r--r--src/libsystemd/sd-bus/bus-socket.c2
-rw-r--r--src/libsystemd/sd-bus/busctl-introspect.c88
-rw-r--r--src/libsystemd/sd-bus/busctl.c4
-rw-r--r--src/libsystemd/sd-bus/sd-bus.c6
-rw-r--r--src/libsystemd/sd-bus/test-bus-chat.c2
-rw-r--r--src/libsystemd/sd-bus/test-bus-creds.c2
-rw-r--r--src/libsystemd/sd-bus/test-bus-objects.c4
-rw-r--r--src/libsystemd/sd-daemon/sd-daemon.c58
-rw-r--r--src/libsystemd/sd-device/device-enumerator.c2
-rw-r--r--src/libsystemd/sd-device/device-internal.h2
-rw-r--r--src/libsystemd/sd-device/sd-device.c49
-rw-r--r--src/libsystemd/sd-event/sd-event.c11
-rw-r--r--src/libsystemd/sd-event/test-event.c3
-rw-r--r--src/libsystemd/sd-hwdb/hwdb-internal.h4
-rw-r--r--src/libsystemd/sd-hwdb/sd-hwdb.c64
-rw-r--r--src/libsystemd/sd-id128/id128-util.c2
-rw-r--r--src/libsystemd/sd-id128/sd-id128.c32
-rw-r--r--src/libsystemd/sd-login/sd-login.c16
-rw-r--r--src/libsystemd/sd-login/test-login.c2
-rw-r--r--src/libsystemd/sd-netlink/netlink-message.c2
-rw-r--r--src/libsystemd/sd-netlink/netlink-socket.c6
-rw-r--r--src/libsystemd/sd-netlink/netlink-types.c29
-rw-r--r--src/libsystemd/sd-netlink/rtnl-message.c2
-rw-r--r--src/libsystemd/sd-netlink/sd-netlink.c4
-rw-r--r--src/libsystemd/sd-network/sd-network.c14
-rw-r--r--src/libsystemd/sd-path/sd-path.c8
-rw-r--r--src/libudev/libudev-monitor.c2
-rw-r--r--src/libudev/libudev-util.c16
-rw-r--r--src/libudev/libudev.c6
-rw-r--r--src/libudev/libudev.pc.in2
-rw-r--r--src/locale/keymap-util.c6
-rw-r--r--src/locale/localectl.c5
-rw-r--r--src/login/inhibit.c2
-rw-r--r--src/login/loginctl.c42
-rw-r--r--src/login/logind-acl.c2
-rw-r--r--src/login/logind-action.c2
-rw-r--r--src/login/logind-button.c14
-rw-r--r--src/login/logind-dbus.c17
-rw-r--r--src/login/logind-inhibit.c9
-rw-r--r--src/login/logind-seat.c17
-rw-r--r--src/login/logind-session.c17
-rw-r--r--src/login/logind-user-dbus.c2
-rw-r--r--src/login/logind-user.c4
-rw-r--r--src/login/logind-utmp.c2
-rw-r--r--src/login/logind.c2
-rw-r--r--src/login/pam_systemd.c4
-rw-r--r--src/login/systemd-user.m48
-rw-r--r--src/machine-id-setup/machine-id-setup-main.c6
-rw-r--r--src/machine/image-dbus.c164
-rw-r--r--src/machine/image-dbus.h1
-rw-r--r--src/machine/machine-dbus.c91
-rw-r--r--src/machine/machine-dbus.h3
-rw-r--r--src/machine/machine.c99
-rw-r--r--src/machine/machine.h2
-rw-r--r--src/machine/machinectl.c178
-rw-r--r--src/machine/machined-dbus.c75
-rw-r--r--src/machine/machined.c2
-rw-r--r--src/machine/operation.c4
-rw-r--r--src/machine/org.freedesktop.machine1.conf16
-rw-r--r--src/modules-load/modules-load.c8
-rw-r--r--src/mount/mount-tool.c107
-rw-r--r--src/network/.gitignore1
-rw-r--r--src/network/netdev/.gitignore1
l---------src/network/netdev/Makefile1
-rw-r--r--src/network/netdev/bond.c (renamed from src/network/networkd-netdev-bond.c)2
-rw-r--r--src/network/netdev/bond.h (renamed from src/network/networkd-netdev-bond.h)2
-rw-r--r--src/network/netdev/bridge.c (renamed from src/network/networkd-netdev-bridge.c)7
-rw-r--r--src/network/netdev/bridge.h (renamed from src/network/networkd-netdev-bridge.h)2
-rw-r--r--src/network/netdev/dummy.c (renamed from src/network/networkd-netdev-dummy.c)2
-rw-r--r--src/network/netdev/dummy.h (renamed from src/network/networkd-netdev-dummy.h)2
-rw-r--r--src/network/netdev/ipvlan.c (renamed from src/network/networkd-netdev-ipvlan.c)2
-rw-r--r--src/network/netdev/ipvlan.h (renamed from src/network/networkd-netdev-ipvlan.h)2
-rw-r--r--src/network/netdev/macvlan.c (renamed from src/network/networkd-netdev-macvlan.c)2
-rw-r--r--src/network/netdev/macvlan.h (renamed from src/network/networkd-netdev-macvlan.h)2
-rw-r--r--src/network/netdev/netdev-gperf.gperf121
-rw-r--r--src/network/netdev/netdev.c (renamed from src/network/networkd-netdev.c)25
-rw-r--r--src/network/netdev/netdev.h (renamed from src/network/networkd-netdev.h)0
-rw-r--r--src/network/netdev/tunnel.c (renamed from src/network/networkd-netdev-tunnel.c)72
-rw-r--r--src/network/netdev/tunnel.h (renamed from src/network/networkd-netdev-tunnel.h)2
-rw-r--r--src/network/netdev/tuntap.c (renamed from src/network/networkd-netdev-tuntap.c)2
-rw-r--r--src/network/netdev/tuntap.h (renamed from src/network/networkd-netdev-tuntap.h)2
-rw-r--r--src/network/netdev/vcan.c (renamed from src/network/networkd-netdev-vcan.c)2
-rw-r--r--src/network/netdev/vcan.h (renamed from src/network/networkd-netdev-vcan.h)2
-rw-r--r--src/network/netdev/veth.c (renamed from src/network/networkd-netdev-veth.c)2
-rw-r--r--src/network/netdev/veth.h (renamed from src/network/networkd-netdev-veth.h)2
-rw-r--r--src/network/netdev/vlan.c (renamed from src/network/networkd-netdev-vlan.c)2
-rw-r--r--src/network/netdev/vlan.h (renamed from src/network/networkd-netdev-vlan.h)2
-rw-r--r--src/network/netdev/vrf.c (renamed from src/network/networkd-netdev-vrf.c)2
-rw-r--r--src/network/netdev/vrf.h (renamed from src/network/networkd-netdev-vrf.h)2
-rw-r--r--src/network/netdev/vxlan.c (renamed from src/network/networkd-netdev-vxlan.c)76
-rw-r--r--src/network/netdev/vxlan.h (renamed from src/network/networkd-netdev-vxlan.h)29
-rw-r--r--src/network/networkd-address-pool.c2
-rw-r--r--src/network/networkd-address.c48
-rw-r--r--src/network/networkd-address.h5
-rw-r--r--src/network/networkd-brvlan.c4
-rw-r--r--src/network/networkd-conf.c2
-rw-r--r--src/network/networkd-conf.h2
-rw-r--r--src/network/networkd-dhcp4.c85
-rw-r--r--src/network/networkd-dhcp6.c4
-rw-r--r--src/network/networkd-fdb.c3
-rw-r--r--src/network/networkd-gperf.gperf1
-rw-r--r--src/network/networkd-ipv4ll.c5
-rw-r--r--src/network/networkd-ipv6-proxy-ndp.c209
-rw-r--r--src/network/networkd-ipv6-proxy-ndp.h44
-rw-r--r--src/network/networkd-link-bus.c2
-rw-r--r--src/network/networkd-link.c247
-rw-r--r--src/network/networkd-link.h5
-rw-r--r--src/network/networkd-lldp-tx.c2
-rw-r--r--src/network/networkd-manager-bus.c2
-rw-r--r--src/network/networkd-manager.c218
-rw-r--r--src/network/networkd-manager.h (renamed from src/network/networkd.h)22
-rw-r--r--src/network/networkd-ndisc.c51
-rw-r--r--src/network/networkd-netdev-gperf.gperf118
-rw-r--r--src/network/networkd-network-bus.c2
-rw-r--r--src/network/networkd-network-gperf.gperf11
-rw-r--r--src/network/networkd-network.c147
-rw-r--r--src/network/networkd-network.h44
-rw-r--r--src/network/networkd-route.c55
-rw-r--r--src/network/networkd-route.h6
-rw-r--r--src/network/networkd.c25
-rw-r--r--src/network/systemd-networkd.pkla4
-rw-r--r--src/network/systemd-networkd.rules8
-rw-r--r--src/network/test-network-tables.c8
-rw-r--r--src/network/test-network.c13
l---------src/network/wait-online/Makefile1
-rw-r--r--src/network/wait-online/link.c (renamed from src/network/networkd-wait-online-link.c)4
-rw-r--r--src/network/wait-online/link.h (renamed from src/network/networkd-wait-online-link.h)5
-rw-r--r--src/network/wait-online/manager.c (renamed from src/network/networkd-wait-online-manager.c)4
-rw-r--r--src/network/wait-online/manager.h (renamed from src/network/networkd-wait-online.h)3
-rw-r--r--src/network/wait-online/wait-online.c (renamed from src/network/networkd-wait-online.c)2
-rw-r--r--src/notify/notify.c2
-rw-r--r--src/nspawn/nspawn-cgroup.c68
-rw-r--r--src/nspawn/nspawn-expose-ports.c10
-rw-r--r--src/nspawn/nspawn-gperf.gperf3
-rw-r--r--src/nspawn/nspawn-mount.c507
-rw-r--r--src/nspawn/nspawn-mount.h30
-rw-r--r--src/nspawn/nspawn-patch-uid.c2
-rw-r--r--src/nspawn/nspawn-register.c5
-rw-r--r--src/nspawn/nspawn-seccomp.c113
-rw-r--r--src/nspawn/nspawn-settings.c56
-rw-r--r--src/nspawn/nspawn-settings.h7
-rw-r--r--src/nspawn/nspawn-stub-pid1.c29
-rw-r--r--src/nspawn/nspawn-stub-pid1.h4
-rw-r--r--src/nspawn/nspawn.c1325
-rw-r--r--src/nss-myhostname/nss-myhostname.c19
-rw-r--r--src/nss-mymachines/nss-mymachines.c30
-rw-r--r--src/nss-resolve/nss-resolve.c104
-rw-r--r--src/nss-systemd/nss-systemd.c42
-rw-r--r--src/quotacheck/quotacheck.c15
-rw-r--r--src/rc-local-generator/rc-local-generator.c4
-rw-r--r--src/remount-fs/remount-fs.c2
-rw-r--r--src/reply-password/reply-password.c2
-rw-r--r--src/resolve/resolve-tool.c26
-rw-r--r--src/resolve/resolved-bus.c8
-rw-r--r--src/resolve/resolved-dns-answer.c2
-rw-r--r--src/resolve/resolved-dns-answer.h8
-rw-r--r--src/resolve/resolved-dns-cache.c133
-rw-r--r--src/resolve/resolved-dns-dnssec.c10
-rw-r--r--src/resolve/resolved-dns-packet.c38
-rw-r--r--src/resolve/resolved-dns-packet.h12
-rw-r--r--src/resolve/resolved-dns-query.c22
-rw-r--r--src/resolve/resolved-dns-query.h5
-rw-r--r--src/resolve/resolved-dns-rr.c16
-rw-r--r--src/resolve/resolved-dns-scope.c106
-rw-r--r--src/resolve/resolved-dns-scope.h6
-rw-r--r--src/resolve/resolved-dns-server.c62
-rw-r--r--src/resolve/resolved-dns-server.h4
-rw-r--r--src/resolve/resolved-dns-stub.c163
-rw-r--r--src/resolve/resolved-dns-transaction.c94
-rw-r--r--src/resolve/resolved-dns-transaction.h16
-rw-r--r--src/resolve/resolved-dns-trust-anchor.c99
-rw-r--r--src/resolve/resolved-dns-zone.c1
-rw-r--r--src/resolve/resolved-dns-zone.h3
-rw-r--r--src/resolve/resolved-etc-hosts.c6
-rw-r--r--src/resolve/resolved-gperf.gperf1
-rw-r--r--src/resolve/resolved-link-bus.c2
-rw-r--r--src/resolve/resolved-link.c213
-rw-r--r--src/resolve/resolved-link.h3
-rw-r--r--src/resolve/resolved-llmnr.c194
-rw-r--r--src/resolve/resolved-manager.c133
-rw-r--r--src/resolve/resolved-manager.h3
-rw-r--r--src/resolve/resolved-mdns.c174
-rw-r--r--src/resolve/resolved-mdns.h1
-rw-r--r--src/resolve/resolved-resolv-conf.c8
-rw-r--r--src/resolve/resolved.c4
-rw-r--r--src/resolve/resolved.conf.in1
-rw-r--r--src/resolve/test-dns-packet.c3
-rw-r--r--src/resolve/test-dnssec-complex.c2
-rw-r--r--src/resolve/test-resolved-packet.c45
-rw-r--r--src/rfkill/rfkill.c4
-rw-r--r--src/run/run.c86
-rw-r--r--src/shared/acl-util.c2
-rw-r--r--src/shared/ask-password-api.c12
-rw-r--r--src/shared/base-filesystem.c4
-rw-r--r--src/shared/bus-unit-util.c134
-rw-r--r--src/shared/bus-util.c56
-rw-r--r--src/shared/bus-util.h8
-rw-r--r--src/shared/cgroup-show.c90
-rw-r--r--src/shared/cgroup-show.h11
-rw-r--r--src/shared/clean-ipc.c6
-rw-r--r--src/shared/condition.c5
-rw-r--r--src/shared/conf-parser.c6
-rw-r--r--src/shared/dissect-image.c1177
-rw-r--r--src/shared/dissect-image.h98
-rw-r--r--src/shared/dns-domain.c16
-rw-r--r--src/shared/dns-domain.h2
-rw-r--r--src/shared/dropin.c129
-rw-r--r--src/shared/dropin.h37
-rw-r--r--src/shared/fdset.c7
-rw-r--r--src/shared/firewall-util.c10
-rw-r--r--src/shared/fstab-util.c6
-rw-r--r--src/shared/generator.c2
-rw-r--r--src/shared/gpt.h19
-rw-r--r--src/shared/install-printf.c10
-rw-r--r--src/shared/install.c246
-rw-r--r--src/shared/journal-util.c151
-rw-r--r--src/shared/journal-util.h25
-rw-r--r--src/shared/logs-show.c25
-rw-r--r--src/shared/loop-util.c166
-rw-r--r--src/shared/loop-util.h41
-rw-r--r--src/shared/machine-image.c98
-rw-r--r--src/shared/machine-pool.c2
-rw-r--r--src/shared/nsflags.c120
-rw-r--r--src/shared/nsflags.h49
-rw-r--r--src/shared/pager.c10
-rw-r--r--src/shared/path-lookup.c74
-rw-r--r--src/shared/ptyfwd.c30
-rw-r--r--src/shared/ptyfwd.h2
-rw-r--r--src/shared/seccomp-util.c975
-rw-r--r--src/shared/seccomp-util.h56
-rw-r--r--src/shared/switch-root.c139
-rw-r--r--src/shared/tests.c40
-rw-r--r--src/shared/tests.h1
-rw-r--r--src/shared/volatile-util.c68
-rw-r--r--src/shared/volatile-util.h32
-rw-r--r--src/sleep/sleep.c9
-rw-r--r--src/socket-proxy/socket-proxyd.c29
-rw-r--r--src/stdio-bridge/stdio-bridge.c4
-rw-r--r--src/system-update-generator/system-update-generator.c31
-rw-r--r--src/systemctl/systemctl.c333
-rw-r--r--src/systemd/_sd-common.h4
-rw-r--r--src/systemd/sd-bus-vtable.h58
-rw-r--r--src/systemd/sd-daemon.h13
-rw-r--r--src/systemd/sd-dhcp-client.h3
-rw-r--r--src/systemd/sd-id128.h5
-rw-r--r--src/systemd/sd-messages.h156
-rw-r--r--src/sysusers/sysusers.c4
-rw-r--r--src/sysv-generator/sysv-generator.c20
-rw-r--r--src/test/test-af-list.c1
-rw-r--r--src/test/test-arphrd-list.c1
-rw-r--r--src/test/test-calendarspec.c52
-rw-r--r--src/test/test-cgroup-mask.c6
-rw-r--r--src/test/test-cgroup-util.c49
-rw-r--r--src/test/test-conf-files.c24
-rw-r--r--src/test/test-conf-parser.c4
-rw-r--r--src/test/test-copy.c39
-rw-r--r--src/test/test-date.c14
-rw-r--r--src/test/test-dissect-image.c66
-rw-r--r--src/test/test-dns-domain.c21
-rw-r--r--src/test/test-engine.c5
-rw-r--r--src/test/test-env-util.c127
-rw-r--r--src/test/test-exec-util.c348
-rw-r--r--src/test/test-execute.c92
-rw-r--r--src/test/test-fd-util.c10
-rw-r--r--src/test/test-fileio.c114
-rw-r--r--src/test/test-fs-util.c122
-rw-r--r--src/test/test-hash.c82
-rw-r--r--src/test/test-hexdecoct.c18
-rw-r--r--src/test/test-id128.c6
-rw-r--r--src/test/test-install-root.c26
-rw-r--r--src/test/test-ipcrm.c10
-rw-r--r--src/test/test-journal-importer.c90
-rw-r--r--src/test/test-log.c2
-rw-r--r--src/test/test-loopback.c2
-rw-r--r--src/test/test-mount-util.c57
-rw-r--r--src/test/test-namespace.c8
-rw-r--r--src/test/test-ns.c3
-rw-r--r--src/test/test-nss.c192
-rw-r--r--src/test/test-path-util.c60
-rw-r--r--src/test/test-path.c4
-rw-r--r--src/test/test-proc-cmdline.c96
-rw-r--r--src/test/test-process-util.c70
-rw-r--r--src/test/test-replace-var.c2
-rw-r--r--src/test/test-sched-prio.c5
-rw-r--r--src/test/test-seccomp.c389
-rw-r--r--src/test/test-selinux.c8
-rw-r--r--src/test/test-socket-util.c45
-rw-r--r--src/test/test-stat-util.c32
-rw-r--r--src/test/test-string-util.c61
-rw-r--r--src/test/test-time.c32
-rw-r--r--src/test/test-tmpfiles.c2
-rw-r--r--src/test/test-util.c45
-rw-r--r--src/timedate/timedatectl.c5
-rw-r--r--src/timedate/timedated.c4
-rw-r--r--src/timesync/timesyncd-conf.c10
-rw-r--r--src/timesync/timesyncd-conf.h1
-rw-r--r--src/timesync/timesyncd-manager.c16
-rw-r--r--src/timesync/timesyncd-manager.h2
-rw-r--r--src/timesync/timesyncd.c6
-rw-r--r--src/tmpfiles/tmpfiles.c37
-rw-r--r--src/tty-ask-password-agent/tty-ask-password-agent.c4
-rw-r--r--src/udev/net/ethtool-util.c209
-rw-r--r--src/udev/net/ethtool-util.h18
-rw-r--r--src/udev/net/link-config-gperf.gperf1
-rw-r--r--src/udev/net/link-config.c39
-rw-r--r--src/udev/net/link-config.h1
-rw-r--r--src/udev/udev-builtin-blkid.c4
-rw-r--r--src/udev/udev-builtin-hwdb.c2
-rw-r--r--src/udev/udev-builtin-input_id.c3
-rw-r--r--src/udev/udev-builtin-net_id.c62
-rw-r--r--src/udev/udev-builtin-path_id.c9
-rw-r--r--src/udev/udev-ctrl.c2
-rw-r--r--src/udev/udev-event.c424
-rw-r--r--src/udev/udev-node.c11
-rw-r--r--src/udev/udev-rules.c46
-rw-r--r--src/udev/udev-watch.c4
-rw-r--r--src/udev/udev.h4
-rw-r--r--src/udev/udevadm-hwdb.c2
-rw-r--r--src/udev/udevadm-info.c4
-rw-r--r--src/udev/udevadm-monitor.c6
-rw-r--r--src/udev/udevadm-test.c2
-rw-r--r--src/udev/udevd.c47
-rw-r--r--src/update-done/update-done.c2
-rw-r--r--src/update-utmp/update-utmp.c2
-rw-r--r--src/vconsole/vconsole-setup.c28
l---------src/veritysetup/Makefile1
-rw-r--r--src/veritysetup/veritysetup-generator.c253
-rw-r--r--src/veritysetup/veritysetup.c154
l---------src/volatile-root/Makefile1
-rw-r--r--src/volatile-root/volatile-root.c157
-rw-r--r--sysctl.d/50-default.conf3
-rw-r--r--system-preset/90-systemd.preset1
-rwxr-xr-xtest/TEST-03-JOBS/test-jobs.sh2
-rwxr-xr-xtest/TEST-13-NSPAWN-SMOKE/test.sh59
-rw-r--r--test/TEST-14-MACHINE-ID/Makefile10
-rwxr-xr-xtest/TEST-14-MACHINE-ID/test.sh119
l---------test/TEST-15-DROPIN/Makefile1
-rwxr-xr-xtest/TEST-15-DROPIN/test-dropin.sh274
-rwxr-xr-xtest/TEST-15-DROPIN/test.sh46
-rw-r--r--test/TEST-15-DROPIN/testsuite.service7
-rwxr-xr-xtest/create-sys-script.py183
-rwxr-xr-xtest/hwdb-test.sh72
-rw-r--r--test/hwdb/10-bad.hwdb26
-rw-r--r--test/journal-data/journal-1.txtbin0 -> 586 bytes
-rw-r--r--test/journal-data/journal-2.txtbin0 -> 513 bytes
-rwxr-xr-xtest/networkd-test.py494
-rwxr-xr-x[-rw-r--r--]test/rule-syntax-check.py9
-rwxr-xr-xtest/sys-script.py16861
-rw-r--r--test/sys.tar.xzbin165116 -> 0 bytes
-rwxr-xr-xtest/sysv-generator-test.py4
-rw-r--r--test/test-execute/exec-privatedevices-no.service2
-rw-r--r--test/test-execute/exec-privatedevices-yes.service2
-rw-r--r--test/test-execute/exec-read-only-path-succeed.service8
-rw-r--r--test/test-execute/exec-restrict-namespaces-mnt-blacklist.service7
-rw-r--r--test/test-execute/exec-restrict-namespaces-mnt.service7
-rw-r--r--test/test-execute/exec-restrict-namespaces-no.service7
-rw-r--r--test/test-execute/exec-restrict-namespaces-yes.service7
-rw-r--r--test/test-functions54
-rw-r--r--test/test-resolve/_443._tcp.fedoraproject.org.pkts (renamed from src/resolve/test-data/_443._tcp.fedoraproject.org.pkts)bin169 -> 169 bytes
-rw-r--r--test/test-resolve/_openpgpkey.fedoraproject.org.pkts (renamed from src/resolve/test-data/_openpgpkey.fedoraproject.org.pkts)bin986 -> 986 bytes
-rw-r--r--test/test-resolve/fake-caa.pkts (renamed from src/resolve/test-data/fake-caa.pkts)bin196 -> 196 bytes
-rw-r--r--test/test-resolve/fedoraproject.org.pkts (renamed from src/resolve/test-data/fedoraproject.org.pkts)bin1483 -> 1483 bytes
-rw-r--r--test/test-resolve/gandi.net.pkts (renamed from src/resolve/test-data/gandi.net.pkts)bin1010 -> 1010 bytes
-rw-r--r--test/test-resolve/google.com.pkts (renamed from src/resolve/test-data/google.com.pkts)bin747 -> 747 bytes
-rw-r--r--test/test-resolve/kyhwana.org.pkts (renamed from src/resolve/test-data/kyhwana.org.pkts)bin1803 -> 1803 bytes
-rw-r--r--test/test-resolve/root.pkts (renamed from src/resolve/test-data/root.pkts)bin1061 -> 1061 bytes
-rw-r--r--test/test-resolve/sw1a1aa-sw1a2aa-sw1a2ab-sw1a2ac.find.me.uk.pkts (renamed from src/resolve/test-data/sw1a1aa-sw1a2aa-sw1a2ab-sw1a2ac.find.me.uk.pkts)bin330 -> 330 bytes
-rw-r--r--test/test-resolve/teamits.com.pkts (renamed from src/resolve/test-data/teamits.com.pkts)bin1021 -> 1021 bytes
-rw-r--r--test/test-resolve/zbyszek@fedoraproject.org.pkts (renamed from src/resolve/test-data/zbyszek@fedoraproject.org.pkts)bin2533 -> 2533 bytes
-rwxr-xr-xtest/udev-test.pl80
-rw-r--r--tmpfiles.d/systemd.conf.m412
-rw-r--r--tmpfiles.d/tmp.conf4
-rw-r--r--tools/catalog-report.py87
-rw-r--r--tools/gdb-sd_dump_hashmaps.py1
-rwxr-xr-xtools/make-directive-index.py1
-rwxr-xr-xtools/make-man-index.py1
-rw-r--r--tools/make-man-rules.py1
-rw-r--r--tools/xml_helper.py1
-rw-r--r--units/.gitignore2
-rw-r--r--units/initrd-switch-root.service.in4
-rw-r--r--units/sys-fs-fuse-connections.mount1
-rw-r--r--units/system-update-cleanup.service.in32
-rw-r--r--units/system-update.target5
-rw-r--r--units/systemd-journal-catalog-update.service.in2
-rw-r--r--units/systemd-networkd.service.m4.in11
-rw-r--r--units/systemd-nspawn@.service.in9
-rw-r--r--units/systemd-resolved.service.m4.in3
-rw-r--r--units/systemd-vconsole-setup.service.in1
-rw-r--r--units/systemd-volatile-root.service.in21
782 files changed, 50727 insertions, 12326 deletions
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 8a6db1f629..abee9cc740 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -18,7 +18,7 @@ Following these guidelines makes it easier for us to process your issue, and ens
* Please make sure to test your change before submitting the PR. See [HACKING](https://raw.githubusercontent.com/systemd/systemd/master/HACKING) for details how to do this.
* Make sure to run "make check" locally, before posting your PR. We use a CI system, meaning we don't even look at your PR, if the build and tests don't pass.
* If you need to update the code in an existing PR, force-push into the same branch, overriding old commits with new versions.
-* After you have pushed a new version, try to remove the `reviewed/needs-rework` label. Also add a comment about the new version (no notification is sent just for the commits, so it's easy to miss the update without an explicit comment).
+* After you have pushed a new version, add a comment about the new version (no notification is sent just for the commits, so it's easy to miss the update without an explicit comment). If you are a member of the systemd project on github, remove the `reviewed/needs-rework` label.
## Final Words
diff --git a/.gitignore b/.gitignore
index 21fcf9841c..25b976a0e3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,6 +19,7 @@
/*.tar.bz2
/*.tar.gz
/*.tar.xz
+/30-systemd-environment-d-generator
/GPATH
/GRTAGS
/GSYMS
@@ -67,6 +68,7 @@
/systemd-debug-generator
/systemd-delta
/systemd-detect-virt
+/systemd-dissect
/systemd-escape
/systemd-export
/systemd-firstboot
@@ -125,6 +127,9 @@
/systemd-update-utmp
/systemd-user-sessions
/systemd-vconsole-setup
+/systemd-veritysetup
+/systemd-veritysetup-generator
+/systemd-volatile-root
/tags
/test-acd
/test-acl-util
@@ -180,6 +185,7 @@
/test-dhcp-option
/test-dhcp-server
/test-dhcp6-client
+/test-dissect-image
/test-dns-domain
/test-dns-packet
/test-dnssec
@@ -189,6 +195,7 @@
/test-env-util
/test-escape
/test-event
+/test-exec-util
/test-execute
/test-extract-word
/test-fd-util
@@ -198,6 +205,7 @@
/test-fs-util
/test-fstab-util
/test-glob-util
+/test-hash
/test-hashmap
/test-hexdecoct
/test-hostname
@@ -214,6 +222,7 @@
/test-journal
/test-journal-enum
/test-journal-flush
+/test-journal-importer
/test-journal-init
/test-journal-interleaving
/test-journal-match
@@ -236,6 +245,7 @@
/test-loopback
/test-machine-tables
/test-mmap-cache
+/test-mount-util
/test-namespace
/test-ndisc-rs
/test-netlink
@@ -259,6 +269,7 @@
/test-replace-var
/test-resolve
/test-resolve-tables
+/test-resolved-packet
/test-ring
/test-rlimit-util
/test-sched-prio
diff --git a/.mailmap b/.mailmap
index d007ba741e..d46c166cf9 100644
--- a/.mailmap
+++ b/.mailmap
@@ -89,3 +89,16 @@ Eric Cook <llua@users.noreply.github.com>
Lukáš Nykrýn <lnykryn@redhat.com>
Heikki Kemppainen <heikki.kemppainen@nokia.com>
Hendrik Brueckner <hbrueckner@users.noreply.github.com>
+Alexandros Frantzis <alexandros.frantzis@canonical.com>
+Alexander Kochetkov <al.kochet@gmail.com>
+Fionn Cleary <clearyf@tcd.ie>
+Michel Kraus <github@demonsphere.de> <27o@users.noreply.github.com>
+Charles (Chas) Williams <ciwillia@brocade.com>
+Emil Soleyman <emil@soleyman.com>
+Dmitry Khlebnikov <dmitry.khlebnikov@rea-group.com> <galaxy4public@users.noreply.github.com>
+Antoine Eiche <lewo@abesis.fr>
+Gianluca Boiano <morf3089@gmail.com>
+Paolo Giangrandi <paolo@luccalug.it>
+Karl Kraus <karl.kraus@tum.de> <laqueray@gmail.com>
+Tibor Nagy <xnagytibor@gmail.com>
+Stuart McLaren <stuart.mclaren@hp.com>
diff --git a/.mkosi/Makefile b/.mkosi/Makefile
new file mode 120000
index 0000000000..bd1047548b
--- /dev/null
+++ b/.mkosi/Makefile
@@ -0,0 +1 @@
+../src/Makefile \ No newline at end of file
diff --git a/.mkosi/mkosi.debian b/.mkosi/mkosi.debian
new file mode 100644
index 0000000000..a68d9dfa11
--- /dev/null
+++ b/.mkosi/mkosi.debian
@@ -0,0 +1,82 @@
+# This file is part of systemd.
+#
+# Copyright 2016 Daniel Rusek
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+# This is a settings file for OS image generation using mkosi (https://github.com/systemd/mkosi).
+# Simply invoke "mkosi" in the project directory to build an OS image.
+
+[Distribution]
+Distribution=debian
+Release=unstable
+
+[Output]
+Format=raw_btrfs
+Bootable=yes
+
+[Partitions]
+RootSize=2G
+
+[Packages]
+BuildPackages=
+ acl
+ autoconf
+ automake
+ diffutils
+ docbook-xml
+ docbook-xsl
+ gcc
+ git
+ gnu-efi
+ gperf
+ intltool
+ iptables-dev
+ libacl1-dev
+ libaudit-dev
+ libblkid-dev
+ libbz2-dev
+ libcap-dev
+ libcryptsetup-dev
+ libcurl4-gnutls-dev
+ libdbus-1-dev
+ libdw-dev
+ libfdisk-dev
+ libgcrypt20-dev
+ libgnutls28-dev
+ libidn11-dev
+ libkmod-dev
+ liblzma-dev
+ liblz4-dev
+ liblz4-tool
+ libmicrohttpd-dev
+ libmount-dev
+ libpam0g-dev
+ libqrencode-dev
+ libseccomp-dev
+ libsmartcols-dev
+ libtool
+ libxkbcommon-dev
+ make
+ pkg-config
+ python3
+ python3-lxml
+ tree
+ uuid-dev
+ xsltproc
+ xz-utils
+
+Packages=
+ libqrencode3
+ locales
diff --git a/.mkosi/mkosi.fedora b/.mkosi/mkosi.fedora
index 0af20c924a..1b8dd47ca4 100644
--- a/.mkosi/mkosi.fedora
+++ b/.mkosi/mkosi.fedora
@@ -27,7 +27,7 @@ Format=raw_btrfs
Bootable=yes
[Partitions]
-RootSize=2G
+RootSize=3G
[Packages]
BuildPackages=
@@ -37,6 +37,7 @@ BuildPackages=
bzip2-devel
cryptsetup-devel
dbus-devel
+ diffutils
docbook-style-xsl
elfutils-devel
gcc
@@ -68,4 +69,5 @@ BuildPackages=
python3-devel
python3-lxml
qrencode-devel
+ tree
xz-devel
diff --git a/CODING_STYLE b/CODING_STYLE
index e89b3c67e5..ed61ea9d28 100644
--- a/CODING_STYLE
+++ b/CODING_STYLE
@@ -429,3 +429,8 @@
and Linux/GNU-specific APIs, we generally prefer the POSIX APIs. If there
aren't, we are happy to use GNU or Linux APIs, and expect non-GNU
implementations of libc to catch up with glibc.
+
+- Whenever installing a signal handler, make sure to set SA_RESTART for it, so
+ that interrupted system calls are automatically restarted, and we minimize
+ hassles with handling EINTR (in particular as EINTR handling is pretty broken
+ on Linux).
diff --git a/DISTRO_PORTING b/DISTRO_PORTING
index 51a244389d..68107e46c9 100644
--- a/DISTRO_PORTING
+++ b/DISTRO_PORTING
@@ -25,21 +25,19 @@ HOWTO:
NTP POOL:
- By default, timesyncd uses the Google NTP servers
- time[1-4].google.com. They serve time that is not standards
- compliant, and can be up to .5s off. Google does not
- officially support these servers for the broader
- audience. Distributions and vendors really should not ship
- OSes or devices with these NTP servers configured. Instead,
- please register your own vendor pool at ntp.org and make it
- the built-in default by passing --with-ntp-servers= to
- configure. Registering vendor pools is free:
+ By default, timesyncd uses the Google Public NTP servers
+ time[1-4].google.com. They serve time that uses a leap second
+ smear, and can be up to .5s off from servers that use stepped
+ leap seconds.
- http://www.pool.ntp.org/en/vendors.html
+ https://developers.google.com/time/smear
+
+ If you prefer to use leap second steps, please register your own
+ vendor pool at ntp.org and make it the built-in default by
+ passing --with-ntp-servers= to configure. Registering vendor
+ pools is free:
- Again, if you ship your software or device with the default
- NTP servers, then you will get served wrong time, and will
- rely on services that might not be supported for long.
+ http://www.pool.ntp.org/en/vendors.html
PAM:
The default PAM config shipped by systemd is really bare bones.
diff --git a/ENVIRONMENT.md b/ENVIRONMENT.md
new file mode 100644
index 0000000000..e542d4ec6f
--- /dev/null
+++ b/ENVIRONMENT.md
@@ -0,0 +1,66 @@
+# Known Environment Variables
+
+A number of systemd components take additional runtime parameters via
+environment variables. Many of these environment variables are not supported at
+the same level as command line switches and other interfaces are: we don't
+document them in the man pages and we make no stability guarantees for
+them. While they generally are unlikely to be dropped any time soon again, we
+do not want to guarantee that they stay around for good either.
+
+Below is an (incomprehensive) list of the environment variables understood by
+the various tools. Note that this list only covers environment variables not
+documented in the proper man pages.
+
+All tools:
+
+* `$SYSTEMD_IGNORE_CHROOT=1` — if set, don't check whether being invoked in a
+ chroot() environment. This is particularly relevant for systemctl, as it will
+ not alter its behaviour for chroot() environments if set. (Normally it
+ refrains from talking to PID 1 in such a case.)
+
+* `$SD_EVENT_PROFILE_DELAYS=1` — if set, the sd-event event loop implementation
+ will print latency information at runtime.
+
+* `$SYSTEMD_PROC_CMDLINE` — if set, may contain a string that is used as kernel
+ command line instead of the actual one readable from /proc/cmdline. This is
+ useful for debugging, in order to test generators and other code against
+ specific kernel command lines.
+
+systemctl:
+
+* `$SYSTEMCTL_FORCE_BUS=1` — if set, do not connect to PID1's private D-Bus
+ listener, and instead always connect through the dbus-daemon D-bus broker.
+
+* `$SYSTEMCTL_INSTALL_CLIENT_SIDE=1` — if set, enable or disable unit files on
+ the client side, instead of asking PID 1 to do this.
+
+* `$SYSTEMCTL_SKIP_SYSV=1` — if set, do not call out to SysV compatibility hooks.
+
+systemd-nspawn:
+
+* `$UNIFIED_CGROUP_HIERARCHY=1` — if set, force nspawn into unified cgroup
+ hierarchy mode.
+
+* `$SYSTEMD_NSPAWN_API_VFS_WRITABLE=1` — if set, make /sys and /proc/sys and
+ friends writable in the container. If set to "network", leave only
+ /proc/sys/net writable.
+
+* `$SYSTEMD_NSPAWN_CONTAINER_SERVICE=…` — override the "service" name nspawn
+ uses to register with machined. If unset defaults to "nspawn", but with this
+ variable may be set to any other value.
+
+* `$SYSTEMD_NSPAWN_USE_CGNS=0` — if set, do not use cgroup namespacing, even if
+ it is available.
+
+* `$SYSTEMD_NSPAWN_LOCK=0` — if set, do not lock container images when running.
+
+systemd-logind:
+
+* `$SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1` — if set, report that
+ hibernation is available even if the swap devices do not provide enough room
+ for it.
+
+installed systemd tests:
+
+* `$SYSTEMD_TEST_DATA` — override the location of test data. This is useful if
+ a test executable is moved to an arbitrary location.
diff --git a/HACKING b/HACKING
index 3ee1c7e340..0d1a93e211 100644
--- a/HACKING
+++ b/HACKING
@@ -51,12 +51,14 @@ systemd's build dependencies:
Putting this all together, here's a series of commands for preparing a patch
for systemd (this example is for Fedora):
+ $ sudo dnf builddep systemd # install build dependencies
+ $ sudo dnf install mkosi # install tool to quickly build images
$ git clone https://github.com/systemd/systemd.git
$ cd systemd
$ vim src/core/main.c # or wherever you'd like to make your changes
- $ dnf builddep systemd # install build dependencies
$ ./autogen.sh c # configure the source tree
$ make -j `nproc` # build it locally, see if everything compiles fine
+ $ make -j `nproc` check # run some simple regression tests
$ sudo mkosi # build a test image
$ sudo systemd-nspawn -bi image.raw # boot up the test image
$ git add -p # interactively put together your patch
diff --git a/Makefile-man.am b/Makefile-man.am
index 013e0d7967..d5626411a5 100644
--- a/Makefile-man.am
+++ b/Makefile-man.am
@@ -11,6 +11,7 @@ MANPAGES += \
man/bootup.7 \
man/busctl.1 \
man/daemon.7 \
+ man/environment.d.5 \
man/file-hierarchy.7 \
man/halt.8 \
man/hostname.5 \
@@ -110,6 +111,7 @@ MANPAGES += \
man/systemd-debug-generator.8 \
man/systemd-delta.1 \
man/systemd-detect-virt.1 \
+ man/systemd-environment-d-generator.8 \
man/systemd-escape.1 \
man/systemd-fsck@.service.8 \
man/systemd-fstab-generator.8 \
@@ -142,9 +144,11 @@ MANPAGES += \
man/systemd-tty-ask-password-agent.1 \
man/systemd-udevd.service.8 \
man/systemd-update-done.service.8 \
+ man/systemd-volatile-root.service.8 \
man/systemd.1 \
man/systemd.automount.5 \
man/systemd.device.5 \
+ man/systemd.environment-generator.7 \
man/systemd.exec.5 \
man/systemd.generator.7 \
man/systemd.journal-fields.7 \
@@ -183,6 +187,7 @@ MANPAGES += \
man/udev_new.3 \
man/udevadm.8
MANPAGES_ALIAS += \
+ man/30-systemd-environment-d-generator.8 \
man/SD_ALERT.3 \
man/SD_BUS_ERROR_ACCESS_DENIED.3 \
man/SD_BUS_ERROR_ADDRESS_IN_USE.3 \
@@ -239,6 +244,7 @@ MANPAGES_ALIAS += \
man/SD_ID128_FORMAT_STR.3 \
man/SD_ID128_FORMAT_VAL.3 \
man/SD_ID128_MAKE.3 \
+ man/SD_ID128_MAKE_STR.3 \
man/SD_ID128_NULL.3 \
man/SD_INFO.3 \
man/SD_JOURNAL_APPEND.3 \
@@ -397,11 +403,13 @@ MANPAGES_ALIAS += \
man/sd_id128_from_string.3 \
man/sd_id128_get_boot.3 \
man/sd_id128_get_invocation.3 \
+ man/sd_id128_get_machine_app_specific.3 \
man/sd_id128_is_null.3 \
man/sd_id128_t.3 \
man/sd_is_mq.3 \
man/sd_is_socket.3 \
man/sd_is_socket_inet.3 \
+ man/sd_is_socket_sockaddr.3 \
man/sd_is_socket_unix.3 \
man/sd_is_special.3 \
man/sd_journal.3 \
@@ -478,8 +486,10 @@ MANPAGES_ALIAS += \
man/systemd-udevd-control.socket.8 \
man/systemd-udevd-kernel.socket.8 \
man/systemd-udevd.8 \
+ man/systemd-umount.1 \
man/systemd-update-done.8 \
man/systemd-user.conf.5 \
+ man/systemd-volatile-root.8 \
man/udev_device_get_action.3 \
man/udev_device_get_devlinks_list_entry.3 \
man/udev_device_get_devnode.3 \
@@ -536,6 +546,7 @@ MANPAGES_ALIAS += \
man/udev_ref.3 \
man/udev_unref.3 \
man/user.conf.d.5
+man/30-systemd-environment-d-generator.8: man/systemd-environment-d-generator.8
man/SD_ALERT.3: man/sd-daemon.3
man/SD_BUS_ERROR_ACCESS_DENIED.3: man/sd-bus-errors.3
man/SD_BUS_ERROR_ADDRESS_IN_USE.3: man/sd-bus-errors.3
@@ -592,6 +603,7 @@ man/SD_ID128_CONST_STR.3: man/sd-id128.3
man/SD_ID128_FORMAT_STR.3: man/sd-id128.3
man/SD_ID128_FORMAT_VAL.3: man/sd-id128.3
man/SD_ID128_MAKE.3: man/sd-id128.3
+man/SD_ID128_MAKE_STR.3: man/sd-id128.3
man/SD_ID128_NULL.3: man/sd-id128.3
man/SD_INFO.3: man/sd-daemon.3
man/SD_JOURNAL_APPEND.3: man/sd_journal_get_fd.3
@@ -750,11 +762,13 @@ man/sd_id128_equal.3: man/sd-id128.3
man/sd_id128_from_string.3: man/sd_id128_to_string.3
man/sd_id128_get_boot.3: man/sd_id128_get_machine.3
man/sd_id128_get_invocation.3: man/sd_id128_get_machine.3
+man/sd_id128_get_machine_app_specific.3: man/sd_id128_get_machine.3
man/sd_id128_is_null.3: man/sd-id128.3
man/sd_id128_t.3: man/sd-id128.3
man/sd_is_mq.3: man/sd_is_fifo.3
man/sd_is_socket.3: man/sd_is_fifo.3
man/sd_is_socket_inet.3: man/sd_is_fifo.3
+man/sd_is_socket_sockaddr.3: man/sd_is_fifo.3
man/sd_is_socket_unix.3: man/sd_is_fifo.3
man/sd_is_special.3: man/sd_is_fifo.3
man/sd_journal.3: man/sd_journal_open.3
@@ -831,8 +845,10 @@ man/systemd-tmpfiles-setup.service.8: man/systemd-tmpfiles.8
man/systemd-udevd-control.socket.8: man/systemd-udevd.service.8
man/systemd-udevd-kernel.socket.8: man/systemd-udevd.service.8
man/systemd-udevd.8: man/systemd-udevd.service.8
+man/systemd-umount.1: man/systemd-mount.1
man/systemd-update-done.8: man/systemd-update-done.service.8
man/systemd-user.conf.5: man/systemd-system.conf.5
+man/systemd-volatile-root.8: man/systemd-volatile-root.service.8
man/udev_device_get_action.3: man/udev_device_get_syspath.3
man/udev_device_get_devlinks_list_entry.3: man/udev_device_has_tag.3
man/udev_device_get_devnode.3: man/udev_device_get_syspath.3
@@ -889,6 +905,9 @@ man/udev_monitor_unref.3: man/udev_monitor_new_from_netlink.3
man/udev_ref.3: man/udev_new.3
man/udev_unref.3: man/udev_new.3
man/user.conf.d.5: man/systemd-system.conf.5
+man/30-systemd-environment-d-generator.html: man/systemd-environment-d-generator.html
+ $(html-alias)
+
man/SD_ALERT.html: man/sd-daemon.html
$(html-alias)
@@ -1057,6 +1076,9 @@ man/SD_ID128_FORMAT_VAL.html: man/sd-id128.html
man/SD_ID128_MAKE.html: man/sd-id128.html
$(html-alias)
+man/SD_ID128_MAKE_STR.html: man/sd-id128.html
+ $(html-alias)
+
man/SD_ID128_NULL.html: man/sd-id128.html
$(html-alias)
@@ -1531,6 +1553,9 @@ man/sd_id128_get_boot.html: man/sd_id128_get_machine.html
man/sd_id128_get_invocation.html: man/sd_id128_get_machine.html
$(html-alias)
+man/sd_id128_get_machine_app_specific.html: man/sd_id128_get_machine.html
+ $(html-alias)
+
man/sd_id128_is_null.html: man/sd-id128.html
$(html-alias)
@@ -1546,6 +1571,9 @@ man/sd_is_socket.html: man/sd_is_fifo.html
man/sd_is_socket_inet.html: man/sd_is_fifo.html
$(html-alias)
+man/sd_is_socket_sockaddr.html: man/sd_is_fifo.html
+ $(html-alias)
+
man/sd_is_socket_unix.html: man/sd_is_fifo.html
$(html-alias)
@@ -1774,12 +1802,18 @@ man/systemd-udevd-kernel.socket.html: man/systemd-udevd.service.html
man/systemd-udevd.html: man/systemd-udevd.service.html
$(html-alias)
+man/systemd-umount.html: man/systemd-mount.html
+ $(html-alias)
+
man/systemd-update-done.html: man/systemd-update-done.service.html
$(html-alias)
man/systemd-user.conf.html: man/systemd-system.conf.html
$(html-alias)
+man/systemd-volatile-root.html: man/systemd-volatile-root.service.html
+ $(html-alias)
+
man/udev_device_get_action.html: man/udev_device_get_syspath.html
$(html-alias)
@@ -2260,13 +2294,20 @@ if HAVE_LIBCRYPTSETUP
MANPAGES += \
man/crypttab.5 \
man/systemd-cryptsetup-generator.8 \
- man/systemd-cryptsetup@.service.8
+ man/systemd-cryptsetup@.service.8 \
+ man/systemd-veritysetup-generator.8 \
+ man/systemd-veritysetup@.service.8
MANPAGES_ALIAS += \
- man/systemd-cryptsetup.8
+ man/systemd-cryptsetup.8 \
+ man/systemd-veritysetup.8
man/systemd-cryptsetup.8: man/systemd-cryptsetup@.service.8
+man/systemd-veritysetup.8: man/systemd-veritysetup@.service.8
man/systemd-cryptsetup.html: man/systemd-cryptsetup@.service.html
$(html-alias)
+man/systemd-veritysetup.html: man/systemd-veritysetup@.service.html
+ $(html-alias)
+
endif
if HAVE_MICROHTTPD
@@ -2607,6 +2648,7 @@ EXTRA_DIST += \
man/crypttab.xml \
man/daemon.xml \
man/dnssec-trust-anchors.d.xml \
+ man/environment.d.xml \
man/file-hierarchy.xml \
man/halt.xml \
man/hostname.xml \
@@ -2739,6 +2781,7 @@ EXTRA_DIST += \
man/systemd-debug-generator.xml \
man/systemd-delta.xml \
man/systemd-detect-virt.xml \
+ man/systemd-environment-d-generator.xml \
man/systemd-escape.xml \
man/systemd-firstboot.xml \
man/systemd-fsck@.service.xml \
@@ -2794,8 +2837,12 @@ EXTRA_DIST += \
man/systemd-update-utmp.service.xml \
man/systemd-user-sessions.service.xml \
man/systemd-vconsole-setup.service.xml \
+ man/systemd-veritysetup-generator.xml \
+ man/systemd-veritysetup@.service.xml \
+ man/systemd-volatile-root.service.xml \
man/systemd.automount.xml \
man/systemd.device.xml \
+ man/systemd.environment-generator.xml \
man/systemd.exec.xml \
man/systemd.generator.xml \
man/systemd.journal-fields.xml \
diff --git a/Makefile.am b/Makefile.am
index 4f1d729a74..f6ab0f481a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -39,12 +39,12 @@ SUBDIRS = . po
.PRECIOUS: $(TEST_SUITE_LOG) Makefile
LIBUDEV_CURRENT=7
-LIBUDEV_REVISION=5
+LIBUDEV_REVISION=6
LIBUDEV_AGE=6
-LIBSYSTEMD_CURRENT=17
+LIBSYSTEMD_CURRENT=18
LIBSYSTEMD_REVISION=0
-LIBSYSTEMD_AGE=17
+LIBSYSTEMD_AGE=18
# Dirs of external packages
dbuspolicydir=@dbuspolicydir@
@@ -55,9 +55,11 @@ pamconfdir=@pamconfdir@
pkgconfigdatadir=$(datadir)/pkgconfig
pkgconfiglibdir=$(libdir)/pkgconfig
polkitpolicydir=$(datadir)/polkit-1/actions
+polkitrulesdir=$(datadir)/polkit-1/rules.d
+polkitpkladir=$(localstatedir)/lib/polkit-1/localauthority/10-vendor.d
bashcompletiondir=@bashcompletiondir@
zshcompletiondir=@zshcompletiondir@
-rpmmacrosdir=$(prefix)/lib/rpm/macros.d
+rpmmacrosdir=@rpmmacrosdir@
sysvinitdir=$(SYSTEM_SYSVINIT_PATH)
sysvrcnddir=$(SYSTEM_SYSVRCND_PATH)
varlogdir=$(localstatedir)/log
@@ -66,6 +68,7 @@ catalogstatedir=$(systemdstatedir)/catalog
xinitrcdir=$(sysconfdir)/X11/xinit/xinitrc.d
# Our own, non-special dirs
+environmentdir=$(prefix)/lib/environment.d
pkgsysconfdir=$(sysconfdir)/systemd
userunitdir=$(prefix)/lib/systemd/user
userpresetdir=$(prefix)/lib/systemd/user-preset
@@ -78,6 +81,8 @@ networkdir=$(rootprefix)/lib/systemd/network
pkgincludedir=$(includedir)/systemd
systemgeneratordir=$(rootlibexecdir)/system-generators
usergeneratordir=$(prefix)/lib/systemd/user-generators
+systemenvgeneratordir=$(prefix)/lib/systemd/system-environment-generators
+userenvgeneratordir=$(prefix)/lib/systemd/user-environment-generators
systemshutdowndir=$(rootlibexecdir)/system-shutdown
systemsleepdir=$(rootlibexecdir)/system-sleep
systemunitdir=$(rootprefix)/lib/systemd/system
@@ -91,6 +96,7 @@ kernelinstalldir = $(prefix)/lib/kernel/install.d
factory_etcdir = $(datadir)/factory/etc
factory_pamdir = $(datadir)/factory/etc/pam.d
bootlibdir = $(prefix)/lib/systemd/boot/efi
+testsdir = $(prefix)/lib/systemd/tests
# And these are the special ones for /
rootprefix=@rootprefix@
@@ -116,6 +122,8 @@ pkgconfiglib_DATA =
polkitpolicy_in_in_files =
polkitpolicy_in_files =
polkitpolicy_files =
+polkitrules_files =
+polkitpkla_files =
dist_udevrules_DATA =
nodist_udevrules_DATA =
dist_pkgsysconf_DATA =
@@ -129,6 +137,7 @@ check_DATA =
dist_rootlibexec_DATA =
tests=
manual_tests =
+TEST_DATA_FILES =
TEST_EXTENSIONS = .py
PY_LOG_COMPILER = $(PYTHON)
DISABLE_HARD_ERRORS = yes
@@ -145,7 +154,8 @@ TESTS =
endif
AM_TESTS_ENVIRONMENT = \
export SYSTEMD_KBD_MODEL_MAP=$(abs_top_srcdir)/src/locale/kbd-model-map; \
- export SYSTEMD_LANGUAGE_FALLBACK_MAP=$(abs_top_srcdir)/src/locale/language-fallback-map;
+ export SYSTEMD_LANGUAGE_FALLBACK_MAP=$(abs_top_srcdir)/src/locale/language-fallback-map; \
+ export PATH=$(abs_top_builddir):$$PATH;
if ENABLE_BASH_COMPLETION
dist_bashcompletion_DATA = $(dist_bashcompletion_data)
@@ -168,6 +178,7 @@ CLEANFILES = $(BUILT_SOURCES) \
$(pkgconfiglib_DATA) \
$(nodist_bashcompletion_data) \
$(nodist_zshcompletion_data) \
+ $(nodist_rpmmacros_DATA) \
$(in_files:.in=) $(in_in_files:.in.in=) \
$(m4_files:.m4=)
@@ -200,6 +211,8 @@ AM_CPPFLAGS = \
-DSYSTEMD_CRYPTSETUP_PATH=\"$(rootlibexecdir)/systemd-cryptsetup\" \
-DSYSTEM_GENERATOR_PATH=\"$(systemgeneratordir)\" \
-DUSER_GENERATOR_PATH=\"$(usergeneratordir)\" \
+ -DSYSTEM_ENV_GENERATOR_PATH=\"$(systemenvgeneratordir)\" \
+ -DUSER_ENV_GENERATOR_PATH=\"$(userenvgeneratordir)\" \
-DSYSTEM_SHUTDOWN_PATH=\"$(systemshutdowndir)\" \
-DSYSTEM_SLEEP_PATH=\"$(systemsleepdir)\" \
-DSYSTEMD_KBD_MODEL_MAP=\"$(pkgdatadir)/kbd-model-map\" \
@@ -213,7 +226,6 @@ AM_CPPFLAGS = \
-DLIBDIR=\"$(libdir)\" \
-DROOTLIBDIR=\"$(rootlibdir)\" \
-DROOTLIBEXECDIR=\"$(rootlibexecdir)\" \
- -DTEST_DIR=\"$(abs_top_srcdir)/test\" \
-I $(top_srcdir)/src \
-I $(top_builddir)/src/basic \
-I $(top_srcdir)/src/basic \
@@ -245,6 +257,8 @@ AM_CPPFLAGS = \
-I $(top_srcdir)/src/libsystemd/sd-device \
-I $(top_srcdir)/src/libsystemd/sd-id128 \
-I $(top_srcdir)/src/libsystemd-network \
+ -DABS_SRC_DIR=\"$(abs_top_srcdir)\" \
+ -DABS_BUILD_DIR=\"$(abs_top_builddir)\" \
$(OUR_CPPFLAGS)
AM_CFLAGS = $(OUR_CFLAGS)
@@ -299,6 +313,10 @@ endef
install-directories-hook:
$(MKDIR_P) $(addprefix $(DESTDIR),$(INSTALL_DIRS))
+install-environment-conf-hook: install-directories-hook
+ $(AM_V_LN)$(LN_S) --relative -f $(DESTDIR)$(sysconfdir)/environment \
+ $(DESTDIR)$(environmentdir)/99-environment.conf
+
install-aliases-hook:
set -- $(SYSTEM_UNIT_ALIASES) && \
dir=$(systemunitdir) && $(install-aliases)
@@ -332,10 +350,13 @@ INSTALL_EXEC_HOOKS += \
install-target-wants-hook \
install-directories-hook \
install-aliases-hook \
- install-touch-usr-hook
+ install-touch-usr-hook \
+ install-busnames-target-wants-hook
+if ENABLE_ENVIRONMENT_D
INSTALL_EXEC_HOOKS += \
- install-busnames-target-wants-hook
+ install-environment-conf-hook
+endif
# ------------------------------------------------------------------------------
AM_V_M4 = $(AM_V_M4_$(V))
@@ -392,6 +413,7 @@ rootlibexec_PROGRAMS = \
systemd-initctl \
systemd-shutdown \
systemd-remount-fs \
+ systemd-volatile-root \
systemd-reply-password \
systemd-fsck \
systemd-ac-power \
@@ -400,6 +422,11 @@ rootlibexec_PROGRAMS = \
systemd-socket-proxyd \
systemd-update-done
+if HAVE_BLKID
+rootlibexec_PROGRAMS += \
+ systemd-dissect
+endif
+
if HAVE_UTMP
rootlibexec_PROGRAMS += \
systemd-update-utmp
@@ -411,6 +438,11 @@ systemgenerator_PROGRAMS = \
systemd-system-update-generator \
systemd-debug-generator
+if ENABLE_ENVIRONMENT_D
+userenvgenerator_PROGRAMS = \
+ 30-systemd-environment-d-generator
+endif
+
dist_bashcompletion_data = \
shell-completion/bash/busctl \
shell-completion/bash/journalctl \
@@ -525,8 +557,10 @@ nodist_systemunit_DATA = \
units/serial-getty@.service \
units/console-getty.service \
units/container-getty@.service \
+ units/system-update-cleanup.service \
units/systemd-initctl.service \
units/systemd-remount-fs.service \
+ units/systemd-volatile-root.service \
units/systemd-ask-password-wall.service \
units/systemd-ask-password-console.service \
units/systemd-sysctl.service \
@@ -588,8 +622,10 @@ EXTRA_DIST += \
units/console-getty.service.m4.in \
units/container-getty@.service.m4.in \
units/rescue.service.in \
+ units/system-update-cleanup.service.in \
units/systemd-initctl.service.in \
units/systemd-remount-fs.service.in \
+ units/systemd-volatile-root.service.in \
units/systemd-update-utmp.service.in \
units/systemd-update-utmp-runlevel.service.in \
units/systemd-ask-password-wall.service.in \
@@ -658,6 +694,15 @@ EXTRA_DIST += \
@INTLTOOL_POLICY_RULE@
+systemd-mount-install-hook:
+ -$(LN_S) systemd-mount $(DESTDIR)$(bindir)/systemd-umount
+
+systemd-mount-uninstall-hook:
+ -rm $(DESTDIR)$(bindir)/systemd-umount
+
+INSTALL_EXEC_HOOKS += systemd-mount-install-hook
+UNINSTALL_EXEC_HOOKS += systemd-mount-uninstall-hook
+
# ------------------------------------------------------------------------------
MANPAGES =
@@ -737,7 +782,9 @@ EXTRA_DIST += \
tools/make-man-rules.py \
tools/make-directive-index.py \
tools/xml_helper.py \
- man/glib-event-glue.c
+ man/glib-event-glue.c \
+ man/50-xdg-data-dirs.sh \
+ man/90-rearrange-path.py
# ------------------------------------------------------------------------------
noinst_LTLIBRARIES += \
@@ -849,6 +896,8 @@ libbasic_la_SOURCES = \
src/basic/bus-label.h \
src/basic/ratelimit.h \
src/basic/ratelimit.c \
+ src/basic/exec-util.c \
+ src/basic/exec-util.h \
src/basic/exit-status.c \
src/basic/exit-status.h \
src/basic/virt.c \
@@ -931,8 +980,12 @@ libbasic_la_SOURCES = \
src/basic/copy.h \
src/basic/alloc-util.h \
src/basic/alloc-util.c \
- src/basic/formats-util.h \
- src/basic/nss-util.h
+ src/basic/format-util.h \
+ src/basic/nss-util.h \
+ src/basic/khash.h \
+ src/basic/khash.c \
+ src/basic/journal-importer.h \
+ src/basic/journal-importer.c
nodist_libbasic_la_SOURCES = \
src/basic/errno-from-name.h \
@@ -953,8 +1006,7 @@ libbasic_la_CFLAGS = \
libbasic_la_LIBADD = \
$(SELINUX_LIBS) \
$(CAP_LIBS) \
- -lrt \
- -lm
+ -lrt
# -----------------------------------------------------------------------------
noinst_LTLIBRARIES += \
@@ -985,6 +1037,8 @@ libshared_la_SOURCES = \
src/shared/apparmor-util.h \
src/shared/ima-util.c \
src/shared/ima-util.h \
+ src/shared/journal-util.c \
+ src/shared/journal-util.h \
src/shared/ptyfwd.c \
src/shared/ptyfwd.h \
src/shared/base-filesystem.c \
@@ -1036,6 +1090,8 @@ libshared_la_SOURCES = \
src/shared/machine-image.h \
src/shared/machine-pool.c \
src/shared/machine-pool.h \
+ src/shared/loop-util.c \
+ src/shared/loop-util.h \
src/shared/resolve-util.c \
src/shared/resolve-util.h \
src/shared/bus-unit-util.c \
@@ -1045,7 +1101,13 @@ libshared_la_SOURCES = \
src/shared/tests.h \
src/shared/tests.c \
src/shared/fdset.c \
- src/shared/fdset.h
+ src/shared/fdset.h \
+ src/shared/nsflags.h \
+ src/shared/nsflags.c \
+ src/shared/dissect-image.c \
+ src/shared/dissect-image.h \
+ src/shared/volatile-util.c \
+ src/shared/volatile-util.h
if HAVE_UTMP
libshared_la_SOURCES += \
@@ -1068,7 +1130,9 @@ libshared_la_CFLAGS = \
$(AM_CFLAGS) \
$(ACL_CFLAGS) \
$(LIBIDN_CFLAGS) \
- $(SECCOMP_CFLAGS)
+ $(SECCOMP_CFLAGS) \
+ $(BLKID_CFLAGS) \
+ $(LIBCRYPTSETUP_CFLAGS)
libshared_la_LIBADD = \
libsystemd-internal.la \
@@ -1077,7 +1141,9 @@ libshared_la_LIBADD = \
libudev-internal.la \
$(ACL_LIBS) \
$(LIBIDN_LIBS) \
- $(SECCOMP_LIBS)
+ $(SECCOMP_LIBS) \
+ $(BLKID_LIBS) \
+ $(LIBCRYPTSETUP_LIBS)
rootlibexec_LTLIBRARIES += \
libsystemd-shared.la
@@ -1099,6 +1165,8 @@ libsystemd_shared_la_CFLAGS = \
$(ACL_CFLAGS) \
$(LIBIDN_CFLAGS) \
$(SECCOMP_CFLAGS) \
+ $(BLKID_CFLAGS) \
+ $(LIBCRYPTSETUP_CFLAGS) \
-fvisibility=default
# We can't use libshared_la_LIBADD here because it would
@@ -1110,7 +1178,9 @@ libsystemd_shared_la_LIBADD = \
$(libudev_internal_la_LIBADD) \
$(ACL_LIBS) \
$(LIBIDN_LIBS) \
- $(SECCOMP_LIBS)
+ $(SECCOMP_LIBS) \
+ $(BLKID_LIBS) \
+ $(LIBCRYPTSETUP_LIBS)
libsystemd_shared_la_LDFLAGS = \
$(AM_LDFLAGS) \
@@ -1428,8 +1498,10 @@ polkitpolicy_in_in_files += \
pkgconfigdata_DATA += \
src/core/systemd.pc
+if ENABLE_RPM_MACROS
nodist_rpmmacros_DATA = \
src/core/macros.systemd
+endif
BUILT_SOURCES += \
src/core/triggers.systemd
@@ -1448,7 +1520,8 @@ manual_tests += \
test-btrfs \
test-acd \
test-ipv4ll-manual \
- test-ask-password-api
+ test-ask-password-api \
+ test-dissect-image
unsafe_tests = \
test-hostname \
@@ -1484,6 +1557,8 @@ tests += \
test-utf8 \
test-ellipsize \
test-util \
+ test-mount-util \
+ test-exec-util \
test-cpu-set-util \
test-hexdecoct \
test-escape \
@@ -1550,7 +1625,8 @@ tests += \
test-rlimit-util \
test-signal-util \
test-selinux \
- test-sizeof
+ test-sizeof \
+ test-journal-importer
if HAVE_ACL
tests += \
@@ -1562,7 +1638,7 @@ tests += \
test-seccomp
endif
-EXTRA_DIST += \
+TEST_DATA_FILES += \
test/a.service \
test/basic.target \
test/b.service \
@@ -1682,13 +1758,21 @@ EXTRA_DIST += \
test/test-execute/exec-runtimedirectory-mode.service \
test/test-execute/exec-runtimedirectory-owner.service \
test/test-execute/exec-runtimedirectory-owner-nfsnobody.service \
+ test/test-execute/exec-restrict-namespaces-no.service \
+ test/test-execute/exec-restrict-namespaces-yes.service \
+ test/test-execute/exec-restrict-namespaces-mnt.service \
+ test/test-execute/exec-restrict-namespaces-mnt-blacklist.service \
+ test/test-execute/exec-read-only-path-succeed.service \
+ test/test-execute/exec-privatedevices-yes-capability-sys-rawio.service \
+ test/test-execute/exec-privatedevices-no-capability-sys-rawio.service \
test/bus-policy/hello.conf \
test/bus-policy/methods.conf \
test/bus-policy/ownerships.conf \
test/bus-policy/signals.conf \
test/bus-policy/check-own-rules.conf \
test/bus-policy/many-rules.conf \
- test/bus-policy/test.conf
+ test/bus-policy/test.conf \
+ test/hwdb/10-bad.hwdb
EXTRA_DIST += \
@@ -1857,6 +1941,18 @@ test_util_SOURCES = \
test_util_LDADD = \
libsystemd-shared.la
+test_mount_util_SOURCES = \
+ src/test/test-mount-util.c
+
+test_mount_util_LDADD = \
+ libsystemd-shared.la
+
+test_exec_util_SOURCES = \
+ src/test/test-exec-util.c
+
+test_exec_util_LDADD = \
+ libsystemd-shared.la
+
test_hexdecoct_SOURCES = \
src/test/test-hexdecoct.c
@@ -2037,7 +2133,8 @@ test_seccomp_SOURCES = \
src/test/test-seccomp.c
test_seccomp_LDADD = \
- libsystemd-shared.la
+ libsystemd-shared.la \
+ $(SECCOMP_LIBS)
test_namespace_LDADD = \
libcore.la
@@ -2054,6 +2151,17 @@ test_ask_password_api_SOURCES = \
test_ask_password_api_LDADD = \
libsystemd-shared.la
+test_dissect_image_SOURCES = \
+ src/test/test-dissect-image.c
+
+test_dissect_image_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(BLKID_CFLAGS)
+
+test_dissect_image_LDADD = \
+ libsystemd-shared.la \
+ $(BLKID_LIBS)
+
test_signal_util_SOURCES = \
src/test/test-signal-util.c
@@ -2390,6 +2498,16 @@ test_arphrd_list_SOURCES = \
test_arphrd_list_LDADD = \
libsystemd-shared.la
+test_journal_importer_SOURCES = \
+ src/test/test-journal-importer.c
+
+test_journal_importer_LDADD = \
+ libsystemd-shared.la
+
+TEST_DATA_FILES += \
+ test/journal-data/journal-1.txt \
+ test/journal-data/journal-2.txt
+
# ------------------------------------------------------------------------------
## .PHONY so it always rebuilds it
.PHONY: coverage lcov-run lcov-report coverage-sync
@@ -2736,6 +2854,13 @@ systemd_system_update_generator_LDADD = \
libsystemd-shared.la
# ------------------------------------------------------------------------------
+30_systemd_environment_d_generator_SOURCES = \
+ src/environment-d-generator/environment-d-generator.c
+
+30_systemd_environment_d_generator_LDADD = \
+ libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
if ENABLE_HIBERNATE
systemgenerator_PROGRAMS += \
systemd-hibernate-resume-generator
@@ -3013,6 +3138,13 @@ systemd_remount_fs_LDADD = \
libsystemd-shared.la
# ------------------------------------------------------------------------------
+systemd_volatile_root_SOURCES = \
+ src/volatile-root/volatile-root.c
+
+systemd_volatile_root_LDADD = \
+ libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
systemd_cgroups_agent_SOURCES = \
src/cgroups-agent/cgroups-agent.c
@@ -3041,6 +3173,13 @@ systemd_notify_LDADD = \
libsystemd-shared.la
# ------------------------------------------------------------------------------
+systemd_dissect_SOURCES = \
+ src/dissect/dissect.c
+
+systemd_dissect_LDADD = \
+ libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
systemd_path_SOURCES = \
src/path/path.c
@@ -3692,6 +3831,7 @@ dist_udevrules_DATA += \
rules/60-persistent-input.rules \
rules/60-persistent-alsa.rules \
rules/60-persistent-storage.rules \
+ rules/60-sensor.rules \
rules/60-serial.rules \
rules/64-btrfs.rules \
rules/70-mouse.rules \
@@ -3861,6 +4001,7 @@ dist_udevhwdb_DATA = \
hwdb/20-net-ifname.hwdb \
hwdb/60-evdev.hwdb \
hwdb/60-keyboard.hwdb \
+ hwdb/60-sensor.hwdb \
hwdb/70-mouse.hwdb \
hwdb/70-pointingstick.hwdb \
hwdb/70-touchpad.hwdb
@@ -3888,7 +4029,8 @@ EXTRA_DIST += \
# ------------------------------------------------------------------------------
if ENABLE_TESTS
TESTS += \
- test/udev-test.pl
+ test/udev-test.pl \
+ test/hwdb-test.sh
if HAVE_PYTHON
TESTS += \
@@ -3929,20 +4071,21 @@ check_DATA += \
test/sys
endif
-# packed sysfs test tree
-test/sys: test/sys.tar.xz
- -rm -rf test/sys
+# sysfs test tree
+test/sys: test/sys-script.py
+ -rm -rf $@
$(AM_V_at)$(MKDIR_P) $(dir $@)
- $(AM_V_GEN)tar -C test/ -xJf $(top_srcdir)/test/sys.tar.xz
- -touch test/sys
+ $(AM_V_GEN)$(top_srcdir)/test/sys-script.py $(dir $@)
+ -touch $@
test-sys-distclean:
-rm -rf test/sys
DISTCLEAN_LOCAL_HOOKS += test-sys-distclean
EXTRA_DIST += \
- test/sys.tar.xz \
+ test/sys-script.py \
test/udev-test.pl \
+ test/hwdb-test.sh \
test/rule-syntax-check.py \
test/sysv-generator-test.py \
test/mocks/fsck \
@@ -4033,6 +4176,16 @@ tests += \
test-id128
# ------------------------------------------------------------------------------
+test_hash_SOURCES = \
+ src/test/test-hash.c
+
+test_hash_LDADD = \
+ libsystemd-shared.la
+
+tests += \
+ test-hash
+
+# ------------------------------------------------------------------------------
bin_PROGRAMS += \
systemd-socket-activate
@@ -4749,10 +4902,12 @@ EXTRA_DIST += \
# ------------------------------------------------------------------------------
if HAVE_LIBCRYPTSETUP
rootlibexec_PROGRAMS += \
- systemd-cryptsetup
+ systemd-cryptsetup \
+ systemd-veritysetup
systemgenerator_PROGRAMS += \
- systemd-cryptsetup-generator
+ systemd-cryptsetup-generator \
+ systemd-veritysetup-generator
dist_systemunit_DATA += \
units/cryptsetup.target \
@@ -4775,6 +4930,23 @@ systemd_cryptsetup_generator_SOURCES = \
systemd_cryptsetup_generator_LDADD = \
libsystemd-shared.la
+systemd_veritysetup_SOURCES = \
+ src/veritysetup/veritysetup.c
+
+systemd_veritysetup_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(LIBCRYPTSETUP_CFLAGS)
+
+systemd_veritysetup_LDADD = \
+ libsystemd-shared.la \
+ $(LIBCRYPTSETUP_LIBS)
+
+systemd_veritysetup_generator_SOURCES = \
+ src/veritysetup/veritysetup-generator.c
+
+systemd_veritysetup_generator_LDADD = \
+ libsystemd-shared.la
+
SYSINIT_TARGET_WANTS += \
cryptsetup.target
@@ -5434,14 +5606,12 @@ dist_dbuspolicy_DATA += \
dist_dbussystemservice_DATA += \
src/resolve/org.freedesktop.resolve1.service
-SYSTEM_UNIT_ALIASES += \
- systemd-resolved.service dbus-org.freedesktop.resolve1.service
-
BUSNAMES_TARGET_WANTS += \
org.freedesktop.resolve1.busname
GENERAL_ALIASES += \
- $(systemunitdir)/systemd-resolved.service $(pkgsysconfdir)/system/multi-user.target.wants/systemd-resolved.service
+ $(systemunitdir)/systemd-resolved.service $(pkgsysconfdir)/system/multi-user.target.wants/systemd-resolved.service \
+ $(systemunitdir)/systemd-resolved.service $(pkgsysconfdir)/system/dbus-org.freedesktop.resolve1.service
nodist_pkgsysconf_DATA += \
src/resolve/resolved.conf
@@ -5461,8 +5631,7 @@ libnss_resolve_la_LDFLAGS = \
libnss_resolve_la_LIBADD = \
libsystemd-internal.la \
- libbasic.la \
- -ldl
+ libbasic.la
rootlib_LTLIBRARIES += \
libnss_resolve.la
@@ -5498,6 +5667,7 @@ dist_zshcompletion_data += \
tests += \
test-dns-packet \
test-resolve-tables \
+ test-resolved-packet \
test-dnssec
manual_tests += \
@@ -5519,13 +5689,26 @@ test_resolve_tables_LDADD = \
$(GCRYPT_LIBS) \
-lm
+test_resolved_packet_SOURCES = \
+ src/resolve/test-resolved-packet.c \
+ $(basic_dns_sources)
+
+test_resolved_packet_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(GCRYPT_CFLAGS)
+
+test_resolved_packet_LDADD = \
+ libsystemd-shared.la \
+ $(GCRYPT_LIBS) \
+ -lm
+
test_dns_packet_SOURCES = \
src/resolve/test-dns-packet.c \
$(basic_dns_sources)
test_dns_packet_CPPFLAGS = \
$(AM_CPPFLAGS) \
- -DRESOLVE_TEST_DIR=\"$(abs_top_srcdir)/src/resolve/test-data\"
+ -I $(top_srcdir)/src/test
test_dns_packet_CFLAGS = \
$(AM_CFLAGS) \
@@ -5536,18 +5719,20 @@ test_dns_packet_LDADD = \
$(GCRYPT_LIBS) \
-lm
-EXTRA_DIST += \
- src/resolve/test-data/_openpgpkey.fedoraproject.org.pkts \
- src/resolve/test-data/fedoraproject.org.pkts \
- src/resolve/test-data/gandi.net.pkts \
- src/resolve/test-data/google.com.pkts \
- src/resolve/test-data/root.pkts \
- src/resolve/test-data/sw1a1aa-sw1a2aa-sw1a2ab-sw1a2ac.find.me.uk.pkts \
- src/resolve/test-data/teamits.com.pkts \
- src/resolve/test-data/zbyszek@fedoraproject.org.pkts \
- src/resolve/test-data/_443._tcp.fedoraproject.org.pkts \
- src/resolve/test-data/kyhwana.org.pkts \
- src/resolve/test-data/fake-caa.pkts
+TEST_DATA_FILES += \
+ test/test-resolve/_openpgpkey.fedoraproject.org.pkts \
+ test/test-resolve/fedoraproject.org.pkts \
+ test/test-resolve/gandi.net.pkts \
+ test/test-resolve/google.com.pkts \
+ test/test-resolve/root.pkts \
+ test/test-resolve/sw1a1aa-sw1a2aa-sw1a2ab-sw1a2ac.find.me.uk.pkts \
+ test/test-resolve/teamits.com.pkts \
+ test/test-resolve/zbyszek@fedoraproject.org.pkts \
+ test/test-resolve/_443._tcp.fedoraproject.org.pkts \
+ test/test-resolve/kyhwana.org.pkts \
+ test/test-resolve/fake-caa.pkts
+
+EXTRA_DIST += $(TEST_DATA_FILES)
test_dnssec_SOURCES = \
src/resolve/test-dnssec.c \
@@ -5609,39 +5794,43 @@ libnetworkd_core_la_CFLAGS = \
libnetworkd_core_la_SOURCES = \
src/libsystemd-network/network-internal.h \
- src/network/networkd.h \
+ src/network/netdev/netdev.h \
+ src/network/netdev/netdev.c \
+ src/network/netdev/vrf.h \
+ src/network/netdev/vrf.c \
+ src/network/netdev/tunnel.h \
+ src/network/netdev/tunnel.c \
+ src/network/netdev/veth.h \
+ src/network/netdev/veth.c \
+ src/network/netdev/vxlan.h \
+ src/network/netdev/vxlan.c \
+ src/network/netdev/vlan.h \
+ src/network/netdev/vlan.c \
+ src/network/netdev/macvlan.h \
+ src/network/netdev/macvlan.c \
+ src/network/netdev/ipvlan.h \
+ src/network/netdev/ipvlan.c \
+ src/network/netdev/dummy.h \
+ src/network/netdev/dummy.c \
+ src/network/netdev/tuntap.h \
+ src/network/netdev/tuntap.c \
+ src/network/netdev/bond.h \
+ src/network/netdev/bond.c \
+ src/network/netdev/bridge.h \
+ src/network/netdev/bridge.c \
+ src/network/netdev/vcan.h \
+ src/network/netdev/vcan.c \
+ src/network/networkd-manager.h \
+ src/network/networkd-manager.c \
+ src/network/networkd-manager-bus.c \
src/network/networkd-conf.h \
src/network/networkd-conf.c \
src/network/networkd-link.h \
src/network/networkd-link.c \
- src/network/networkd-netdev.h \
- src/network/networkd-netdev.c \
- src/network/networkd-netdev-vrf.h \
- src/network/networkd-netdev-vrf.c \
- src/network/networkd-netdev-tunnel.h \
- src/network/networkd-netdev-tunnel.c \
- src/network/networkd-netdev-veth.h \
- src/network/networkd-netdev-veth.c \
- src/network/networkd-netdev-vxlan.h \
- src/network/networkd-netdev-vxlan.c \
- src/network/networkd-netdev-vlan.h \
- src/network/networkd-netdev-vlan.c \
- src/network/networkd-netdev-macvlan.h \
- src/network/networkd-netdev-macvlan.c \
- src/network/networkd-netdev-ipvlan.h \
- src/network/networkd-netdev-ipvlan.c \
- src/network/networkd-netdev-dummy.h \
- src/network/networkd-netdev-dummy.c \
- src/network/networkd-netdev-tuntap.h \
- src/network/networkd-netdev-tuntap.c \
- src/network/networkd-netdev-bond.h \
- src/network/networkd-netdev-bond.c \
- src/network/networkd-netdev-bridge.h \
- src/network/networkd-netdev-bridge.c \
- src/network/networkd-netdev-vcan.h \
- src/network/networkd-netdev-vcan.c \
src/network/networkd-link-bus.c \
src/network/networkd-ipv4ll.c \
+ src/network/networkd-ipv6-proxy-ndp.h \
+ src/network/networkd-ipv6-proxy-ndp.c \
src/network/networkd-dhcp4.c \
src/network/networkd-dhcp6.c \
src/network/networkd-ndisc.h \
@@ -5653,8 +5842,6 @@ libnetworkd_core_la_SOURCES = \
src/network/networkd-address.c \
src/network/networkd-route.h \
src/network/networkd-route.c \
- src/network/networkd-manager.c \
- src/network/networkd-manager-bus.c \
src/network/networkd-fdb.h \
src/network/networkd-fdb.c \
src/network/networkd-brvlan.h \
@@ -5669,7 +5856,7 @@ libnetworkd_core_la_SOURCES = \
nodist_libnetworkd_core_la_SOURCES = \
src/network/networkd-gperf.c \
src/network/networkd-network-gperf.c \
- src/network/networkd-netdev-gperf.c
+ src/network/netdev/netdev-gperf.c
libnetworkd_core_la_LIBADD = \
libsystemd-network.la \
@@ -5683,11 +5870,11 @@ systemd_networkd_wait_online_CFLAGS = \
systemd_networkd_wait_online_SOURCES = \
src/libsystemd-network/network-internal.h \
- src/network/networkd-wait-online.h \
- src/network/networkd-wait-online-link.h \
- src/network/networkd-wait-online.c \
- src/network/networkd-wait-online-manager.c \
- src/network/networkd-wait-online-link.c
+ src/network/wait-online/link.h \
+ src/network/wait-online/link.c \
+ src/network/wait-online/manager.h \
+ src/network/wait-online/manager.c \
+ src/network/wait-online/wait-online.c
systemd_networkd_wait_online_LDADD = \
libsystemd-network.la \
@@ -5706,6 +5893,9 @@ networkctl_LDADD = \
dist_bashcompletion_data += \
shell-completion/bash/networkctl
+dist_zshcompletion_data += \
+ shell-completion/zsh/_networkctl
+
test_networkd_conf_SOURCES = \
src/network/test-networkd-conf.c
@@ -5768,14 +5958,22 @@ SYSTEM_UNIT_ALIASES += \
BUSNAMES_TARGET_WANTS += \
org.freedesktop.network1.busname
+polkitrules_files += \
+ src/network/systemd-networkd.rules
+
+polkitpkla_files += \
+ src/network/systemd-networkd.pkla
+
endif
gperf_gperf_sources += \
src/network/networkd-gperf.gperf \
src/network/networkd-network-gperf.gperf \
- src/network/networkd-netdev-gperf.gperf
+ src/network/netdev/netdev-gperf.gperf
EXTRA_DIST += \
+ src/network/systemd-networkd.rules \
+ src/network/systemd-networkd.pkla \
units/systemd-networkd.service.m4.in \
units/systemd-networkd-wait-online.service.in \
test/networkd-test.py
@@ -6042,6 +6240,8 @@ EXTRA_DIST += \
test/TEST-13-NSPAWN-SMOKE/Makefile \
test/TEST-13-NSPAWN-SMOKE/create-busybox-container \
test/TEST-13-NSPAWN-SMOKE/test.sh \
+ test/TEST-14-MACHINE-ID/Makefile \
+ test/TEST-14-MACHINE-ID/test.sh \
test/test-functions
EXTRA_DIST += \
@@ -6054,6 +6254,7 @@ EXTRA_DIST += \
# ------------------------------------------------------------------------------
substitutions = \
+ '|rootlibdir=$(rootlibdir)|' \
'|rootlibexecdir=$(rootlibexecdir)|' \
'|rootbindir=$(rootbindir)|' \
'|bindir=$(bindir)|' \
@@ -6075,6 +6276,8 @@ substitutions = \
'|sysctldir=$(sysctldir)|' \
'|systemgeneratordir=$(systemgeneratordir)|' \
'|usergeneratordir=$(usergeneratordir)|' \
+ '|systemenvgeneratordir=$(systemenvgeneratordir)|' \
+ '|userenvgeneratordir=$(userenvgeneratordir)|' \
'|CERTIFICATEROOT=$(CERTIFICATEROOT)|' \
'|PACKAGE_VERSION=$(PACKAGE_VERSION)|' \
'|PACKAGE_NAME=$(PACKAGE_NAME)|' \
@@ -6118,6 +6321,7 @@ substitutions = \
SED_PROCESS = \
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
$(SED) $(subst '|,-e 's|@,$(subst =,\@|,$(subst |',|g',$(substitutions)))) \
+ -e '/^\#\# /d' \
< $< > $@
units/%: units/%.in
@@ -6183,6 +6387,8 @@ if ENABLE_POLKIT
nodist_polkitpolicy_DATA = \
$(polkitpolicy_files) \
$(polkitpolicy_in_in_files:.policy.in.in=.policy)
+polkitrules_DATA = $(polkitrules_files)
+polkitpkla_DATA = $(polkitpkla_files)
endif
EXTRA_DIST += \
@@ -6335,6 +6541,7 @@ INSTALL_DIRS += \
endif
INSTALL_DIRS += \
+ $(environmentdir) \
$(prefix)/lib/modules-load.d \
$(sysconfdir)/modules-load.d \
$(prefix)/lib/systemd/network \
@@ -6377,6 +6584,7 @@ DISTCHECK_CONFIGURE_FLAGS = \
--with-zshcompletiondir=$$dc_install_base/$(zshcompletiondir) \
--with-pamlibdir=$$dc_install_base/$(pamlibdir) \
--with-pamconfdir=$$dc_install_base/$(pamconfdir) \
+ --with-rpmmacrosdir=$$dc_install_base/$(rpmmacrosdir) \
--with-rootprefix=$$dc_install_base \
--enable-compat-libs
@@ -6464,7 +6672,7 @@ valgrind-tests: $(TESTS)
if $(LIBTOOL) --mode=execute file $$f | grep -q shell; then \
echo -e "$${x}Skipping non-binary $$f"; else \
echo -e "$${x}Running $$f"; \
- $(LIBTOOL) --mode=execute valgrind -q --leak-check=full --max-stackframe=5242880 --error-exitcode=55 $(builddir)/$$f ; fi; \
+ $(AM_TESTS_ENVIRONMENT) $(LIBTOOL) --mode=execute valgrind -q --leak-check=full --max-stackframe=5242880 --error-exitcode=55 $(builddir)/$$f ; fi; \
x="\n\n"; \
done
@@ -6562,6 +6770,20 @@ tests += \
test-libsystemd-sym \
test-libudev-sym
+.PHONY: install-tests
+install-tests: $(tests) $(TEST_DATA_FILES)
+ for f in $(tests); do \
+ if [ -x $(top_builddir)/.libs/$$f ]; then \
+ install -D -m 755 $(top_builddir)/.libs/$$f $(DESTDIR)/$(testsdir)/$$f; \
+ else \
+ install -D -m 755 $(top_builddir)/$$f $(DESTDIR)/$(testsdir)/$$f; \
+ fi; \
+ done
+ for f in $(TEST_DATA_FILES); do \
+ install -D -m 644 $(top_srcdir)/$$f $(DESTDIR)/$(testsdir)/testdata/$${f#test/}; \
+ done
+
+
.PHONY: cppcheck
cppcheck:
cppcheck --enable=all -q $(top_srcdir)
diff --git a/NEWS b/NEWS
index b10a6f538f..05822a2cdc 100644
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,427 @@
systemd System and Service Manager
+CHANGES WITH 233:
+
+ * The "hybrid" control group mode has been modified to improve
+ compatibility with "legacy" cgroups-v1 setups. Specifically, the
+ "hybrid" setup of /sys/fs/cgroup is now pretty much identical to
+ "legacy" (including /sys/fs/cgroup/systemd as "name=systemd" named
+ cgroups-v1 hierarchy), the only externally visible change being that
+ the cgroups-v2 hierarchy is also mounted, to
+ /sys/fs/cgroup/unified. This should provide a large degree of
+ compatibility with "legacy" cgroups-v1, while taking benefit of the
+ better management capabilities of cgroups-v2.
+
+ * The default control group setup mode may be selected both a boot-time
+ via a set of kernel command line parameters (specifically:
+ systemd.unified_cgroup_hierarchy= and
+ systemd.legacy_systemd_cgroup_controller=), as well as a compile-time
+ default selected on the configure command line
+ (--with-default-hierarchy=). The upstream default is "hybrid"
+ (i.e. the cgroups-v1 + cgroups-v2 mixture discussed above) now, but
+ this will change in a future systemd version to be "unified" (pure
+ cgroups-v2 mode). The third option for the compile time option is
+ "legacy", to enter pure cgroups-v1 mode. We recommend downstream
+ distributions to default to "hybrid" mode for release distributions,
+ starting with v233. We recommend "unified" for development
+ distributions (specifically: distributions such as Fedora's rawhide)
+ as that's where things are headed in the long run. Use "legacy" for
+ greatest stability and compatibility only.
+
+ * Note one current limitation of "unified" and "hybrid" control group
+ setup modes: the kernel currently does not permit the systemd --user
+ instance (i.e. unprivileged code) to migrate processes between two
+ disconnected cgroup subtrees, even if both are managed and owned by
+ the user. This effectively means "systemd-run --user --scope" doesn't
+ work when invoked from outside of any "systemd --user" service or
+ scope. Specifically, it is not supported from session scopes. We are
+ working on fixing this in a future systemd version. (See #3388 for
+ further details about this.)
+
+ * DBus policy files are now installed into /usr rather than /etc. Make
+ sure your system has dbus >= 1.9.18 running before upgrading to this
+ version, or override the install path with --with-dbuspolicydir= .
+
+ * All python scripts shipped with systemd (specifically: the various
+ tests written in Python) now require Python 3.
+
+ * systemd unit tests can now run standalone (without the source or
+ build directories), and can be installed into /usr/lib/systemd/tests/
+ with 'make install-tests'.
+
+ * Note that from this version on, CONFIG_CRYPTO_USER_API_HASH,
+ CONFIG_CRYPTO_HMAC and CONFIG_CRYPTO_SHA256 need to be enabled in the
+ kernel.
+
+ * Support for the %c, %r, %R specifiers in unit files has been
+ removed. Specifiers are not supposed to be dependent on configuration
+ in the unit file itself (so that they resolve the same regardless
+ where used in the unit files), but these specifiers were influenced
+ by the Slice= option.
+
+ * The shell invoked by debug-shell.service now defaults to /bin/sh in
+ all cases. If distributions want to use a different shell for this
+ purpose (for example Fedora's /sbin/sushell) they need to specify
+ this explicitly at configure time using --with-debug-shell=.
+
+ * The confirmation spawn prompt has been reworked to offer the
+ following choices:
+
+ (c)ontinue, proceed without asking anymore
+ (D)ump, show the state of the unit
+ (f)ail, don't execute the command and pretend it failed
+ (h)elp
+ (i)nfo, show a short summary of the unit
+ (j)obs, show jobs that are in progress
+ (s)kip, don't execute the command and pretend it succeeded
+ (y)es, execute the command
+
+ The 'n' choice for the confirmation spawn prompt has been removed,
+ because its meaning was confusing.
+
+ The prompt may now also be redirected to an alternative console by
+ specifying the console as parameter to systemd.confirm_spawn=.
+
+ * Services of Type=notify require a READY=1 notification to be sent
+ during startup. If no such message is sent, the service now fails,
+ even if the main process exited with a successful exit code.
+
+ * Services that fail to start up correctly now always have their
+ ExecStopPost= commands executed. Previously, they'd enter "failed"
+ state directly, without executing these commands.
+
+ * The option MulticastDNS= of network configuration files has acquired
+ an actual implementation. With MulticastDNS=yes a host can resolve
+ names of remote hosts and reply to mDNS A and AAAA requests.
+
+ * When units are about to be started an additional check is now done to
+ ensure that all dependencies of type BindsTo= (when used in
+ combination with After=) have been started.
+
+ * systemd-analyze gained a new verb "syscall-filter" which shows which
+ system call groups are defined for the SystemCallFilter= unit file
+ setting, and which system calls they contain.
+
+ * A new system call filter group "@filesystem" has been added,
+ consisting of various file system related system calls. Group
+ "@reboot" has been added, covering reboot, kexec and shutdown related
+ calls. Finally, group "@swap" has been added covering swap
+ configuration related calls.
+
+ * A new unit file option RestrictNamespaces= has been added that may be
+ used to restrict access to the various process namespace types the
+ Linux kernel provides. Specifically, it may be used to take away the
+ right for a service unit to create additional file system, network,
+ user, and other namespaces. This sandboxing option is particularly
+ relevant due to the high amount of recently discovered namespacing
+ related vulnerabilities in the kernel.
+
+ * systemd-udev's .link files gained support for a new AutoNegotiation=
+ setting for configuring Ethernet auto-negotiation.
+
+ * systemd-networkd's .network files gained support for a new
+ ListenPort= setting in the [DHCP] section to explicitly configure the
+ UDP client port the DHCP client shall listen on.
+
+ * .network files gained a new Unmanaged= boolean setting for explicitly
+ excluding one or more interfaces from management by systemd-networkd.
+
+ * The systemd-networkd ProxyARP= option has been renamed to
+ IPV4ProxyARP=. Similarly, VXLAN-specific option ARPProxy= has been
+ renamed to ReduceARPProxy=. The old names continue to be available
+ for compatibility.
+
+ * systemd-networkd gained support for configuring IPv6 Proxy NDP
+ addresses via the new IPv6ProxyNDPAddress= .network file setting.
+
+ * systemd-networkd's bonding device support gained support for two new
+ configuration options ActiveSlave= and PrimarySlave=.
+
+ * The various options in the [Match] section of .network files gained
+ support for negative matching.
+
+ * New systemd-specific mount options are now understood in /etc/fstab:
+
+ x-systemd.mount-timeout= may be used to configure the maximum
+ permitted runtime of the mount command.
+
+ x-systemd.device-bound may be set to bind a mount point to its
+ backing device unit, in order to automatically remove a mount point
+ if its backing device is unplugged. This option may also be
+ configured through the new SYSTEMD_MOUNT_DEVICE_BOUND udev property
+ on the block device, which is now automatically set for all CDROM
+ drives, so that mounted CDs are automatically unmounted when they are
+ removed from the drive.
+
+ x-systemd.after= and x-systemd.before= may be used to explicitly
+ order a mount after or before another unit or mount point.
+
+ * Enqueued start jobs for device units are now automatically garbage
+ collected if there are no jobs waiting for them anymore.
+
+ * systemctl list-jobs gained two new switches: with --after, for every
+ queued job the jobs it's waiting for are shown; with --before the
+ jobs which it's blocking are shown.
+
+ * systemd-nspawn gained support for ephemeral boots from disk images
+ (or in other words: --ephemeral and --image= may now be
+ combined). Moreover, ephemeral boots are now supported for normal
+ directories, even if the backing file system is not btrfs. Of course,
+ if the file system does not support file system snapshots or
+ reflinks, the initial copy operation will be relatively expensive, but
+ this should still be suitable for many use cases.
+
+ * Calendar time specifications in .timer units now support
+ specifications relative to the end of a month by using "~" instead of
+ "-" as separator between month and day. For example, "*-02~03" means
+ "the third last day in February". In addition a new syntax for
+ repeated events has been added using the "/" character. For example,
+ "9..17/2:00" means "every two hours from 9am to 5pm".
+
+ * systemd-socket-proxyd gained a new parameter --connections-max= for
+ configuring the maximum number of concurrent connections.
+
+ * sd-id128 gained a new API for generating unique IDs for the host in a
+ way that does not leak the machine ID. Specifically,
+ sd_id128_get_machine_app_specific() derives an ID based on the
+ machine ID a in well-defined, non-reversible, stable way. This is
+ useful whenever an identifier for the host is needed but where the
+ identifier shall not be useful to identify the system beyond the
+ scope of the application itself. (Internally this uses HMAC-SHA256 as
+ keyed hash function using the machine ID as input.)
+
+ * NotifyAccess= gained a new supported value "exec". When set
+ notifications are accepted from all processes systemd itself invoked,
+ including all control processes.
+
+ * .nspawn files gained support for defining overlay mounts using the
+ Overlay= and OverlayReadOnly= options. Previously this functionality
+ was only available on the systemd-nspawn command line.
+
+ * systemd-nspawn's --bind= and --overlay= options gained support for
+ bind/overlay mounts whose source lies within the container tree by
+ prefixing the source path with "+".
+
+ * systemd-nspawn's --bind= and --overlay= options gained support for
+ automatically allocating a temporary source directory in /var/tmp
+ that is removed when the container dies. Specifically, if the source
+ directory is specified as empty string this mechanism is selected. An
+ example usage is --overlay=+/var::/var, which creates an overlay
+ mount based on the original /var contained in the image, overlayed
+ with a temporary directory in the host's /var/tmp. This way changes
+ to /var are automatically flushed when the container shuts down.
+
+ * systemd-nspawn --image= option does now permit raw file system block
+ devices (in addition to images containing partition tables, as
+ before).
+
+ * The disk image dissection logic in systemd-nspawn gained support for
+ automatically setting up LUKS encrypted as well as Verity protected
+ partitions. When a container is booted from an encrypted image the
+ passphrase is queried at start-up time. When a container with Verity
+ data is started, the root hash is search in a ".roothash" file
+ accompanying the disk image (alternatively, pass the root hash via
+ the new --root-hash= command line option).
+
+ * A new tool /usr/lib/systemd/systemd-dissect has been added that may
+ be used to dissect disk images the same way as systemd-nspawn does
+ it, following the Bootable Partition Specification. It may even be
+ used to mount disk images with complex partition setups (including
+ LUKS and Verity partitions) to a local host directory, in order to
+ inspect them. This tool is not considered public API (yet), and is
+ thus not installed into /usr/bin. Please do not rely on its
+ existence, since it might go away or be changed in later systemd
+ versions.
+
+ * A new generator "systemd-verity-generator" has been added, similar in
+ style to "systemd-cryptsetup-generator", permitting automatic setup of
+ Verity root partitions when systemd boots up. In order to make use of
+ this your partition setup should follow the Discoverable Partitions
+ Specification, and the GPT partition ID of the root file system
+ partition should be identical to the upper 128bit of the Verity root
+ hash. The GPT partition ID of the Verity partition protecting it
+ should be the lower 128bit of the Verity root hash. If the partition
+ image follows this model it is sufficient to specify a single
+ "roothash=" kernel command line argument to both configure which root
+ image and verity partition to use as well as the root hash for
+ it. Note that systemd-nspawn's Verity support follows the same
+ semantics, meaning that disk images with proper Verity data in place
+ may be booted in containers with systemd-nspawn as well as on
+ physical systems via the verity generator. Also note that the "mkosi"
+ tool available at https://github.com/systemd/mkosi has been updated
+ to generate Verity protected disk images following this scheme. In
+ fact, it has been updated to generate disk images that optionally
+ implement a complete UEFI SecureBoot trust chain, involving a signed
+ kernel and initrd image that incorporates such a root hash as well as
+ a Verity-enabled root partition.
+
+ * The hardware database (hwdb) udev supports has been updated to carry
+ accelerometer quirks.
+
+ * All system services are now run with a fresh kernel keyring set up
+ for them. The invocation ID is stored by default in it, thus
+ providing a safe, non-overridable way to determine the invocation
+ ID of each service.
+
+ * Service unit files gained new BindPaths= and BindReadOnlyPaths=
+ options for bind mounting arbitrary paths in a service-specific
+ way. When these options are used, arbitrary host or service files and
+ directories may be mounted to arbitrary locations in the service's
+ view.
+
+ * Documentation has been added that lists all of systemd's low-level
+ environment variables:
+
+ https://github.com/systemd/systemd/blob/master/ENVIRONMENT.md
+
+ * sd-daemon gained a new API sd_is_socket_sockaddr() for determining
+ whether a specific socket file descriptor matches a specified socket
+ address.
+
+ * systemd-firstboot has been updated to check for the
+ systemd.firstboot= kernel command line option. It accepts a boolean
+ and when set to false the first boot questions are skipped.
+
+ * systemd-fstab-generator has been updated to check for the
+ systemd.volatile= kernel command line option, which either takes an
+ optional boolean parameter or the special value "state". If used the
+ system may be booted in a "volatile" boot mode. Specifically,
+ "systemd.volatile" is used, the root directory will be mounted as
+ tmpfs, and only /usr is mounted from the actual root file system. If
+ "systemd.volatile=state" is used, the root directory will be mounted
+ as usual, but /var is mounted as tmpfs. This concept provides similar
+ functionality as systemd-nspawn's --volatile= option, but provides it
+ on physical boots. Use this option for implementing stateless
+ systems, or testing systems with all state and/or configuration reset
+ to the defaults. (Note though that many distributions are not
+ prepared to boot up without a populated /etc or /var, though.)
+
+ * systemd-gpt-auto-generator gained support for LUKS encrypted root
+ partitions. Previously it only supported LUKS encrypted partitions
+ for all other uses, except for the root partition itself.
+
+ * Socket units gained support for listening on AF_VSOCK sockets for
+ communication in virtualized QEMU environments.
+
+ * The "configure" script gained a new option --with-fallback-hostname=
+ for specifying the fallback hostname to use if none is configured in
+ /etc/hostname. For example, by specifying
+ --with-fallback-hostname=fedora it is possible to default to a
+ hostname of "fedora" on pristine installations.
+
+ * systemd-cgls gained support for a new --unit= switch for listing only
+ the control groups of a specific unit. Similar --user-unit= has been
+ added for listing only the control groups of a specific user unit.
+
+ * systemd-mount gained a new --umount switch for unmounting a mount or
+ automount point (and all mount/automount points below it).
+
+ * systemd will now refuse full configuration reloads (via systemctl
+ daemon-reload and related calls) unless at least 16MiB of free space
+ are available in /run. This is a safety precaution in order to ensure
+ that generators can safely operate after the reload completed.
+
+ * A new unit file option RootImage= has been added, which has a similar
+ effect as RootDirectory= but mounts the service's root directory from
+ a disk image instead of plain directory. This logic reuses the same
+ image dissection and mount logic that systemd-nspawn already uses,
+ and hence supports any disk images systemd-nspawn supports, including
+ those following the Discoverable Partition Specification, as well as
+ Verity enabled images. This option enables systemd to run system
+ services directly off disk images acting as resource bundles,
+ possibly even including full integrity data.
+
+ * A new MountAPIVFS= unit file option has been added, taking a boolean
+ argument. If enabled /proc, /sys and /dev (collectively called the
+ "API VFS") will be mounted for the service. This is only relevant if
+ RootDirectory= or RootImage= is used for the service, as these mounts
+ are of course in place in the host mount namespace anyway.
+
+ * systemd-nspawn gained support for a new --pivot-root= switch. If
+ specified the root directory within the container image is pivoted to
+ the specified mount point, while the original root disk is moved to a
+ different place. This option enables booting of ostree images
+ directly with systemd-nspawn.
+
+ * The systemd build scripts will no longer complain if the NTP server
+ addresses are not changed from the defaults. Google now supports
+ these NTP servers officially. We still recommend downstreams to
+ properly register an NTP pool with the NTP pool project though.
+
+ * coredumpctl gained new new "--reverse" option for printing the list
+ of coredumps in reverse order.
+
+ * coredumpctl will now show additional information about truncated and
+ inaccessible coredumps, as well as coredumps that are still being
+ processed. It also gained a new --quiet switch for suppressing
+ additional informational message in its output.
+
+ * coredumpctl gained support for only showing coredumps newer and/or
+ older than specific timestamps, using the new --since= and --until=
+ options, reminiscent of journalctl's options by the same name.
+
+ * The systemd-coredump logic has been improved so that it may be reused
+ to collect backtraces in non-compiled languages, for example in
+ scripting languages such as Python.
+
+ * machinectl will now show the UID shift of local containers, if user
+ namespacing is enabled for them.
+
+ * systemd will now optionally run "environment generator" binaries at
+ configuration load time. They may be used to add environment
+ variables to the environment block passed to services invoked. One
+ user environment generator is shipped by default that sets up
+ environment variables based on files dropped into /etc/environment.d
+ and ~/.config/environment.d/.
+
+ * systemd-resolved now includes the new, recently published 2017 DNSSEC
+ root key (KSK).
+
+ * hostnamed has been updated to report a new chassis type of
+ "convertible" to cover "foldable" laptops that can both act as a
+ tablet and as a laptop, such as various Lenovo Yoga devices.
+
+ Contributions from: Adrián López, Alexander Galanin, Alexander
+ Kochetkov, Alexandros Frantzis, Andrey Ulanov, Antoine Eiche, Baruch
+ Siach, Bastien Nocera, Benjamin Robin, Björn, Brandon Philips, Cédric
+ Schieli, Charles (Chas) Williams, Christian Hesse, Daniele Medri,
+ Daniel Drake, Daniel Rusek, Daniel Wagner, Dan Streetman, Dave Reisner,
+ David Glasser, David Herrmann, David Michael, Djalal Harouni, Dmitry
+ Khlebnikov, Dmitry Rozhkov, Dongsu Park, Douglas Christman, Earnestly,
+ Emil Soleyman, Eric Cook, Evgeny Vereshchagin, Felipe Sateler, Fionn
+ Cleary, Florian Klink, Francesco Brozzu, Franck Bui, Gabriel Rauter,
+ Gianluca Boiano, Giedrius StatkeviÄius, Graeme Lawes, Hans de Goede,
+ Harald Hoyer, Ian Kelling, Ivan Shapovalov, Jakub Wilk, Janne Heß, Jan
+ Synacek, Jason Reeder, Jonathan Boulle, Jörg Thalheim, Jouke Witteveen,
+ Karl Kraus, Kees Cook, Keith Busch, Kieran Colford, kilian-k, Lennart
+ Poettering, Lubomir Rintel, Lucas Werkmeister, Lukas Rusak, Maarten de
+ Vries, Maks Naumov, Mantas MikulÄ—nas, Marc-Andre Lureau, Marcin Bachry,
+ Mark Stosberg, Martin Ejdestig, Martin Pitt, Mauricio Faria de
+ Oliveira, micah, Michael Biebl, Michael Shields, Michal Schmidt, Michal
+ Sekletar, Michel Kraus, Mike Gilbert, Mikko Ylinen, Mirza Krak,
+ Namhyung Kim, nikolaof, peoronoob, Peter Hutterer, Peter Körner, Philip
+ Withnall, Piotr DrÄ…g, Ray Strode, Reverend Homer, Rike-Benjamin
+ Schuppner, Robert Kreuzer, Ronny Chevalier, Ruslan Bilovol, sammynx,
+ Sergey Ptashnick, Sergiusz Urbaniak, Stefan Berger, Stefan Hajnoczi,
+ Stefan Schweter, Stuart McLaren, Susant Sahani, Sylvain Plantefève,
+ Taylor Smock, Tejun Heo, Thomas Blume, Thomas H. P. Andersen, Tibor
+ Nagy, Tobias Stoeckmann, Tom Gundersen, Torstein Husebø, Viktar
+ VaÅ­ÄkieviÄ, Viktor Mihajlovski, Vitaly Sulimov, Waldemar Brodkorb,
+ Walter Garcia-Fontes, Wim de With, Yassine Imounachen, Yi EungJun,
+ YunQiang Su, Yu Watanabe, Zbigniew JÄ™drzejewski-Szmek, ÐлекÑандр
+ Тихонов
+
+ — Berlin, 2017-03-01
+
CHANGES WITH 232:
+ * udev now runs with MemoryDenyWriteExecute=, RestrictRealtime= and
+ RestrictAddressFamilies= enabled. These sandboxing options should
+ generally be compatible with the various external udev call-out
+ binaries we are aware of, however there may be exceptions, in
+ particular when exotic languages for these call-outs are used. In
+ this case, consider turning off these settings locally.
+
* The new RemoveIPC= option can be used to remove IPC objects owned by
the user or group of a service when that service exits.
@@ -1853,7 +2273,7 @@ CHANGES WITH 220:
gudev from the Gnome project instead. gudev is still included
in systemd, for now. It will be removed soon, though. Please
also see the announcement-thread on systemd-devel:
- http://lists.freedesktop.org/archives/systemd-devel/2015-May/032070.html
+ https://lists.freedesktop.org/archives/systemd-devel/2015-May/032070.html
* systemd now exposes a CPUUsageNSec= property for each
service unit on the bus, that contains the overall consumed
@@ -2895,7 +3315,7 @@ CHANGES WITH 216:
like Cockpit which register web clients as PAM sessions.
* timer units with at least one OnCalendar= setting will now
- be started only after timer-sync.target has been
+ be started only after time-sync.target has been
reached. This way they will not elapse before the system
clock has been corrected by a local NTP client or
similar. This is particular useful on RTC-less embedded
@@ -3756,7 +4176,7 @@ CHANGES WITH 211:
also supports LUKS-encrypted partitions now. With this in
place, automatic discovery of partitions to mount following
the Discoverable Partitions Specification
- (http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec)
+ (https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec)
is now a lot more complete. This allows booting without
/etc/fstab and without root= on the kernel command line on
systems prepared appropriately.
@@ -5108,7 +5528,7 @@ CHANGES WITH 199:
* A new libsystemd-bus module has been added that implements a
pretty complete D-Bus client library. For details see:
- http://lists.freedesktop.org/archives/systemd-devel/2013-March/009797.html
+ https://lists.freedesktop.org/archives/systemd-devel/2013-March/009797.html
* journald will now explicitly flush the journal files to disk
at the latest 5min after each write. The file will then also
@@ -5258,7 +5678,7 @@ CHANGES WITH 198:
only in conjunction with Gummiboot, but could be supported
by other boot loaders too. For details see:
- http://www.freedesktop.org/wiki/Software/systemd/BootLoaderInterface
+ https://www.freedesktop.org/wiki/Software/systemd/BootLoaderInterface
* A new generator has been added that automatically mounts the
EFI System Partition (ESP) to /boot, if that directory
@@ -5334,7 +5754,7 @@ CHANGES WITH 198:
* A new tool kernel-install has been added that can install
kernel images according to the Boot Loader Specification:
- http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec
+ https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec
* Boot time console output has been improved to provide
animated boot time output for hanging jobs.
@@ -5424,7 +5844,7 @@ CHANGES WITH 197:
of these policies is now the default. Please see this wiki
document for details:
- http://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames
+ https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames
* Auke Kok's bootchart implementation has been added to the
systemd tree. It is an optional component that can graph the
@@ -5572,7 +5992,7 @@ CHANGES WITH 196:
indexed database to link up additional information with
journal entries. For further details please check:
- http://www.freedesktop.org/wiki/Software/systemd/catalog
+ https://www.freedesktop.org/wiki/Software/systemd/catalog
The indexed message catalog database also needs to be
rebuilt after installation of message catalog files. Use
@@ -6424,7 +6844,7 @@ CHANGES WITH 183:
* A framework for implementing offline system updates is now
integrated, for details see:
- http://freedesktop.org/wiki/Software/systemd/SystemUpdates
+ https://www.freedesktop.org/wiki/Software/systemd/SystemUpdates
* A new service type Type=idle is available now which helps us
avoiding ugly interleaving of getty output and boot status
@@ -6705,7 +7125,7 @@ CHANGES WITH 39:
* New unit file option ControlGroupPersistent= to make cgroups
persistent, following the mechanisms outlined in
- http://www.freedesktop.org/wiki/Software/systemd/PaxControlGroups
+ https://www.freedesktop.org/wiki/Software/systemd/PaxControlGroups
* Support multiple local RTCs in a sane way
@@ -6792,7 +7212,7 @@ CHANGES WITH 38:
* Processes with '@' in argv[0][0] are now excluded from the
final shut-down killing spree, following the logic explained
in:
- http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons
+ https://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons
* All processes remaining in a service cgroup when we enter
the START or START_PRE states are now killed with
diff --git a/README b/README
index 9f5bc93827..a4a6493959 100644
--- a/README
+++ b/README
@@ -4,7 +4,7 @@ DETAILS:
http://0pointer.de/blog/projects/systemd.html
WEB SITE:
- http://www.freedesktop.org/wiki/Software/systemd
+ https://www.freedesktop.org/wiki/Software/systemd
GIT:
git@github.com:systemd/systemd.git
@@ -14,7 +14,7 @@ GITWEB:
https://github.com/systemd/systemd
MAILING LIST:
- http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+ https://lists.freedesktop.org/mailman/listinfo/systemd-devel
IRC:
#systemd on irc.freenode.org
@@ -50,6 +50,11 @@ REQUIREMENTS:
CONFIG_PROC_FS
CONFIG_FHANDLE (libudev, mount and bind mount handling)
+ Kernel crypto/hash API
+ CONFIG_CRYPTO_USER_API_HASH
+ CONFIG_CRYPTO_HMAC
+ CONFIG_CRYPTO_SHA256
+
udev will fail to work with the legacy sysfs layout:
CONFIG_SYSFS_DEPRECATED=n
@@ -67,12 +72,15 @@ REQUIREMENTS:
create additional symlinks in /dev/disk/ and /dev/tape:
CONFIG_BLK_DEV_BSG
- Required for PrivateNetwork and PrivateDevices in service units:
+ Required for PrivateNetwork= and PrivateDevices= in service units:
CONFIG_NET_NS
CONFIG_DEVPTS_MULTIPLE_INSTANCES
Note that systemd-localed.service and other systemd units use
PrivateNetwork and PrivateDevices so this is effectively required.
+ Required for PrivateUsers= in service units:
+ CONFIG_USER_NS
+
Optional but strongly recommended:
CONFIG_IPV6
CONFIG_AUTOFS4_FS
@@ -143,6 +151,8 @@ REQUIREMENTS:
util-linux >= v2.27.1 required
dbus >= 1.4.0 (strictly speaking optional, but recommended)
+ NOTE: If using dbus < 1.9.18, you should override the default
+ policy directory (--with-dbuspolicydir=/etc/dbus-1/system.d).
dracut (optional)
PolicyKit (optional)
@@ -175,6 +185,7 @@ REQUIREMENTS:
- python3-pyparsing
- python3-evdev (used by hwdb parsing tests)
- strace (used by test/test-functions)
+ - capsh (optional, used by test-execute)
USERS AND GROUPS:
Default udev rules use the following standard system group
@@ -263,18 +274,13 @@ WARNINGS:
requires that /var/run is a symlink to /run.
For more information on this issue consult
- http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken
+ https://www.freedesktop.org/wiki/Software/systemd/separate-usr-is-broken
To run systemd under valgrind, compile with VALGRIND defined
(e.g. ./configure CPPFLAGS='... -DVALGRIND=1'). Otherwise,
false positives will be triggered by code which violates
some rules but is actually safe.
- Currently, systemd-timesyncd defaults to use the Google NTP
- servers if not specified otherwise at configure time. You
- really should not ship an OS or device with this default
- setting. See DISTRO_PORTING for details.
-
ENGINEERING AND CONSULTING SERVICES:
Kinvolk (https://kinvolk.io) offers professional engineering
and consulting services for systemd. Please contact Chris Kühl
diff --git a/README.md b/README.md
index 35ab9663ca..82fb799b42 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
## Details
-General information about systemd can be found in the [systemd Wiki](http://www.freedesktop.org/wiki/Software/systemd).
+General information about systemd can be found in the [systemd Wiki](https://www.freedesktop.org/wiki/Software/systemd).
Information about build requirements are provided in the [README file](../master/README).
@@ -17,4 +17,4 @@ Please see our [Contribution Guidelines](../master/.github/CONTRIBUTING.md) for
When preparing patches for systemd, please follow our [Coding Style Guidelines](../master/CODING_STYLE).
-If you are looking for support, please contact our [mailing list](http://lists.freedesktop.org/mailman/listinfo/systemd-devel) or join our [IRC channel](irc://irc.freenode.org/%23systemd).
+If you are looking for support, please contact our [mailing list](https://lists.freedesktop.org/mailman/listinfo/systemd-devel) or join our [IRC channel](irc://irc.freenode.org/%23systemd).
diff --git a/TODO b/TODO
index c8266a549d..3cf4ce393c 100644
--- a/TODO
+++ b/TODO
@@ -12,9 +12,6 @@ Bugfixes:
Environment=ONE='one' "TWO='two two' too" THREE=
ExecStart=/bin/python3 -c 'import sys;print(sys.argv)' $ONE $TWO $THREE
-* When systemctl --host is used, underlying ssh connection can remain open.
- bus_close does not kill children?
-
External:
* Fedora: add an rpmlint check that verifies that all unit files in the RPM are listed in %systemd_post macros.
@@ -23,15 +20,102 @@ External:
Janitorial Clean-ups:
-* code cleanup: retire FOREACH_WORD_QUOTED, port to extract_first_word() loops instead.
- For example, most conf parsing callbacks should use it.
-
-* replace manual readdir() loops with FOREACH_DIRENT or FOREACH_DIRENT_ALL
-
* Rearrange tests so that the various test-xyz.c match a specific src/basic/xyz.c again
Features:
+* sort generated hwdb files alphabetically when we import them, so that git
+ diffs remain minimal (in particular: the OUI databases we import are not
+ sorted, and not stable)
+
+* set SystemCallArchitectures=native on all our services
+
+* maybe add call sd_journal_set_block_timeout() or so to set SO_SNDTIMEO for
+ the sd-journal logging socket, and, if the timeout is set to 0, sets
+ O_NONBLOCK on it. That way people can control if and when to block for
+ logging.
+
+* tighten sd_notify() MAINPID= checks a bit: don't accept foreign PIDs (i.e.
+ PIDs not managed by the service manager)
+
+* journald: when we recv a log datagram via the native or syslog transports,
+ search for the PID in the active stream connections, and let's make sure to
+ always process the datagrams before the streams. Then, cache client metadata
+ per stream in the stream object. This way we can somewhat fix the race with
+ quickly exiting processes which log as long as they had their own stream
+ connection...
+
+* hostnamed: populate form factor data from a new hwdb database, so that old
+ yogas can be recognized as "convertible" too, even if they predate the DMI
+ "convertible" form factor
+
+* Maybe add a small tool invoked early at boot, that adds in or resizes
+ partitions automatically, to be used when the media used is actually larger
+ than the image written onto it is.
+
+* Maybe add PrivatePIDs= as new unit setting, and do minimal PID namespacing
+ after all. Be strict however, only support the equivalent of nspawn's
+ --as-pid2 switch, and sanely proxy sd_notify() messages dropping stuff such
+ as MAINPID.
+
+* change the dependency Set* objects in Unit structures to become Hashmap*, and
+ then store a bit mask who created a specific dependency: the source unit via
+ fragment configuration, the destination unit via fragment configuration, or
+ the source unit via udev rules (in case of .device units), or any combination
+ thereof. This information can then be used to flush out old udev-created
+ dependencies when the udev properties change, and eventually to implement a
+ "systemctl refresh" operation for reloading the configuration of individual
+ units without reloading the whole set.
+
+* Add ExecMonitor= setting. May be used multiple times. Forks off a process in
+ the service cgroup, which is supposed to monitor the service, and when it
+ exits the service is considered failed by its monitor.
+
+* track the per-service PAM process properly (i.e. as an additional control
+ process), so that it may be queried on the bus and everything.
+
+* add a new "debug" job mode, that is propagated to unit_start() and for
+ services results in two things: we raise SIGSTOP right before invoking
+ execve() and turn off watchdog support. Then, use that to implement
+ "systemd-gdb" for attaching to the start-up of any system service in its
+ natural habitat.
+
+* replace all canonicalize_file_name() invocations by chase_symlinks(), in
+ particulr those where a rootdir is relevant.
+
+* maybe introduce gpt auto discovery for /var/tmp?
+
+* set ProtectSystem=strict for all our usual services.
+
+* fix PrivateNetwork= so that we fall back gracefully on kernels lacking
+ namespacing support (similar for the other namespacing options)
+
+* maybe add gpt-partition-based user management: each user gets his own
+ LUKS-encrypted GPT partition with a new GPT type. A small nss module
+ enumerates users via udev partition enumeration. UIDs are assigned in a fixed
+ way: the partition index is added as offset to some fixed base uid. User name
+ is stored in GPT partition name. A PAM module authenticates the user via the
+ LUKS partition password. Benefits: strong per-user security, compatibility
+ with stateless/read-only/verity-enabled root. (other idea: do this based on
+ loopback files in /home, without GPT involvement)
+
+* gpt-auto logic: introduce support for discovering /var matching an image. For
+ that, use a partition type UUID that is hashed from the OS name (as encoded
+ in /etc/os-release), the architecture, and 4 new bits from the gpt flags
+ field of the root partition. This way can easily support multiple OS
+ installations on the same GPT partition table, without problems with
+ unmatched /var partitions.
+
+* gpt-auto logic: related to the above, maybe support a "secondary" root
+ partition, that is mounted to / and is writable, and where the actual root's
+ /usr is mounted into.
+
+* machined: add apis to query /etc/machine-info data of a container
+
+* .mount and .swap units: add Format=yes|no option that formats the partition before mounting/enabling it, implicitly
+
+* gpt-auto logic: support encrypted swap, add kernel cmdline option to force it, and honour a gpt bit about it, plus maybe a configuration file
+
* drop nss-myhostname in favour of nss-resolve?
* drop internal dlopen() based nss-dns fallback in nss-resolve, and rely on the
@@ -49,8 +133,6 @@ Features:
* switch to ProtectSystem=strict for all our long-running services where that's possible
-* If RootDirectory= is used, mount /proc, /sys, /dev into it, if not mounted yet
-
* Permit masking specific netlink APIs with RestrictAddressFamily=
* nspawn: start UID allocation loop from hash of container name
@@ -59,14 +141,10 @@ Features:
* define gpt header bits to select volatility mode
-* nspawn: mount loopback filesystems with "discard"
-
* ProtectKernelLogs= (drops CAP_SYSLOG, add seccomp for syslog() syscall, and DeviceAllow to /dev/kmsg) in service files
* ProtectClock= (drops CAP_SYS_TIMES, adds seecomp filters for settimeofday, adjtimex), sets DeviceAllow o /dev/rtc
-* ProtectKernelModules= (drops CAP_SYS_MODULE and filters the kmod syscalls)
-
* ProtectTracing= (drops CAP_SYS_PTRACE, blocks ptrace syscall, makes /sys/kernel/tracing go away)
* ProtectMount= (drop mount/umount/pivot_root from seccomp, disallow fuse via DeviceAllow, imply Mountflags=slave)
@@ -84,12 +162,6 @@ Features:
* Add DataDirectory=, CacheDirectory= and LogDirectory= to match
RuntimeDirectory=, and create it as necessary when starting a service, owned by the right user.
-* Add BindDirectory= for allowing arbitrary, private bind mounts for services
-
-* Add RootImage= for mounting a disk image or file as root directory
-
-* RestrictNamespaces= or so in services (taking away the ability to create namespaces, with setns, unshare, clone)
-
* make sure the ratelimit object can deal with USEC_INFINITY as way to turn off things
* journalctl: make sure -f ends when the container indicated by -M terminates
@@ -124,8 +196,6 @@ Features:
* journald: sigbus API via a signal-handler safe function that people may call
from the SIGBUS handler
-* move specifier expansion from service_spawn() into load-fragment.c
-
* optionally, also require WATCHDOG=1 notifications during service start-up and shutdown
* resolved: when routing queries, make sure only look for the *longest* suffix...
@@ -274,7 +344,6 @@ Features:
* support empty /etc boots nicely:
- nspawn/gpt-generator: introduce new gpt partition type for /usr
- - fstab-generator: support systemd.volatile=yes|no|state on the kernel cmdline, too, similar to nspawn's --volatile=
* generator that automatically discovers btrfs subvolumes, identifies their purpose based on some xattr on them.
@@ -287,12 +356,9 @@ Features:
* For timer units: add some mechanisms so that timer units that trigger immediately on boot do not have the services
they run added to the initial transaction and thus confuse Type=idle.
-* Run most system services with cgroupfs read-only and procfs with a more secure mode (doesn't work, since the hidepid= option is per-pid-namespace, not per-mount)
-
* add bus api to query unit file's X fields.
* gpt-auto-generator:
- - Support LUKS for root devices
- Define new partition type for encrypted swap? Support probed LUKS for encrypted swap?
- Make /home automount rather than mount?
@@ -350,8 +416,6 @@ Features:
* refuse boot if /usr/lib/os-release is missing or /etc/machine-id cannot be set up
-* btrfs raid assembly: some .device jobs stay stuck in the queue
-
* man: the documentation of Restart= currently is very misleading and suggests the tools from ExecStartPre= might get restarted.
* load .d/*.conf dropins for device units
@@ -569,7 +633,6 @@ Features:
- man: maybe sort directives in man pages, and take sections from --help and apply them to man too
* systemctl:
- - systemctl list-jobs - show dependencies
- add systemctl switch to dump transaction without executing it
- Add a verbose mode to "systemctl start" and friends that explains what is being done or not done
- "systemctl disable" on a static unit prints no message and does
@@ -590,7 +653,6 @@ Features:
- timer units should get the ability to trigger when:
o CLOCK_REALTIME makes jumps (TFD_TIMER_CANCEL_ON_SET)
o DST changes
- - Support 2012-02~4 as syntax for specifying the fourth to last day of the month.
- Modulate timer frequency based on battery state
* add libsystemd-password or so to query passwords during boot using the password agent logic
@@ -599,15 +661,13 @@ Features:
* on shutdown: move utmp, wall, audit logic all into PID 1 (or logind?), get rid of systemd-update-utmp-runlevel
-* make repeated alt-ctrl-del presses printing a dump, or even force a reboot without
- waiting for the timeout
+* make repeated alt-ctrl-del presses printing a dump
* hostnamed: before returning information from /etc/machine-info.conf check the modification data and reread. Similar for localed, ...
* currently x-systemd.timeout is lost in the initrd, since crypttab is copied into dracut, but fstab is not
* nspawn:
- - nspawn -x should support ephemeral instances of gpt images
- emulate /dev/kmsg using CUSE and turn off the syslog syscall
with seccomp. That should provide us with a useful log buffer that
systemd can log to during early boot, and disconnect container logs
@@ -630,6 +690,10 @@ Features:
- maybe make copying of /etc/resolv.conf optional, and skip it if --read-only
is used
+* dissect
+ - refuse mounting over a mount point
+ - automatically discover .roothash files in dissect, similarly to nspawn
+
* machined:
- add an API so that libvirt-lxc can inform us about network interfaces being
removed or added to an existing machine
@@ -744,7 +808,6 @@ Features:
- maybe introduce WantsMountsFor=? Usecase:
http://lists.freedesktop.org/archives/systemd-devel/2015-January/027729.html
- recreate systemd's D-Bus private socket file on SIGUSR2
- - GC unreferenced jobs (such as .device jobs)
- move PAM code into its own binary
- when we automatically restart a service, ensure we restart its rdeps, too.
- hide PAM options in fragment parser when compile time disabled
diff --git a/catalog/systemd.be.catalog.in b/catalog/systemd.be.catalog.in
index 5b237f0558..5b1cdf2492 100644
--- a/catalog/systemd.be.catalog.in
+++ b/catalog/systemd.be.catalog.in
@@ -20,7 +20,7 @@
# Belarusian translation
# Фармат каталога апіÑаны на Ñтаронцы
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# For an explanation why we do all this, see https://xkcd.com/1024/
@@ -94,7 +94,7 @@ Documentation: man:core(5)
Subject: ÐÐ¾Ð²Ð°Ñ ÑеÑÑ–Ñ â„– @SESSION_ID@ Ñтворана Ð´Ð»Ñ ÐºÐ°Ñ€Ñ‹Ñтальніка @USER_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
ÐÐ¾Ð²Ð°Ñ ÑеÑÑ–Ñ Ð· â„– @SESSION_ID@ Ñтворана Ð´Ð»Ñ ÐºÐ°Ñ€Ñ‹Ñтальніка @USER_ID@.
@@ -104,7 +104,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: СеÑÑ–Ñ â„– @SESSION_ID@ Ñпынена
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
СеÑÑ–Ñ â„– @SESSION_ID@ Ñпынена.
@@ -112,7 +112,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: ДаÑтупна новае працоўнае меÑца â„– @SEAT_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Ðовае працоўнае меÑца â„– @SEAT_ID@ наладжана Ñ– даÑтупна Ð´Ð»Ñ Ð²Ñ‹ÐºÐ°Ñ€Ñ‹ÑтаннÑ.
@@ -120,7 +120,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: Працоўнае меÑца â„– @SEAT_ID@ выдалена
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Працоўнае меÑца â„– @SEAT_ID@ выдалена Ñ– больш не даÑтупна.
diff --git a/catalog/systemd.be@latin.catalog.in b/catalog/systemd.be@latin.catalog.in
index fc9f7cad16..764432c0dc 100644
--- a/catalog/systemd.be@latin.catalog.in
+++ b/catalog/systemd.be@latin.catalog.in
@@ -20,7 +20,7 @@
# Belarusian Latin translation
# Farmat kataloha apisany na staroncy
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# For an explanation why we do all this, see https://xkcd.com/1024/
@@ -95,7 +95,7 @@ Rekamiendujecca paviedamić ab hetym raspracoŭnikam.
Subject: Novaja siesija № @SESSION_ID@ stvorana dlia karystaĺnika @USER_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Novaja siesija z № @SESSION_ID@ stvorana dlia karystaĺnika @USER_ID@.
@@ -105,7 +105,7 @@ Lidar hetaj siesii pad â„– @LEADER@.
Subject: Siesija â„– @SESSION_ID@ spyniena
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Siesija â„– @SESSION_ID@ spyniena.
@@ -113,7 +113,7 @@ Siesija â„– @SESSION_ID@ spyniena.
Subject: Dastupna novaje pracoÅ­naje miesca â„– @SEAT_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Novaje pracoŭnaje miesca № @SEAT_ID@ naladžana i dastupna dlia
vykarystannia.
@@ -122,7 +122,7 @@ vykarystannia.
Subject: PracoÅ­naje miesca â„– @SEAT_ID@ vydaliena
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Pracoŭnaje miesca № @SEAT_ID@ vydaliena i boĺš nie dastupna.
diff --git a/catalog/systemd.bg.catalog.in b/catalog/systemd.bg.catalog.in
index 76b0ce8f17..4b6cf118be 100644
--- a/catalog/systemd.bg.catalog.in
+++ b/catalog/systemd.bg.catalog.in
@@ -19,7 +19,7 @@
# Message catalog for systemd's own messages
# The catalog format is documented on
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# For an explanation why we do all this, see https://xkcd.com/1024/
@@ -95,7 +95,7 @@ Documentation: man:core(5)
Subject: Създадена е нова ÑеÑÐ¸Ñ â„–â€Š@SESSION_ID@ за Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ñ â€ž@USER_ID@“
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
За Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ñ â€ž@USER_ID@“ е Ñъздадена нова ÑеÑÐ¸Ñ â„–â€Š@SESSION_ID@.
@@ -105,7 +105,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: СеÑÐ¸Ñ â„–â€Š@SESSION_ID@ приключи
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
СеÑÐ¸Ñ â„–â€Š@SESSION_ID@ приключи работа.
@@ -113,7 +113,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: Ðалично е ново работно мÑÑто № @SEAT_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Ðовото работно мÑÑто № @SEAT_ID@ е наÑтроено и готово за работа.
@@ -121,7 +121,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: Работното мÑÑто № @SEAT_ID@ е премахнато
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Работното мÑÑто № @SEAT_ID@ вече не е налично.
diff --git a/catalog/systemd.catalog.in b/catalog/systemd.catalog.in
index 2c72d31290..9cd3e6bac3 100644
--- a/catalog/systemd.catalog.in
+++ b/catalog/systemd.catalog.in
@@ -18,7 +18,7 @@
# Message catalog for systemd's own messages
# The catalog format is documented on
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# For an explanation why we do all this, see https://xkcd.com/1024/
@@ -115,7 +115,7 @@ als Fehler dem jeweiligen Hersteller gemeldet werden.
Subject: A new session @SESSION_ID@ has been created for user @USER_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
A new session with the ID @SESSION_ID@ has been created for the user @USER_ID@.
@@ -125,7 +125,7 @@ The leading process of the session is @LEADER@.
Subject: Session @SESSION_ID@ has been terminated
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
A session with the ID @SESSION_ID@ has been terminated.
@@ -133,7 +133,7 @@ A session with the ID @SESSION_ID@ has been terminated.
Subject: A new seat @SEAT_ID@ is now available
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
A new seat @SEAT_ID@ has been configured and is now available.
@@ -141,7 +141,7 @@ A new seat @SEAT_ID@ has been configured and is now available.
Subject: Seat @SEAT_ID@ has now been removed
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
A seat @SEAT_ID@ has been removed and is no longer available.
@@ -172,8 +172,8 @@ Defined-By: systemd
Support: %SUPPORT_URL%
All system services necessary queued for starting at boot have been
-successfully started. Note that this does not mean that the machine is
-now idle as services might still be busy with completing start-up.
+started. Note that this does not mean that the machine is now idle as services
+might still be busy with completing start-up.
Kernel start-up required @KERNEL_USEC@ microseconds.
@@ -181,6 +181,17 @@ Initial RAM disk start-up required @INITRD_USEC@ microseconds.
Userspace start-up required @USERSPACE_USEC@ microseconds.
+-- eed00a68ffd84e31882105fd973abdd1
+Subject: User manager start-up is now complete
+Defined-By: systemd
+Support: %SUPPORT_URL%
+
+The user manager instance for user @_UID@ has been started. All services queued
+for starting have been started. Note that other services might still be starting
+up or be started at any later time.
+
+Startup of the manager took @USERSPACE_USEC@ microseconds.
+
-- 6bbd95ee977941e497c48be27c254128
Subject: System sleep state @SLEEP@ entered
Defined-By: systemd
diff --git a/catalog/systemd.da.catalog.in b/catalog/systemd.da.catalog.in
index bc7d94476f..a5570f47d5 100644
--- a/catalog/systemd.da.catalog.in
+++ b/catalog/systemd.da.catalog.in
@@ -19,7 +19,7 @@
# Danish translation
# The catalog format is documented on
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# For an explanation why we do all this, see https://xkcd.com/1024/
@@ -79,7 +79,7 @@ og burde blive reporteret som en bug til folkene bag
Subject: En ny session @SESSION_ID@ er blevet lavet for bruger @USER_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
En ny session med ID @SESSION_ID@ er blevet lavet for brugeren @USER_ID@.
@@ -89,7 +89,7 @@ Den ledende process for sessionen er @LEADER@.
Subject: Session @SESSION_ID@ er blevet lukket ned
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
En session med ID @SESSION_ID@ er blevet lukket ned.
@@ -97,7 +97,7 @@ En session med ID @SESSION_ID@ er blevet lukket ned.
Subject: En ny arbejdsstation $SEAT_ID@ er nu tilgængelig
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
En ny arbejdsstation @SEAT_ID@ er blevet konfigureret og er nu tilgængelig.
@@ -105,7 +105,7 @@ En ny arbejdsstation @SEAT_ID@ er blevet konfigureret og er nu tilgængelig.
Subject: Arbejdsstation @SEAT_ID@ er nu blevet fjernet
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
En arbejdsstation @SEAT_ID@ er blevet fjernet og er ikke længere tilgængelig.
diff --git a/catalog/systemd.fr.catalog.in b/catalog/systemd.fr.catalog.in
index 573b288e74..c4b1a81ceb 100644
--- a/catalog/systemd.fr.catalog.in
+++ b/catalog/systemd.fr.catalog.in
@@ -1,7 +1,7 @@
# This file is part of systemd.
#
# Copyright 2012 Lennart Poettering
-# Copyright 2013-2015 Sylvain Plantefève
+# Copyright 2013-2016 Sylvain Plantefève
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
@@ -20,7 +20,7 @@
# French translation
# Le format du catalogue de messages est décrit (en anglais) içi :
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
-- f77379a8490b408bbe5f6940505a777b
Subject: Le journal a été démarré
@@ -96,7 +96,7 @@ incriminé, et cela devrait être notifié à son concepteur comme un défaut (b
Subject: Une nouvelle session @SESSION_ID@ a été créée pour l'utilisateur @USER_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Une nouvelle session a été créée pour l'utilisateur @USER_ID@ avec
l'identifiant (ID) @SESSION_ID@.
@@ -107,7 +107,7 @@ Le processus maître de la session est @LEADER@.
Subject: La session @SESSION_ID@ s'est terminée
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
La session d'identifiant (ID) @SESSION_ID@ s'est terminée.
@@ -115,7 +115,7 @@ La session d'identifiant (ID) @SESSION_ID@ s'est terminée.
Subject: Un nouveau poste (seat) @SEAT_ID@ est disponible
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Un nouveau poste (seat) @SEAT_ID@ a été configuré et est maintenant
disponible.
@@ -124,7 +124,7 @@ disponible.
Subject: Le poste (seat) @SEAT_ID@ a été retiré
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Le poste (seat) @SEAT_ID@ a été retiré et n'est plus disponible.
@@ -148,10 +148,9 @@ Subject: Le démarrage du système est terminé
Defined-By: systemd
Support: %SUPPORT_URL%
-Tous les services nécessaires au démarrage du système ont été lancés avec
-succès. Notez que cela ne signifie pas que le système est maintenant au
-repos, car des services peuvent encore être en train de terminer leur
-démarrage.
+Tous les services nécessaires au démarrage du système ont été lancés.
+Notez que cela ne signifie pas que le système est maintenant au repos,
+car des services peuvent encore être en train de terminer leur démarrage.
Le chargement du noyau a nécessité @KERNEL_USEC@ microsecondes.
@@ -159,6 +158,18 @@ Le chargement du « RAM disk » initial a nécessité @INITRD_USEC@ microseconde
Le chargement de l'espace utilisateur a nécessité @USERSPACE_USEC@ microsecondes.
+-- eed00a68ffd84e31882105fd973abdd1
+Subject: Le démarrage du gestionnaire utilisateur est terminé
+Defined-By: systemd
+Support: %SUPPORT_URL%
+
+L'instance du gestionnaire d'utilisateurs pour l'utilisateur @_UID@ a été démarrée.
+Tous les services en file d'attente pour démarrer ont été lancés.
+Notez que des services peuvent être encore en train de démarrer,
+ou d'autres être lancés à tout moment ultérieur.
+
+Le démarrage du gestionnaire a nécéssité @USERSPACE_USEC@ microsecondes.
+
-- 6bbd95ee977941e497c48be27c254128
Subject: Le système entre dans l'état de repos (sleep state) @SLEEP@
Defined-By: systemd
diff --git a/catalog/systemd.hr.catalog.in b/catalog/systemd.hr.catalog.in
index 7502aed741..d30e955e28 100644
--- a/catalog/systemd.hr.catalog.in
+++ b/catalog/systemd.hr.catalog.in
@@ -19,7 +19,7 @@
# Croatian translation
# Format kataloga je dokumentiran na
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# Za pojašnjenje zašto ovo radimo, posjetite https://xkcd.com/1024/
@@ -93,7 +93,7 @@ trebalo bi se prijaviti razvijatelju kao greška.
Subject: Nova sesija @SESSION_ID@ je stvorena za korisnika @USER_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Nova sesija sa ID @SESSION_ID@ je stvorena za korisnika @USER_ID@.
@@ -103,7 +103,7 @@ Glavni proces sesije je @LEADER@.
Subject: Sesija @SESSION_ID@ je prekinuta
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Sesija sa ID @SESSION_ID@ je prekinuta.
@@ -111,7 +111,7 @@ Sesija sa ID @SESSION_ID@ je prekinuta.
Subject: Novo sjedište @SEAT_ID@ je sada dostupno
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Novo sjedište @SEAT_ID@ je podešeno i sada je dostupno.
@@ -119,7 +119,7 @@ Novo sjedište @SEAT_ID@ je podešeno i sada je dostupno.
Subject: Sjedište @SEAT_ID@ je sada uklonjeno
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Sjedište @SEAT_ID@ je uklonjeno i više nije dostupno.
diff --git a/catalog/systemd.hu.catalog.in b/catalog/systemd.hu.catalog.in
index f538b7f958..23c1cd44db 100644
--- a/catalog/systemd.hu.catalog.in
+++ b/catalog/systemd.hu.catalog.in
@@ -19,7 +19,7 @@
# Message catalog for systemd's own messages
# The catalog format is documented on
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# For an explanation why we do all this, see https://xkcd.com/1024/
@@ -78,7 +78,7 @@ a szállítója felé kell bejelenteni.
Subject: Új munkamenet (@SESSION_ID@) létrehozva, felhasználója: @USER_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Létrejött egy új munkamenet @SESSION_ID@ azonosítóval ezen felhasználóhoz:
@USER_ID@.
@@ -89,7 +89,7 @@ A munkamenet vezető folyamata: @LEADER@.
Subject: Munkamenet (@SESSION_ID@) befejezve
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
A következő azonosítójú munkamenet befejeződött: @SESSION_ID@.
@@ -97,7 +97,7 @@ A következő azonosítójú munkamenet befejeződött: @SESSION_ID@.
Subject: Elérhető egy új munkaállomás: @SEAT_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Beállításra kerül és használható egy új munkaállomás: @SEAT_ID@.
@@ -105,7 +105,7 @@ Beállításra kerül és használható egy új munkaállomás: @SEAT_ID@.
Subject: A munkaállomás eltávolítva: @SEAT_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
A munkaállomás el lett távolítva, és már nem érhető el: @SEAT_ID@
diff --git a/catalog/systemd.it.catalog.in b/catalog/systemd.it.catalog.in
index 86e44a604d..208ac2bfdc 100644
--- a/catalog/systemd.it.catalog.in
+++ b/catalog/systemd.it.catalog.in
@@ -33,6 +33,21 @@ Support: %SUPPORT_URL%
Il processo relativo al registro di sistema è stato terminato e ha chiuso
tutti i file attivi.
+-- ec387f577b844b8fa948f33cad9a75e6
+Subject: Spazio disco utilizzato dal journal
+Defined-By: systemd
+Support: %SUPPORT_URL%
+
+@JOURNAL_NAME@ (@JOURNAL_PATH@) sta attualmente utilizzando @CURRENT_USE_PRETTY@.
+L'utilizzo massimo consentito è impostato a @MAX_USE_PRETTY@.
+Lasciando liberi almeno @DISK_KEEP_FREE_PRETTY@ (dell'attuale @DISK_AVAILABLE_PRETTY@ di spazio libero).
+Il limite di utilizzo forzato è quindi @LIMIT_PRETTY@, del quale @AVAILABLE_PRETTY@ sono ancora disponibili.
+
+I limiti di controllo dello spazio disco utilizzati dal Journal possono
+essere configurati con le impostazioni SystemMaxUse=, SystemKeepFree=, SystemMaxFileSize=,
+RuntimeMaxUse=, RuntimeKeepFree=, RuntimeMaxFileSize= nel file di configurazione
+/etc/systemd/journald.conf. Guardare journald.conf(5) per i dettagli.
+
-- a596d6fe7bfa4994828e72309e95d61e
Subject: I messaggi di un servizio sono stati soppressi
Defined-By: systemd
@@ -54,7 +69,7 @@ Subject: I messaggi di un servizio sono stati perduti
Defined-By: systemd
Support: %SUPPORT_URL%
-I messaggi del kernel sono stati perduti perché, il registro di sistema
+I messaggi del kernel sono andati persi perché, il registro di sistema
non è stato in grado di gestirli abbastanza velocemente.
-- fc2e22bc6ee647b6b90729ab34a250b1
@@ -68,11 +83,22 @@ Il processo @COREDUMP_PID@ (@COREDUMP_COMM@) si è bloccato generando un dump.
Questo di solito capita per un errore di programmazione nell'applicazione e
dovrebbe essere segnalato al vendor come un bug.
+-- 5aadd8e954dc4b1a8c954d63fd9e1137
+Subject: Il Core file è stato troncato a @SIZE_LIMIT@ bytes.
+Defined-By: systemd
+Support: %SUPPORT_URL%
+Documentation: man:coredump.conf(5)
+
+Il processo più memoria mappata del limite massimo configurato da systemd-coredump(8)
+per processare e memorizzare. Solo i primi @SIZE_LIMIT@ bytes sono stati salvati.
+Il file potrebbe essere ancora utile, ma strumenti come gdb(1) dovrebbero
+segnalare la troncatura.
+
-- 8d45620c1a4348dbb17410da57c60c66
Subject: La nuova sessione @SESSION_ID@ è stata creata per l'utente @USER_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Una nuova sessione con ID @SESSION_ID@ è stata creata per l'utente @USER_ID@.
@@ -82,7 +108,7 @@ Il processo primario della sessione è @LEADER@.
Subject: La sessione @SESSION_ID@ è terminata
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
La sessione con ID @SESSION_ID@ è terminata.
@@ -90,7 +116,7 @@ La sessione con ID @SESSION_ID@ è terminata.
Subject: La nuova postazione @SEAT_ID@ è ora disponibile
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
La nuova postazione @SEAT_ID@ è stata configurata ed è ora disponibile.
@@ -98,7 +124,7 @@ La nuova postazione @SEAT_ID@ è stata configurata ed è ora disponibile.
Subject: La postazione @SEAT_ID@ è stata rimossa
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
La postazione @SEAT_ID@ è stata rimossa e non è più disponibile.
@@ -131,6 +157,17 @@ L'avvio del disco RAM ha richiesto @INITRD_USEC@ microsecondi.
L'avvio dello userspace ha richiesto @USERSPACE_USEC@ microsecondi.
+-- eed00a68ffd84e31882105fd973abdd1
+Subject: User manager start-up is now complete
+Defined-By: systemd
+Support: %SUPPORT_URL%
+
+L'istanza di gestione per l'utente @_UID@ è stata avviata. Tutti i servizi
+interrogati sono stati avviati. Da notare che altri servizi potrebbero essere
+ancora in fase di avvio o in attesa di essere avviati.
+
+L'avvio dell'istanza ha impiegato @USERSPACE_USEC@ microsecondi.
+
-- 6bbd95ee977941e497c48be27c254128
Subject: Il sistema è entrato in fase di pausa @SLEEP@
Defined-By: systemd
@@ -252,3 +289,42 @@ Defined-By: systemd
Support: %SUPPORT_URL%
La macchina virtuale @NAME@ con PID primario @LEADER@ è stata spenta.
+
+-- 36db2dfa5a9045e1bd4af5f93e1cf057
+Subject: La modalità DNSSEC è stata spenta, il server non la supporta
+Defined-By: systemd
+Support: %SUPPORT_URL%
+Documentation: man:systemd-resolved.service(8) resolved.conf(5)
+
+Il servizio di risoluzione (systemd-resolved.service) ha rilevato che il
+server DNS indicato non supporta DNSSEC e la validazione DNSSEC è stata
+conseguentemente disabilitata.
+
+Ciò avverrà se DNSSEC=allow-downgrade è configurato nel file
+resolved.conf e il server DNS indicato è incompatibile con DNSSEC. Da notare
+che in questo modo ci si espone ad attacchi DNSSEC downgrade, e un aggressore
+potrebbe disabilitare la validazione DNSSEC sul sistema inserendo risposte
+DNS nel canale di comunicazione.
+
+Questo evento potrebbe essere indice che il DNS server è forse incompatibile
+con DNSSEC o che un aggressore è riuscito nel suo intento malevolo.
+
+-- 1675d7f172174098b1108bf8c7dc8f5d
+Subject: La validazione DNSSEC è fallita
+Defined-By: systemd
+Support: %SUPPORT_URL%
+Documentation: man:systemd-resolved.service(8)
+
+Una query DNS o un dato hanno fatto fallire la validazione DNSSEC. Questo è
+usualmente un segnale che il canale di comunicazione utilizzato è stato
+manomesso.
+
+-- 4d4408cfd0d144859184d1e65d7c8a65
+Subject: Un trust anchor DNSSEC è stato revocato
+Defined-By: systemd
+Support: %SUPPORT_URL%
+Documentation: man:systemd-resolved.service(8)
+
+Un trust anchor DNSSEC è stato revocato. Un nuovo punto di fiducia è stato
+riconfigurato o il sistema operativo deve essere aggiornato per fornire un
+nuovo ancoraggio.
diff --git a/catalog/systemd.ko.catalog.in b/catalog/systemd.ko.catalog.in
index 0249cba747..4e8d7008c3 100644
--- a/catalog/systemd.ko.catalog.in
+++ b/catalog/systemd.ko.catalog.in
@@ -19,7 +19,7 @@
# Korean translation
# The catalog format is documented on
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# For an explanation why we do all this, see https://xkcd.com/1024/
#
@@ -101,7 +101,7 @@ Documentation: man:core(5)
Subject: @USER_ID@ 사용ìžì˜ 새 @SESSION_ID@ 세션 만듦
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
@USER_ID@ 사용ìžì˜ 새 @SESSION_ID@ ì„¸ì…˜ì„ ë§Œë“¤ì—ˆìŠµë‹ˆë‹¤.
@@ -111,7 +111,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: @SESSION_ID@ 세션 마침
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
@SESSION_ID@ ì„¸ì…˜ì„ ë냈습니다.
@@ -119,7 +119,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: 새 @SEAT_ID@ 시트 사용할 수 있ìŒ
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
새 @SEAT_ID@ 시트를 설정했고 사용할 수 있습니다.
@@ -127,7 +127,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: @SEAT_ID@ 시트 제거함
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
@SEAT_ID@ 시트를 제거했으며 ë”ì´ìƒ 사용할 수 없습니다.
diff --git a/catalog/systemd.pl.catalog.in b/catalog/systemd.pl.catalog.in
index 5eead5c92c..981fefb7b9 100644
--- a/catalog/systemd.pl.catalog.in
+++ b/catalog/systemd.pl.catalog.in
@@ -20,7 +20,7 @@
# Polish translation
# The catalog format is documented on
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# For an explanation why we do all this, see https://xkcd.com/1024/
@@ -106,7 +106,7 @@ gdb(1) będą ostrzegały o skróceniu pliku.
Subject: Utworzono nową sesję @SESSION_ID@ dla użytkownika @USER_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Nowa sesja o identyfikatorze @SESSION_ID@ została utworzona dla użytkownika
@USER_ID@.
@@ -117,7 +117,7 @@ Proces prowadzÄ…cy sesji: @LEADER@.
Subject: Zakończono sesję @SESSION_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Sesja o identyfikatorze @SESSION_ID@ została zakończona.
@@ -125,7 +125,7 @@ Sesja o identyfikatorze @SESSION_ID@ została zakończona.
Subject: Dostępne jest nowe stanowisko @SEAT_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Nowe stanowisko @SEAT_ID@ zostało skonfigurowane i jest teraz dostępne.
@@ -133,7 +133,7 @@ Nowe stanowisko @SEAT_ID@ zostało skonfigurowane i jest teraz dostępne.
Subject: Usunięto stanowisko @SEAT_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Stanowisko @SEAT_ID@ zostało usunięte i nie jest już dostępne.
@@ -157,9 +157,9 @@ Defined-By: systemd
Support: %SUPPORT_URL%
Wszystkie usługi systemowe obowiązkowo zakolejkowane do włączenia podczas
-uruchamiania systemu zostały pomyślnie uruchomione. Proszę zauważyć, że nie
-oznacza to, że komputer jest bezczynny, jako że usługi mogą wciąż kończyć
-proces uruchamiania.
+uruchamiania systemu zostały uruchomione. Proszę zauważyć, że nie oznacza
+to, że komputer jest bezczynny, jako że usługi mogą wciąż kończyć proces
+uruchamiania.
Uruchamianie jądra zajęło @KERNEL_USEC@ μs.
@@ -167,6 +167,18 @@ Uruchamianie początkowego dysku RAM zajęło @INITRD_USEC@ μs.
Uruchamianie przestrzeni użytkownika zajęło @USERSPACE_USEC@ μs.
+-- eed00a68ffd84e31882105fd973abdd1
+Subject: Ukończono uruchamianie menedżera użytkownika
+Defined-By: systemd
+Support: %SUPPORT_URL%
+
+Wystąpienie menedżera dla użytkownika @_UID@ zostało uruchomione.
+Wszystkie usługi zakolejkowane do włączenia zostały uruchomione.
+Proszę zauważyć, że inne usługi mogą być nadal uruchamiane
+lub zostać uruchomione później.
+
+Uruchamianie menedżera zajęło @USERSPACE_USEC@ μs.
+
-- 6bbd95ee977941e497c48be27c254128
Subject: Przejście do stanu uśpienia @SLEEP@
Defined-By: systemd
diff --git a/catalog/systemd.pt_BR.catalog.in b/catalog/systemd.pt_BR.catalog.in
index e461c2b2ba..192fd33c1c 100644
--- a/catalog/systemd.pt_BR.catalog.in
+++ b/catalog/systemd.pt_BR.catalog.in
@@ -19,7 +19,7 @@
# Catálogo de mensagens para as mensagens do próprio systemd
# O formato do catálogo está documentado em
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# Para uma explicação do porquê de fazermos tudo isso, veja
# https://xkcd.com/1024/
@@ -79,7 +79,7 @@ deveria ser relatado para seu fabricante como um erro.
Subject: A nova sessão @SESSION_ID@ foi criada para usuário o @USER_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Uma nova sessão com o ID @SESSION_ID@ foi criada para o usuário @USER_ID@.
@@ -89,7 +89,7 @@ O processo originador da sessão é @LEADER@.
Subject: Sessão @SESSION_ID@ foi terminada
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Um sessão com o ID @SESSION_ID@ foi terminada.
@@ -97,7 +97,7 @@ Um sessão com o ID @SESSION_ID@ foi terminada.
Subject: Um novo seat @SEAT_ID@ está disponível
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Um novo seat @SEAT_ID@ foi configurado e está disponível.
@@ -105,7 +105,7 @@ Um novo seat @SEAT_ID@ foi configurado e está disponível.
Subject: Seat @SEAT_ID@ foi removido agora
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Um seat @SEAT_ID@ foi removido e não está mais disponível.
diff --git a/catalog/systemd.ru.catalog.in b/catalog/systemd.ru.catalog.in
index df55478592..367ed89d96 100644
--- a/catalog/systemd.ru.catalog.in
+++ b/catalog/systemd.ru.catalog.in
@@ -1,7 +1,7 @@
# This file is part of systemd.
#
# Copyright 2012 Lennart Poettering
-# Copyright 2013-2016 Sergey Ptashnick
+# Copyright 2013-2017 Sergey Ptashnick
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
@@ -20,7 +20,7 @@
# Russian translation
# Формат каталога Ñообщений опиÑан по ÑÑылке
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# Перед каждым Ñлементом в комментарии указан Subject иÑходного
# ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ (на английÑком).
@@ -102,12 +102,24 @@ Documentation: man:core(5)
ВероÑтно, Ñто произошло из-за ошибки, допущенной в коде программы.
РекомендуетÑÑ Ñообщить её разработчикам о возникшей проблеме.
+# Subject: Core file was truncated to @SIZE_LIMIT@ bytes
+-- 5aadd8e954dc4b1a8c954d63fd9e1137
+Subject: Файл Ñ Ð´Ð°Ð¼Ð¿Ð¾Ð¼ памÑти был урезан до @SIZE_LIMIT@ байт
+Defined-By: systemd
+Support: %SUPPORT_URL%
+Documentation: man:coredump.conf(5)
+
+Объем памÑти процеÑÑа превыÑил Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð½Ð° размер дампа, уÑтановленные
+Ð´Ð»Ñ systemd-coredump(8). ЗапиÑаны только первые @SIZE_LIMIT@ байт. Ðе иÑключено,
+что Ñтот дамп еще пригоден Ð´Ð»Ñ Ð°Ð½Ð°Ð»Ð¸Ð·Ð°, Ñ…Ð¾Ñ‚Ñ Ð¸Ð½Ñтрументы Ð´Ð»Ñ Ð°Ð½Ð°Ð»Ð¸Ð·Ð°
+дампов (например, gdb(1)) могут выдать предупреждение, что файл был урезан.
+
# Subject: A new session @SESSION_ID@ has been created for user @USER_ID@
-- 8d45620c1a4348dbb17410da57c60c66
Subject: Ð”Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ @USER_ID@ Ñоздан новый ÑÐµÐ°Ð½Ñ @SESSION_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Ð”Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ @USER_ID@ Ñоздан новый ÑÐµÐ°Ð½Ñ Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ð¾Ð¼ @SESSION_ID@.
@@ -118,7 +130,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: Ð¡ÐµÐ°Ð½Ñ @SESSION_ID@ завершен
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Ð¡ÐµÐ°Ð½Ñ Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ð¾Ð¼ @SESSION_ID@ завершилÑÑ.
@@ -127,7 +139,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: Добавлено новое рабочее меÑто @SEAT_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Ðовое рабочее меÑто (seat) @SEAT_ID@ полноÑтью наÑтроено и готово к
иÑпользованию.
@@ -137,7 +149,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: Рабочее меÑто @SEAT_ID@ отключено
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Рабочее меÑто (seat) @SEAT_ID@ было отключено.
@@ -175,6 +187,19 @@ Support: %SUPPORT_URL%
ЗапуÑк ÑиÑтемных Ñлужб занÑл @USERSPACE_USEC@ микроÑекунд.
+# Subject: User manager start-up is now complete
+-- eed00a68ffd84e31882105fd973abdd1
+Subject: Завершен запуÑк менеджера пользовательÑкого ÑеанÑа
+Defined-By: systemd
+Support: %SUPPORT_URL%
+
+Менеджер пользовательÑкого ÑеанÑа Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ð¾Ð¼ @_UID@
+был запущен. Ð’Ñе Ñлужбы, ÑтоÑвшие в очереди на запуÑк, также были запущены. Тем
+не менее, прочие Ñлужбы могут вÑе еще находитьÑÑ Ð² процеÑÑе запуÑка, либо могут
+быть запущены позднее.
+
+ЗапуÑк менеджера занÑл @USERSPACE_USEC@ микроÑекунд.
+
# Subject: System sleep state @SLEEP@ entered
-- 6bbd95ee977941e497c48be27c254128
Subject: СиÑтема перешла в ÑоÑтоÑние Ñна (@SLEEP@)
diff --git a/catalog/systemd.sr.catalog.in b/catalog/systemd.sr.catalog.in
index 06a0ff648c..674eb557b5 100644
--- a/catalog/systemd.sr.catalog.in
+++ b/catalog/systemd.sr.catalog.in
@@ -19,7 +19,7 @@
# Serbian translation
# Формат каталога је документован на
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# Да биÑте видели зашто ово радимо, погледајте https://xkcd.com/1024/
@@ -78,7 +78,7 @@ Documentation: man:core(5)
Subject: Ðова ÑеÑија @SESSION_ID@ је направљена за кориÑника @USER_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Ðова ÑеÑија Ñа ИБ-ом @SESSION_ID@ је направљена за кориÑника @USER_ID@.
@@ -88,7 +88,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: СеÑија @SESSION_ID@ је окончана
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
СеÑија Ñа ИБ-ом @SESSION_ID@ је окончана.
@@ -96,7 +96,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: Ðово Ñедиште @SEAT_ID@ је Ñада доÑтупно
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Ðово Ñедиште @SEAT_ID@ је иÑподешавано и Ñада је доÑтупно.
@@ -104,7 +104,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: Седиште @SEAT_ID@ је Ñада уклоњено
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Седиште @SEAT_ID@ је Ñада уклоњено и више није доÑтупно.
diff --git a/catalog/systemd.zh_CN.catalog.in b/catalog/systemd.zh_CN.catalog.in
index ba7c697c16..78a8a8ca62 100644
--- a/catalog/systemd.zh_CN.catalog.in
+++ b/catalog/systemd.zh_CN.catalog.in
@@ -20,7 +20,7 @@
# Simplified Chinese translation
# 本 catalog 文档格å¼è¢«è®°è½½åœ¨
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# 如需了解我们为什么åšè¿™äº›å·¥ä½œï¼Œè¯·è§ https://xkcd.com/1024/
@@ -76,7 +76,7 @@ Documentation: man:core(5)
Subject: ä¸€ä¸ªæ–°ä¼šè¯ @SESSION_ID@ 已为用户 @USER_ID@ 建立
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
一个 ID 为 @SESSION_ID@ 的新会è¯å·²ä¸ºç”¨æˆ· @USER_ID@ 建立。
@@ -86,7 +86,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: ä¼šè¯ @SESSION_ID@ 已终止
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
一个 ID 为 @SESSION_ID@ 的会è¯å·²ç»ˆæ­¢ã€‚
@@ -94,7 +94,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: ä¸€ä¸ªæ–°çš„åº§ä½ @SEAT_ID@ å¯ç”¨
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
ä¸€ä¸ªæ–°çš„åº§ä½ @SEAT_ID@ 已被é…置并已å¯ç”¨ã€‚
@@ -102,7 +102,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: åº§ä½ @SEAT_ID@ 已被移除
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
åº§ä½ @SEAT_ID@ 已被移除并ä¸å†å¯ç”¨ã€‚
@@ -137,7 +137,7 @@ Support: %SUPPORT_URL%
-- 6bbd95ee977941e497c48be27c254128
Subject: 系统已进入 @SLEEP@ ç¡çœ çŠ¶æ€
Defined-By: systemd
-Support: http://lists.freedesktop.org/mailman/listinfo/systemd-deve
+Support: %SUPPORT_URL%
系统现已进入 @SLEEP@ ç¡çœ çŠ¶æ€ã€‚
diff --git a/catalog/systemd.zh_TW.catalog.in b/catalog/systemd.zh_TW.catalog.in
index f7b42fa1c7..d262b88a01 100644
--- a/catalog/systemd.zh_TW.catalog.in
+++ b/catalog/systemd.zh_TW.catalog.in
@@ -20,7 +20,7 @@
# Traditional Chinese translation
# Catalog çš„æ ¼å¼è¨˜éŒ„æ–¼
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# For an explanation why we do all this, see https://xkcd.com/1024/
@@ -79,7 +79,7 @@ Documentation: man:core(5)
Subject: 新的工作階段 @SESSION_ID@ 已為使用者 @USER_ID@ 建立
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
一個新的工作階段,ID @SESSION_ID@ 已為使用者 @USER_ID@ 建立。
@@ -89,7 +89,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: 工作階段 @SESSION_ID@ å·²çµæŸ
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
一個工作階段,ID @SESSION_ID@ å·²çµæŸã€‚
@@ -97,7 +97,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: æ–°çš„åº§ä½ @SEAT_ID@ å¯ç”¨
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
ä¸€å€‹æ–°çš„åº§ä½ @SEAT_ID@ 已被設定且ç¾åœ¨å¯ç”¨ã€‚
@@ -105,7 +105,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: åº§ä½ @SEAT_ID@ 已被移除
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
åº§ä½ @SEAT_ID@ 已被移除且ä¸å†å¯ç”¨ã€‚
diff --git a/coccinelle/strjoin.cocci b/coccinelle/strjoin.cocci
new file mode 100644
index 0000000000..675760e37a
--- /dev/null
+++ b/coccinelle/strjoin.cocci
@@ -0,0 +1,16 @@
+@@
+expression list args;
+@@
+- strjoin(args, NULL);
++ strjoin(args);
+@@
+expression t;
+expression list args;
+@@
+- t = strjoin(args, NULL);
++ t = strjoin(args);
+@@
+expression list args;
+@@
+- return strjoin(args, NULL);
++ return strjoin(args);
diff --git a/configure.ac b/configure.ac
index 5c639e32d4..64b2d28048 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,10 +20,10 @@
AC_PREREQ([2.64])
AC_INIT([systemd],
- [232],
- [http://github.com/systemd/systemd/issues],
+ [233],
+ [https://github.com/systemd/systemd/issues],
[systemd],
- [http://www.freedesktop.org/wiki/Software/systemd])
+ [https://www.freedesktop.org/wiki/Software/systemd])
AC_CONFIG_SRCDIR([src/core/main.c])
AC_CONFIG_MACRO_DIR([m4])
@@ -97,8 +97,6 @@ AC_PATH_PROG([M4], [m4])
AC_PATH_PROG([QUOTAON], [quotaon], [/usr/sbin/quotaon], [$PATH:/usr/sbin:/sbin])
AC_PATH_PROG([QUOTACHECK], [quotacheck], [/usr/sbin/quotacheck], [$PATH:/usr/sbin:/sbin])
-AC_PATH_PROG([SETCAP], [setcap], [/usr/sbin/setcap], [$PATH:/usr/sbin:/sbin])
-
AC_PATH_PROG([KILL], [kill], [/usr/bin/kill], [$PATH:/usr/sbin:/sbin])
AC_PATH_PROG([KMOD], [kmod], [/usr/bin/kmod], [$PATH:/usr/sbin:/sbin])
@@ -157,7 +155,6 @@ CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\
-Wall \
-Wextra \
-Wundef \
- "-Wformat=2 -Wformat-security -Wformat-nonliteral" \
-Wlogical-op \
-Wmissing-include-dirs \
-Wold-style-definition \
@@ -170,6 +167,8 @@ CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\
-Werror=implicit-function-declaration \
-Werror=missing-declarations \
-Werror=return-type \
+ -Werror=incompatible-pointer-types \
+ -Werror=format=2 \
-Wstrict-prototypes \
-Wredundant-decls \
-Wmissing-noreturn \
@@ -218,25 +217,21 @@ AS_CASE([$CFLAGS], [*-O[[12345sz\ ]]*],
[CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [-flto])],
[AC_MSG_RESULT([disabling -flto as requested])])],
[AC_MSG_RESULT([skipping -flto, optimization not enabled])])
-AC_SUBST([OUR_CFLAGS], "$with_cflags $sanitizer_cflags")
AS_CASE([$CFLAGS], [*-O[[12345sz\ ]]*],
[CC_CHECK_FLAGS_APPEND([with_cppflags], [CPPFLAGS], [\
-Wp,-D_FORTIFY_SOURCE=2])],
[AC_MSG_RESULT([skipping -D_FORTIFY_SOURCE, optimization not enabled])])
-AC_SUBST([OUR_CPPFLAGS], "$with_cppflags $sanitizer_cppflags")
AS_CASE([$CFLAGS], [*-O[[12345sz\ ]]*],
[CC_CHECK_FLAGS_APPEND([with_ldflags], [LDFLAGS], [\
-Wl,--gc-sections])],
[AC_MSG_RESULT([skipping --gc-sections, optimization not enabled])])
-AC_SUBST([OUR_CFLAGS], "$with_ldflags $sanitizer_cflags")
AS_CASE([$CFLAGS], [*-O[[12345sz\ ]]*],
[CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\
-ffunction-sections -fdata-sections])],
[AC_MSG_RESULT([skipping -ffunction/data-section, optimization not enabled])])
-AC_SUBST([OUR_CFLAGS], "$with_cflags $sanitizer_cflags")
CC_CHECK_FLAGS_APPEND([with_ldflags], [LDFLAGS], [\
-Wl,--as-needed \
@@ -245,6 +240,9 @@ CC_CHECK_FLAGS_APPEND([with_ldflags], [LDFLAGS], [\
-Wl,-z,now \
-pie \
-Wl,-fuse-ld=gold])
+
+AC_SUBST([OUR_CPPFLAGS], "$with_cppflags $sanitizer_cppflags")
+AC_SUBST([OUR_CFLAGS], "-D__SANE_USERSPACE_TYPES__ $with_cflags $sanitizer_cflags")
AC_SUBST([OUR_LDFLAGS], "$with_ldflags $sanitizer_ldflags")
AC_CHECK_SIZEOF(pid_t)
@@ -284,11 +282,11 @@ AC_DEFINE_UNQUOTED([GPERF_LEN_TYPE], [$GPERF_LEN_TYPE], [gperf len type])
# we use python to build the man page index
have_python=no
AC_ARG_WITH([python],
- [AS_HELP_STRING([--without-python], [Disable building the man page index and systemd-python (default: test)])])
+ [AS_HELP_STRING([--without-python], [disable building the man page index and systemd-python (default: test)])])
have_lxml=no
AS_IF([test "x$with_python" != "xno"], [
- AM_PATH_PYTHON(,, [:])
+ AM_PATH_PYTHON([3],, [:])
AS_IF([test "x$PYTHON" != "x:"], [
AC_MSG_CHECKING([for python lxml module])
AS_IF(["$PYTHON" -c 'import lxml' 2>/dev/null], [have_lxml=yes])
@@ -310,6 +308,7 @@ AM_CONDITIONAL([HAVE_PYTHON], [test "x$have_python" = "xyes"])
AC_CHECK_HEADERS([sys/capability.h], [], [AC_MSG_ERROR([*** POSIX caps headers not found])])
AC_CHECK_HEADERS([linux/btrfs.h], [], [])
AC_CHECK_HEADERS([linux/memfd.h], [], [])
+AC_CHECK_HEADERS([linux/vm_sockets.h], [], [], [#include <sys/socket.h>])
# unconditionally pull-in librt with old glibc versions
AC_SEARCH_LIBS([clock_gettime], [rt], [], [])
@@ -333,20 +332,23 @@ AC_CHECK_DECLS([
kcmp,
keyctl,
LO_FLAGS_PARTSCAN,
- copy_file_range],
+ copy_file_range,
+ explicit_bzero],
[], [], [[
#include <sys/types.h>
#include <unistd.h>
#include <sys/mount.h>
#include <fcntl.h>
#include <sched.h>
+#include <string.h>
#include <linux/loop.h>
#include <linux/random.h>
]])
-AC_CHECK_TYPES([char16_t, char32_t, key_serial_t],
+AC_CHECK_TYPES([char16_t, char32_t, key_serial_t, struct ethtool_link_settings],
[], [], [[
#include <uchar.h>
+#include <linux/ethtool.h>
]])
AC_CHECK_DECLS([IFLA_INET6_ADDR_GEN_MODE,
@@ -479,7 +481,7 @@ AM_CONDITIONAL(HAVE_LIBMOUNT, [test "$have_libmount" = "yes"])
# ------------------------------------------------------------------------------
have_seccomp=no
-AC_ARG_ENABLE(seccomp, AS_HELP_STRING([--disable-seccomp], [Disable optional SECCOMP support]))
+AC_ARG_ENABLE(seccomp, AS_HELP_STRING([--disable-seccomp], [disable optional SECCOMP support]))
if test "x$enable_seccomp" != "xno"; then
PKG_CHECK_MODULES(SECCOMP, [libseccomp >= 2.3.1],
[AC_DEFINE(HAVE_SECCOMP, 1, [Define if seccomp is available])
@@ -494,7 +496,7 @@ AM_CONDITIONAL(HAVE_SECCOMP, [test "$have_seccomp" = "yes"])
# ------------------------------------------------------------------------------
have_ima=yes
-AC_ARG_ENABLE([ima], AS_HELP_STRING([--disable-ima],[Disable optional IMA support]),
+AC_ARG_ENABLE([ima], AS_HELP_STRING([--disable-ima], [disable optional IMA support]),
[case "${enableval}" in
yes) have_ima=yes ;;
no) have_ima=no ;;
@@ -508,7 +510,7 @@ fi
# ------------------------------------------------------------------------------
have_selinux=no
-AC_ARG_ENABLE(selinux, AS_HELP_STRING([--disable-selinux], [Disable optional SELINUX support]))
+AC_ARG_ENABLE(selinux, AS_HELP_STRING([--disable-selinux], [disable optional SELINUX support]))
if test "x$enable_selinux" != "xno"; then
PKG_CHECK_MODULES([SELINUX], [libselinux >= 2.1.9],
[AC_DEFINE(HAVE_SELINUX, 1, [Define if SELinux is available])
@@ -522,7 +524,7 @@ fi
AM_CONDITIONAL(HAVE_SELINUX, [test "$have_selinux" = "yes"])
have_apparmor=no
-AC_ARG_ENABLE(apparmor, AS_HELP_STRING([--disable-apparmor], [Disable optional AppArmor support]))
+AC_ARG_ENABLE(apparmor, AS_HELP_STRING([--disable-apparmor], [disable optional AppArmor support]))
if test "x$enable_apparmor" != "xno"; then
PKG_CHECK_MODULES([APPARMOR], [libapparmor],
[AC_DEFINE(HAVE_APPARMOR, 1, [Define if AppArmor is available])
@@ -554,15 +556,15 @@ AS_IF([test "x$enable_wheel_group" != "xno"], [
AC_ARG_WITH(debug-shell,
AS_HELP_STRING([--with-debug-shell=PATH],
- [Path to debug shell binary]),
- [SUSHELL="$withval"],[
- AS_IF([test "x${have_selinux}" != "xno"], [SUSHELL="/sbin/sushell"] , [SUSHELL="/bin/sh"])])
+ [path to debug shell binary]),
+ [SUSHELL="$withval"],
+ [SUSHELL="/bin/sh"])
AC_SUBST(SUSHELL)
AC_ARG_WITH([debug-tty],
AS_HELP_STRING([--with-debug-tty=PATH],
- [Specify the tty device for debug shell]),
+ [specify the tty device for debug shell]),
[DEBUGTTY="$withval"],
[DEBUGTTY=/dev/tty9])
@@ -570,7 +572,7 @@ AC_SUBST(DEBUGTTY)
AC_ARG_WITH([certificate-root],
AS_HELP_STRING([--with-certificate-root=PATH],
- [Specify the prefix for TLS certificates [/etc/ssl]]),
+ [specify the prefix for TLS certificates [/etc/ssl]]),
[CERTIFICATEROOT="$withval"],
[CERTIFICATEROOT="/etc/ssl"])
@@ -578,15 +580,15 @@ AC_SUBST(CERTIFICATEROOT)
AC_ARG_WITH([support-url],
AS_HELP_STRING([--with-support-url=URL],
- [Specify the support URL to show in catalog entries included in systemd]),
+ [specify the support URL to show in catalog entries included in systemd]),
[SUPPORT_URL="$withval"],
- [SUPPORT_URL=http://lists.freedesktop.org/mailman/listinfo/systemd-devel])
+ [SUPPORT_URL=https://lists.freedesktop.org/mailman/listinfo/systemd-devel])
AC_SUBST(SUPPORT_URL)
AC_ARG_WITH([nobody-user],
AS_HELP_STRING([--with-nobody-user=NAME],
- [Specify the name of the nobody user (the one with UID 65534)]),
+ [specify the name of the nobody user (the one with UID 65534)]),
[NOBODY_USER_NAME="$withval"],
[NOBODY_USER_NAME=nobody])
@@ -595,16 +597,42 @@ AC_DEFINE_UNQUOTED(NOBODY_USER_NAME, ["$NOBODY_USER_NAME"], [The name of the nob
AC_ARG_WITH([nobody-group],
AS_HELP_STRING([--with-nobody-group=NAME],
- [Specify the name of the nobody group (the one with GID 65534)]),
+ [specify the name of the nobody group (the one with GID 65534)]),
[NOBODY_GROUP_NAME="$withval"],
[NOBODY_GROUP_NAME=nobody])
AC_SUBST(NOBODY_GROUP_NAME)
AC_DEFINE_UNQUOTED(NOBODY_GROUP_NAME, ["$NOBODY_GROUP_NAME"], [The name of the nobody group (the one with GID 65534)])
+AC_ARG_WITH([fallback-hostname],
+ AS_HELP_STRING([--with-fallback-hostname=NAME],
+ [specify the hostname used if none configured]),
+ [FALLBACK_HOSTNAME="$withval"],
+ [FALLBACK_HOSTNAME=localhost])
+
+AC_SUBST(FALLBACK_HOSTNAME)
+AC_DEFINE_UNQUOTED(FALLBACK_HOSTNAME, ["$FALLBACK_HOSTNAME"], [The hostname used if none configured])
+
+# ------------------------------------------------------------------------------
+
+AC_ARG_WITH(default-hierarchy,
+ AS_HELP_STRING([--with-default-hierarchy=MODE],
+ [default cgroup hierarchy, defaults to "hybrid"]),
+ [DEFAULT_HIERARCHY="$withval"],
+ [DEFAULT_HIERARCHY="hybrid"])
+
+AS_CASE("$DEFAULT_HIERARCHY",
+ [legacy], [mode=CGROUP_UNIFIED_NONE],
+ [hybrid], [mode=CGROUP_UNIFIED_SYSTEMD233],
+ [unified], [mode=CGROUP_UNIFIED_ALL],
+ AC_MSG_ERROR(Bad default hierarchy mode ${DEFAULT_HIERARCHY}))
+AC_DEFINE_UNQUOTED(DEFAULT_HIERARCHY, [$mode], [Default cgroup hierarchy])
+AC_DEFINE_UNQUOTED(DEFAULT_HIERARCHY_NAME, ["$DEFAULT_HIERARCHY"],
+ [Default cgroup hierarchy as string])
+
# ------------------------------------------------------------------------------
have_xz=no
-AC_ARG_ENABLE(xz, AS_HELP_STRING([--disable-xz], [Disable optional XZ support]))
+AC_ARG_ENABLE(xz, AS_HELP_STRING([--disable-xz], [disable optional XZ support]))
AS_IF([test "x$enable_xz" != "xno"], [
PKG_CHECK_MODULES(XZ, [ liblzma ],
[AC_DEFINE(HAVE_XZ, 1, [Define if XZ is available])
@@ -617,7 +645,7 @@ AM_CONDITIONAL(HAVE_XZ, [test "$have_xz" = "yes"])
# ------------------------------------------------------------------------------
have_zlib=no
-AC_ARG_ENABLE(zlib, AS_HELP_STRING([--disable-zlib], [Disable optional ZLIB support]))
+AC_ARG_ENABLE(zlib, AS_HELP_STRING([--disable-zlib], [disable optional ZLIB support]))
AS_IF([test "x$enable_zlib" != "xno"], [
PKG_CHECK_MODULES(ZLIB, [ zlib ],
[AC_DEFINE(HAVE_ZLIB, 1, [Define if ZLIB is available])
@@ -630,7 +658,7 @@ AM_CONDITIONAL(HAVE_ZLIB, [test "$have_zlib" = "yes"])
# ------------------------------------------------------------------------------
have_bzip2=no
-AC_ARG_ENABLE(bzip2, AS_HELP_STRING([--enable-bzip2], [Enable optional BZIP2 support]))
+AC_ARG_ENABLE(bzip2, AS_HELP_STRING([--disable-bzip2], [disable optional BZIP2 support]))
AS_IF([test "x$enable_bzip2" != "xno"], [
AC_CHECK_HEADERS(bzlib.h,
[AC_DEFINE(HAVE_BZIP2, 1, [Define if BZIP2 is available])
@@ -643,7 +671,7 @@ AM_CONDITIONAL(HAVE_BZIP2, [test "$have_bzip2" = "yes"])
# ------------------------------------------------------------------------------
have_lz4=no
-AC_ARG_ENABLE(lz4, AS_HELP_STRING([--disable-lz4], [Disable optional LZ4 support]))
+AC_ARG_ENABLE(lz4, AS_HELP_STRING([--disable-lz4], [disable optional LZ4 support]))
AS_IF([test "x$enable_lz4" != "xno"], [
PKG_CHECK_MODULES(LZ4, [ liblz4 < 10 ],
[AC_DEFINE(HAVE_LZ4, 1, [Define if LZ4 is available])
@@ -661,7 +689,7 @@ AM_CONDITIONAL(HAVE_COMPRESSION, [test "$have_xz" = "yes" -o "$have_lz4" = "yes"
# ------------------------------------------------------------------------------
AC_ARG_ENABLE([pam],
- AS_HELP_STRING([--disable-pam],[Disable optional PAM support]),
+ AS_HELP_STRING([--disable-pam], [disable optional PAM support]),
[case "${enableval}" in
yes) have_pam=yes ;;
no) have_pam=no ;;
@@ -700,7 +728,7 @@ AM_CONDITIONAL([HAVE_PAM], [test "x$have_pam" != xno])
# ------------------------------------------------------------------------------
AC_ARG_ENABLE([acl],
- AS_HELP_STRING([--disable-acl],[Disable optional ACL support]),
+ AS_HELP_STRING([--disable-acl], [disable optional ACL support]),
[case "${enableval}" in
yes) have_acl=yes ;;
no) have_acl=no ;;
@@ -738,7 +766,7 @@ AC_SUBST(ACL_LIBS)
AM_CONDITIONAL([HAVE_ACL], [test "x$have_acl" != xno])
# ------------------------------------------------------------------------------
-AC_ARG_ENABLE([smack], AS_HELP_STRING([--disable-smack],[Disable optional SMACK support]),
+AC_ARG_ENABLE([smack], AS_HELP_STRING([--disable-smack], [disable optional SMACK support]),
[case "${enableval}" in
yes) have_smack=yes ;;
no) have_smack=no ;;
@@ -773,7 +801,7 @@ AS_HELP_STRING([--with-smack-default-process-label=STRING],
# ------------------------------------------------------------------------------
AC_ARG_ENABLE([gcrypt],
- AS_HELP_STRING([--disable-gcrypt],[Disable optional GCRYPT support]),
+ AS_HELP_STRING([--disable-gcrypt], [disable optional GCRYPT support]),
[case "${enableval}" in
yes) have_gcrypt=yes ;;
no) have_gcrypt=no ;;
@@ -825,7 +853,7 @@ AM_CONDITIONAL([HAVE_GCRYPT], [test "x$have_gcrypt" != xno])
# ------------------------------------------------------------------------------
AC_ARG_ENABLE([audit],
- AS_HELP_STRING([--disable-audit],[Disable optional AUDIT support]),
+ AS_HELP_STRING([--disable-audit], [disable optional AUDIT support]),
[case "${enableval}" in
yes) have_audit=yes ;;
no) have_audit=no ;;
@@ -863,7 +891,7 @@ AM_CONDITIONAL([HAVE_AUDIT], [test "x$have_audit" != xno])
# ------------------------------------------------------------------------------
AC_ARG_ENABLE([elfutils],
- AS_HELP_STRING([--disable-elfutils],[Disable optional ELFUTILS support]),
+ AS_HELP_STRING([--disable-elfutils], [disable optional ELFUTILS support]),
[case "${enableval}" in
yes) have_elfutils=yes ;;
no) have_elfutils=no ;;
@@ -970,7 +998,7 @@ AM_CONDITIONAL(HAVE_REMOTE, [test "$have_microhttpd" = "yes" -o "$have_libcurl"
# ------------------------------------------------------------------------------
have_libidn=no
-AC_ARG_ENABLE(libidn, AS_HELP_STRING([--disable-libidn], [Disable optional LIBIDN support]))
+AC_ARG_ENABLE(libidn, AS_HELP_STRING([--disable-libidn], [disable optional LIBIDN support]))
if test "x$enable_libidn" != "xno"; then
PKG_CHECK_MODULES(LIBIDN, [libidn],
[AC_DEFINE(HAVE_LIBIDN, 1, [Define if libidn is available])
@@ -985,7 +1013,7 @@ AM_CONDITIONAL(HAVE_LIBIDN, [test "$have_libidn" = "yes"])
# ------------------------------------------------------------------------------
have_libiptc=no
-AC_ARG_ENABLE(libiptc, AS_HELP_STRING([--disable-libiptc], [Disable optional LIBIPTC support]))
+AC_ARG_ENABLE(libiptc, AS_HELP_STRING([--disable-libiptc], [disable optional LIBIPTC support]))
if test "x$enable_libiptc" != "xno"; then
PKG_CHECK_MODULES(LIBIPTC, [libiptc],
[AC_DEFINE(HAVE_LIBIPTC, 1, [Define if libiptc is available])
@@ -1031,6 +1059,14 @@ fi
AM_CONDITIONAL(ENABLE_TMPFILES, [test "$have_tmpfiles" = "yes"])
# ------------------------------------------------------------------------------
+have_environment_d=no
+AC_ARG_ENABLE(environment-d, AS_HELP_STRING([--disable-environment-d], [disable environment.d support]))
+if test "x$enable_environment_d" != "xno"; then
+ have_environment_d=yes
+fi
+AM_CONDITIONAL(ENABLE_ENVIRONMENT_D, [test "$have_environment_d" = "yes"])
+
+# ------------------------------------------------------------------------------
have_sysusers=no
AC_ARG_ENABLE(sysusers, AS_HELP_STRING([--disable-sysusers], [disable sysusers support]))
if test "x$enable_sysusers" != "xno"; then
@@ -1080,7 +1116,7 @@ AM_CONDITIONAL(ENABLE_LOGIND, [test "$have_logind" = "yes"])
AS_IF([test "$have_logind" = "yes"], [ AC_DEFINE(HAVE_LOGIND, [1], [Logind support available]) ])
AC_ARG_WITH([kill-user-processes],
- [AS_HELP_STRING([--without-kill-user-processes], [Set logind's KillUserProcesses=no by default])])
+ [AS_HELP_STRING([--without-kill-user-processes], [set logind's KillUserProcesses=no by default])])
AS_IF([test "$with_kill_user_processes" != "no"],
[kill_user_processes=true
KILL_USER_PROCESSES=yes],
@@ -1134,19 +1170,16 @@ AM_CONDITIONAL(ENABLE_TIMESYNCD, [test "$have_timesyncd" = "yes"])
AC_ARG_WITH(ntp-servers,
AS_HELP_STRING([--with-ntp-servers=NTPSERVERS],
- [Space-separated list of default NTP servers]),
+ [space-separated list of default NTP servers]),
[NTP_SERVERS="$withval"],
- [NTP_SERVERS="time1.google.com time2.google.com time3.google.com time4.google.com"
- AC_MSG_WARN([*** Using Google NTP servers.
- Do not ship OSes or devices with these default settings.
- See DISTRO_PORTING for details!])])
+ [NTP_SERVERS="time1.google.com time2.google.com time3.google.com time4.google.com"])
AC_DEFINE_UNQUOTED(NTP_SERVERS, ["$NTP_SERVERS"], [Default NTP Servers])
AC_SUBST(NTP_SERVERS)
AC_ARG_WITH(time-epoch,
AS_HELP_STRING([--with-time-epoch=SECONDS],
- [Time epoch for time clients]),
+ [time epoch for time clients]),
[TIME_EPOCH="$withval"],
[TIME_EPOCH="`stat -c %Y ${srcdir}/NEWS 2>/dev/null || echo 0`"])
@@ -1155,7 +1188,7 @@ AC_DEFINE_UNQUOTED(TIME_EPOCH, [$TIME_EPOCH], [Time Epoch])
# ------------------------------------------------------------------------------
AC_ARG_WITH(system-uid-max,
AS_HELP_STRING([--with-system-uid-max=UID]
- [Maximum UID for system users]),
+ [maximum UID for system users]),
[SYSTEM_UID_MAX="$withval"],
[SYSTEM_UID_MAX="`awk 'BEGIN { uid=999 } /^\s*SYS_UID_MAX\s+/ { uid=$2 } END { print uid }' /etc/login.defs 2>/dev/null || echo 999`"])
@@ -1165,7 +1198,7 @@ AC_SUBST(SYSTEM_UID_MAX)
# ------------------------------------------------------------------------------
AC_ARG_WITH(system-gid-max,
AS_HELP_STRING([--with-system-gid-max=GID]
- [Maximum GID for system groups]),
+ [maximum GID for system groups]),
[SYSTEM_GID_MAX="$withval"],
[SYSTEM_GID_MAX="`awk 'BEGIN { gid=999 } /^\s*SYS_GID_MAX\s+/ { gid=$2 } END { print gid }' /etc/login.defs 2>/dev/null || echo 999`"])
@@ -1212,7 +1245,7 @@ AM_CONDITIONAL(ENABLE_RESOLVED, [test "$have_resolved" = "yes"])
AC_ARG_WITH(dns-servers,
AS_HELP_STRING([--with-dns-servers=DNSSERVERS],
- [Space-separated list of default DNS servers]),
+ [space-separated list of default DNS servers]),
[DNS_SERVERS="$withval"],
[DNS_SERVERS="8.8.8.8 8.8.4.4 2001:4860:4860::8888 2001:4860:4860::8844"])
@@ -1221,7 +1254,7 @@ AC_SUBST(DNS_SERVERS)
AC_ARG_WITH(default-dnssec,
AS_HELP_STRING([--with-default-dnssec=MODE],
- [Default DNSSEC mode, defaults to "allow-downgrade"]),
+ [default DNSSEC mode, defaults to "allow-downgrade"]),
[DEFAULT_DNSSEC_MODE="$withval"],
[DEFAULT_DNSSEC_MODE="allow-downgrade"])
@@ -1271,7 +1304,7 @@ AC_SUBST([EFI_ARCH])
AC_SUBST([EFI_MACHINE_TYPE_NAME])
have_gnuefi=no
-AC_ARG_ENABLE(gnuefi, AS_HELP_STRING([--enable-gnuefi], [Enable optional gnuefi support]))
+AC_ARG_ENABLE(gnuefi, AS_HELP_STRING([--enable-gnuefi], [enable optional gnuefi support]))
AS_IF([test "x$enable_gnuefi" != "xno"], [
AC_CHECK_HEADERS(efi/${EFI_ARCH}/efibind.h,
[AC_DEFINE(HAVE_GNUEFI, 1, [Define if gnuefi is available])
@@ -1284,14 +1317,14 @@ AS_IF([test "x$enable_gnuefi" != "xno"], [
EFI_LIB_DIR="$efiroot"
AC_ARG_WITH(efi-libdir,
- AS_HELP_STRING([--with-efi-libdir=PATH], [Path to EFI lib directory]),
+ AS_HELP_STRING([--with-efi-libdir=PATH], [path to EFI lib directory]),
[EFI_LIB_DIR="$withval"], [EFI_LIB_DIR="$efiroot"]
)
AC_SUBST([EFI_LIB_DIR])
have_efi_lds=no
AC_ARG_WITH(efi-ldsdir,
- AS_HELP_STRING([--with-efi-ldsdir=PATH], [Path to EFI lds directory]),
+ AS_HELP_STRING([--with-efi-ldsdir=PATH], [path to EFI lds directory]),
[EFI_LDS_DIR="$withval" && AS_IF([test -f "${EFI_LDS_DIR}/elf_${EFI_ARCH}_efi.lds"],
[have_efi_lds=yes])],
[AS_FOR([DIR], [EFI_LDS_DIR], ["${EFI_LIB_DIR}/gnuefi" "${EFI_LIB_DIR}"],
@@ -1304,7 +1337,7 @@ AS_IF([test "x$enable_gnuefi" != "xno"], [
[have_gnuefi=no])])
AC_ARG_WITH(efi-includedir,
- AS_HELP_STRING([--with-efi-includedir=PATH], [Path to EFI include directory]),
+ AS_HELP_STRING([--with-efi-includedir=PATH], [path to EFI include directory]),
[EFI_INC_DIR="$withval"], [EFI_INC_DIR="/usr/include"]
)
AC_SUBST([EFI_INC_DIR])
@@ -1313,7 +1346,7 @@ AM_CONDITIONAL(HAVE_GNUEFI, [test "x$have_gnuefi" = xyes])
# ------------------------------------------------------------------------------
have_tpm=no
-AC_ARG_ENABLE([tpm], AS_HELP_STRING([--enable-tpm],[Enable optional TPM support]),
+AC_ARG_ENABLE([tpm], AS_HELP_STRING([--enable-tpm], [enable optional TPM support]),
[case "${enableval}" in
yes) have_tpm=yes ;;
no) have_tpm=no ;;
@@ -1336,13 +1369,13 @@ AC_DEFINE_UNQUOTED(SD_TPM_PCR, [$SD_TPM_PCR], [TPM PCR register number to use])
# ------------------------------------------------------------------------------
AC_ARG_WITH(rc-local-script-path-start,
AS_HELP_STRING([--with-rc-local-script-path-start=PATH],
- [Path to /etc/rc.local]),
+ [path to /etc/rc.local]),
[RC_LOCAL_SCRIPT_PATH_START="$withval"],
[RC_LOCAL_SCRIPT_PATH_START="/etc/rc.local"])
AC_ARG_WITH(rc-local-script-path-stop,
AS_HELP_STRING([--with-rc-local-script-path-stop=PATH],
- [Path to /usr/sbin/halt.local]),
+ [path to /usr/sbin/halt.local]),
[RC_LOCAL_SCRIPT_PATH_STOP="$withval"],
[RC_LOCAL_SCRIPT_PATH_STOP="/usr/sbin/halt.local"])
@@ -1355,13 +1388,13 @@ AC_SUBST(RC_LOCAL_SCRIPT_PATH_STOP)
# ------------------------------------------------------------------------------
AC_ARG_WITH(kbd-loadkeys,
AS_HELP_STRING([--with-kbd-loadkeys=PATH],
- [Path to loadkeys]),
+ [path to loadkeys]),
[KBD_LOADKEYS="$withval"],
[KBD_LOADKEYS="/usr/bin/loadkeys"])
AC_ARG_WITH(kbd-setfont,
AS_HELP_STRING([--with-kbd-setfont=PATH],
- [Path to setfont]),
+ [path to setfont]),
[KBD_SETFONT="$withval"],
[KBD_SETFONT="/usr/bin/setfont"])
@@ -1373,7 +1406,7 @@ AC_SUBST(KBD_SETFONT)
AC_ARG_WITH(telinit,
AS_HELP_STRING([--with-telinit=PATH],
- [Path to telinit]),
+ [path to telinit]),
[TELINIT="$withval"],
[TELINIT="/lib/sysvinit/telinit"])
@@ -1403,7 +1436,7 @@ fi
AM_CONDITIONAL(HAVE_MYHOSTNAME, [test "$have_myhostname" = "yes"])
# ------------------------------------------------------------------------------
-AC_ARG_ENABLE(hwdb, [AC_HELP_STRING([--disable-hwdb], [disable hardware database support])],
+AC_ARG_ENABLE(hwdb, [AS_HELP_STRING([--disable-hwdb], [disable hardware database support])],
enable_hwdb=$enableval, enable_hwdb=yes)
AM_CONDITIONAL(ENABLE_HWDB, [test x$enable_hwdb = xyes])
@@ -1420,13 +1453,13 @@ AM_CONDITIONAL(ENABLE_MANPAGES, [test "x$have_manpages" = "xyes"])
# ------------------------------------------------------------------------------
AC_ARG_ENABLE(hibernate,
- [AC_HELP_STRING([--disable-hibernate], [disable hibernation support])],
+ [AS_HELP_STRING([--disable-hibernate], [disable hibernation support])],
enable_hibernate=$enableval, enable_hibernate=yes)
AM_CONDITIONAL(ENABLE_HIBERNATE, [test x$enable_hibernate = xyes])
# ------------------------------------------------------------------------------
AC_ARG_ENABLE(ldconfig,
- [AC_HELP_STRING([--disable-ldconfig], [disable ldconfig])],
+ [AS_HELP_STRING([--disable-ldconfig], [disable ldconfig])],
enable_ldconfig=$enableval, enable_ldconfig=yes)
AM_CONDITIONAL(ENABLE_LDCONFIG, [test x$enable_ldconfig = xyes])
@@ -1437,13 +1470,13 @@ SYSTEM_SYSVRCND_PATH=/etc/rc.d
AC_ARG_WITH([sysvinit-path],
[AS_HELP_STRING([--with-sysvinit-path=PATH],
- [Specify the path to where the SysV init scripts are located])],
+ [specify the path to where the SysV init scripts are located])],
[SYSTEM_SYSVINIT_PATH="$withval"],
[])
AC_ARG_WITH([sysvrcnd-path],
[AS_HELP_STRING([--with-sysvrcnd-path=PATH],
- [Specify the path to the base directory for the SysV rcN.d directories])],
+ [specify the path to the base directory for the SysV rcN.d directories])],
[SYSTEM_SYSVRCND_PATH="$withval"],
[])
@@ -1465,7 +1498,7 @@ AM_CONDITIONAL(HAVE_SYSV_COMPAT, test "$SYSTEM_SYSV_COMPAT" = "yes")
AC_ARG_WITH([tty-gid],
[AS_HELP_STRING([--with-tty-gid=GID],
- [Specify the numeric GID of the 'tty' group])],
+ [specify the numeric GID of the 'tty' group])],
[TTY_GID="$withval"],
[TTY_GID="5"])
@@ -1475,7 +1508,7 @@ AC_SUBST(TTY_GID)
AC_ARG_WITH([dbuspolicydir],
AS_HELP_STRING([--with-dbuspolicydir=DIR], [D-Bus policy directory]),
[],
- [with_dbuspolicydir=${sysconfdir}/dbus-1/system.d])
+ [with_dbuspolicydir=${datadir}/dbus-1/system.d])
AX_NORMALIZE_PATH([with_dbuspolicydir])
AC_ARG_WITH([dbussessionservicedir],
@@ -1491,7 +1524,7 @@ AC_ARG_WITH([dbussystemservicedir],
AX_NORMALIZE_PATH([with_dbussystemservicedir])
AC_ARG_WITH([bashcompletiondir],
- AS_HELP_STRING([--with-bashcompletiondir=DIR], [Bash completions directory]),
+ AS_HELP_STRING([--with-bashcompletiondir=DIR], [bash completions directory]),
[],
[AS_IF([$($PKG_CONFIG --exists bash-completion)], [
with_bashcompletiondir=$($PKG_CONFIG --variable=completionsdir bash-completion)
@@ -1502,7 +1535,7 @@ AM_CONDITIONAL(ENABLE_BASH_COMPLETION, [test "$with_bashcompletiondir" != "no"])
AX_NORMALIZE_PATH([with_bashcompletiondir])
AC_ARG_WITH([zshcompletiondir],
- AS_HELP_STRING([--with-zshcompletiondir=DIR], [Zsh completions directory]),
+ AS_HELP_STRING([--with-zshcompletiondir=DIR], [zsh completions directory]),
[], [with_zshcompletiondir=${datadir}/zsh/site-functions])
AM_CONDITIONAL(ENABLE_ZSH_COMPLETION, [test "$with_zshcompletiondir" != "no"])
AX_NORMALIZE_PATH([with_zshcompletiondir])
@@ -1520,26 +1553,32 @@ fi
AX_NORMALIZE_PATH([with_rootprefix])
AC_ARG_WITH([rootlibdir],
- AS_HELP_STRING([--with-rootlibdir=DIR], [Root directory for libraries necessary for boot]),
+ AS_HELP_STRING([--with-rootlibdir=DIR], [root directory for libraries necessary for boot]),
[],
[with_rootlibdir=${libdir}])
AX_NORMALIZE_PATH([with_rootlibdir])
AC_ARG_WITH([pamlibdir],
- AS_HELP_STRING([--with-pamlibdir=DIR], [Directory for PAM modules]),
+ AS_HELP_STRING([--with-pamlibdir=DIR], [directory for PAM modules]),
[],
[with_pamlibdir=${with_rootlibdir}/security])
AX_NORMALIZE_PATH([with_pamlibdir])
AC_ARG_WITH([pamconfdir],
- AS_HELP_STRING([--with-pamconfdir=DIR], [Directory for PAM configuration (pass no to disable installing)]),
+ AS_HELP_STRING([--with-pamconfdir=DIR], [directory for PAM configuration (pass no to disable installing)]),
[],
[with_pamconfdir=${sysconfdir}/pam.d])
AM_CONDITIONAL(ENABLE_PAM_CONFIG, [test "$with_pamconfdir" != "no"])
AX_NORMALIZE_PATH([with_pamconfdir])
+AC_ARG_WITH([rpmmacrosdir],
+ AS_HELP_STRING([--with-rpmmacrosdir=DIR], [directory to store macros for RPM]),
+ [], [with_rpmmacrosdir=\${prefix}/lib/rpm/macros.d])
+AM_CONDITIONAL(ENABLE_RPM_MACROS, [test "$with_rpmmacrosdir" != "no"])
+AX_NORMALIZE_PATH([with_rpmmacrosdir])
+
AC_ARG_ENABLE([split-usr],
- AS_HELP_STRING([--enable-split-usr], [Assume that /bin, /sbin aren\'t symlinks into /usr]),
+ AS_HELP_STRING([--enable-split-usr], [assume that /bin, /sbin aren't symlinks into /usr]),
[],
[AS_IF([test "x${ac_default_prefix}" != "x${with_rootprefix}"], [
enable_split_usr=yes
@@ -1566,13 +1605,13 @@ AS_IF([test x"$cross_compiling" = "xyes"], [], [
])
AC_ARG_ENABLE(tests,
- [AC_HELP_STRING([--disable-tests], [disable tests, or enable extra tests with =unsafe])],
+ [AS_HELP_STRING([--disable-tests], [disable tests, or enable extra tests with =unsafe])],
enable_tests=$enableval, enable_tests=yes)
AM_CONDITIONAL(ENABLE_TESTS, [test x$enable_tests = xyes -o x$enable_tests = xunsafe])
AM_CONDITIONAL(ENABLE_UNSAFE_TESTS, [test x$enable_tests = xunsafe])
AC_ARG_ENABLE(debug,
- [AC_HELP_STRING([--enable-debug@<:@=LIST@:>@], [enable extra debugging (hashmap,mmap-cache)])],
+ [AS_HELP_STRING([--enable-debug@<:@=LIST@:>@], [enable extra debugging (hashmap,mmap-cache)])],
[if test "x$enableval" = "xyes"; then
enableval="hashmap,mmap-cache"
fi
@@ -1608,6 +1647,7 @@ AC_SUBST([bashcompletiondir], [$with_bashcompletiondir])
AC_SUBST([zshcompletiondir], [$with_zshcompletiondir])
AC_SUBST([pamlibdir], [$with_pamlibdir])
AC_SUBST([pamconfdir], [$with_pamconfdir])
+AC_SUBST([rpmmacrosdir], [$with_rpmmacrosdir])
AC_SUBST([rootprefix], [$with_rootprefix])
AC_SUBST([rootlibdir], [$with_rootlibdir])
@@ -1645,25 +1685,27 @@ AC_MSG_RESULT([
vconsole: ${have_vconsole}
quotacheck: ${have_quotacheck}
tmpfiles: ${have_tmpfiles}
+ environment.d: ${have_environment_d}
sysusers: ${have_sysusers}
firstboot: ${have_firstboot}
randomseed: ${have_randomseed}
backlight: ${have_backlight}
rfkill: ${have_rfkill}
logind: ${have_logind}
- Default KillUserProcesses setting: ${KILL_USER_PROCESSES}
+ default cgroup hierarchy: ${DEFAULT_HIERARCHY}
+ default KillUserProcesses setting: ${KILL_USER_PROCESSES}
machined: ${have_machined}
importd: ${have_importd}
hostnamed: ${have_hostnamed}
timedated: ${have_timedated}
timesyncd: ${have_timesyncd}
- Default NTP servers: ${NTP_SERVERS}
+ default NTP servers: ${NTP_SERVERS}
time epoch: ${TIME_EPOCH}
localed: ${have_localed}
networkd: ${have_networkd}
resolved: ${have_resolved}
- Default DNS servers: ${DNS_SERVERS}
- Default DNSSEC mode: ${DEFAULT_DNSSEC_MODE}
+ default DNS servers: ${DNS_SERVERS}
+ default DNSSEC mode: ${DEFAULT_DNSSEC_MODE}
coredump: ${have_coredump}
polkit: ${have_polkit}
efi: ${have_efi}
@@ -1702,26 +1744,28 @@ AC_MSG_RESULT([
rootlib dir: ${with_rootlibdir}
SysV init scripts: ${SYSTEM_SYSVINIT_PATH}
SysV rc?.d directories: ${SYSTEM_SYSVRCND_PATH}
- Build Python: ${PYTHON}
+ build Python: ${PYTHON}
PAM modules dir: ${with_pamlibdir}
PAM configuration dir: ${with_pamconfdir}
+ RPM macros dir: ${with_rpmmacrosdir}
D-Bus policy dir: ${with_dbuspolicydir}
D-Bus session dir: ${with_dbussessionservicedir}
D-Bus system dir: ${with_dbussystemservicedir}
- Bash completions dir: ${with_bashcompletiondir}
- Zsh completions dir: ${with_zshcompletiondir}
- Extra start script: ${RC_LOCAL_SCRIPT_PATH_START}
- Extra stop script: ${RC_LOCAL_SCRIPT_PATH_STOP}
- Adm group: ${have_adm_group}
- Wheel group: ${have_wheel_group}
- Debug shell: ${SUSHELL} @ ${DEBUGTTY}
+ bash completions dir: ${with_bashcompletiondir}
+ zsh completions dir: ${with_zshcompletiondir}
+ extra start script: ${RC_LOCAL_SCRIPT_PATH_START}
+ extra stop script: ${RC_LOCAL_SCRIPT_PATH_STOP}
+ adm group: ${have_adm_group}
+ wheel group: ${have_wheel_group}
+ debug shell: ${SUSHELL} @ ${DEBUGTTY}
TTY GID: ${TTY_GID}
- Maximum System UID: ${SYSTEM_UID_MAX}
- Maximum System GID: ${SYSTEM_GID_MAX}
- Certificate root: ${CERTIFICATEROOT}
- Support URL: ${SUPPORT_URL}
- Nobody User Name: ${NOBODY_USER_NAME}
- Nobody Group Name: ${NOBODY_GROUP_NAME}
+ maximum system UID: ${SYSTEM_UID_MAX}
+ maximum system GID: ${SYSTEM_GID_MAX}
+ certificate root: ${CERTIFICATEROOT}
+ support URL: ${SUPPORT_URL}
+ nobody user name: ${NOBODY_USER_NAME}
+ nobody group name: ${NOBODY_GROUP_NAME}
+ fallback hostname: ${FALLBACK_HOSTNAME}
CFLAGS: ${OUR_CFLAGS} ${CFLAGS}
CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS}
diff --git a/docs/sysvinit/README.in b/docs/sysvinit/README.in
index 996402d06b..de5d80d902 100644
--- a/docs/sysvinit/README.in
+++ b/docs/sysvinit/README.in
@@ -24,4 +24,4 @@ Further reading:
man:systemctl(1)
man:systemd(1)
http://0pointer.de/blog/projects/systemd-for-admins-3.html
- http://www.freedesktop.org/wiki/Software/systemd/Incompatibilities
+ https://www.freedesktop.org/wiki/Software/systemd/Incompatibilities
diff --git a/hwdb/20-OUI.hwdb b/hwdb/20-OUI.hwdb
index 6bce57305d..2f0dbc9e74 100644
--- a/hwdb/20-OUI.hwdb
+++ b/hwdb/20-OUI.hwdb
@@ -356,9 +356,6 @@ OUI:70B3D5660*
OUI:70B3D5EFE*
ID_OUI_FROM_DATABASE=MEIDEN SYSTEM SOLUTIONS
-OUI:70B3D5C60*
- ID_OUI_FROM_DATABASE=Aircell Inc
-
OUI:70B3D5C03*
ID_OUI_FROM_DATABASE=XAVi Technologies Corp.
@@ -1100,6 +1097,114 @@ OUI:70B3D55D3*
OUI:70B3D52AD*
ID_OUI_FROM_DATABASE=Opgal Optronic Industries
+OUI:70B3D58EC*
+ ID_OUI_FROM_DATABASE=Rudy Tellert
+
+OUI:70B3D5CF5*
+ ID_OUI_FROM_DATABASE=Petring Energietechnik GmbH
+
+OUI:70B3D5FF7*
+ ID_OUI_FROM_DATABASE=Cybercom AB
+
+OUI:70B3D5DCC*
+ ID_OUI_FROM_DATABASE=Eutron SPA
+
+OUI:70B3D5269*
+ ID_OUI_FROM_DATABASE=Gilbarco Veeder-Root ‎
+
+OUI:70B3D5173*
+ ID_OUI_FROM_DATABASE=National TeleConsultants LLC
+
+OUI:70B3D515C*
+ ID_OUI_FROM_DATABASE=Woods Hole Oceanographic Institution
+
+OUI:70B3D5CAE*
+ ID_OUI_FROM_DATABASE=THEMA
+
+OUI:70B3D55BC*
+ ID_OUI_FROM_DATABASE=LAMTEC Meß- und Regeltechnik für Feuerungen GmbH & Co. KG
+
+OUI:70B3D51B8*
+ ID_OUI_FROM_DATABASE=OES Inc.
+
+OUI:70B3D585A*
+ ID_OUI_FROM_DATABASE=BRUSHIES
+
+OUI:70B3D5FAF*
+ ID_OUI_FROM_DATABASE=Radig Hard & Software
+
+OUI:70B3D57A2*
+ ID_OUI_FROM_DATABASE=Alpha ESS Co., Ltd.
+
+OUI:70B3D50BC*
+ ID_OUI_FROM_DATABASE=Practical Software Studio LLC
+
+OUI:70B3D5724*
+ ID_OUI_FROM_DATABASE=Quan International Co., Ltd.
+
+OUI:70B3D553B*
+ ID_OUI_FROM_DATABASE=Mr.Loop
+
+OUI:70B3D5EBE*
+ ID_OUI_FROM_DATABASE=Sierra Pacific Innovations Corp
+
+OUI:70B3D5103*
+ ID_OUI_FROM_DATABASE=HANYOUNG NUX CO.,LTD
+
+OUI:70B3D504A*
+ ID_OUI_FROM_DATABASE=Gecko Robotics Inc
+
+OUI:70B3D5040*
+ ID_OUI_FROM_DATABASE=Savari Inc
+
+OUI:70B3D592A*
+ ID_OUI_FROM_DATABASE=Miravue
+
+OUI:70B3D5063*
+ ID_OUI_FROM_DATABASE=PoolDigital GmbH & Co. KG
+
+OUI:70B3D5209*
+ ID_OUI_FROM_DATABASE=SmartNodes
+
+OUI:70B3D514C*
+ ID_OUI_FROM_DATABASE=CRDE
+
+OUI:70B3D5AB8*
+ ID_OUI_FROM_DATABASE=HORIBA MEDICAL
+
+OUI:70B3D5F9E*
+ ID_OUI_FROM_DATABASE=International Center for Elementary Particle Physics, The University of Tokyo
+
+OUI:70B3D59C6*
+ ID_OUI_FROM_DATABASE=Overspeed SARL
+
+OUI:70B3D507A*
+ ID_OUI_FROM_DATABASE=ZAO ZEO
+
+OUI:70B3D506B*
+ ID_OUI_FROM_DATABASE=U-Tech
+
+OUI:70B3D5F77*
+ ID_OUI_FROM_DATABASE=Satcube AB
+
+OUI:70B3D57A1*
+ ID_OUI_FROM_DATABASE=Excelfore Corporation
+
+OUI:70B3D590D*
+ ID_OUI_FROM_DATABASE=Modtronix Engineering
+
+OUI:70B3D5C60*
+ ID_OUI_FROM_DATABASE=Gogo BA
+
+OUI:70B3D5A73*
+ ID_OUI_FROM_DATABASE=MobiPromo
+
+OUI:70B3D5585*
+ ID_OUI_FROM_DATABASE=Nefteavtomatika
+
+OUI:70B3D5495*
+ ID_OUI_FROM_DATABASE=Fiem Industries Ltd.
+
OUI:70B3D5D60*
ID_OUI_FROM_DATABASE=Flintab AB
@@ -2153,6 +2258,126 @@ OUI:70B3D57F4*
OUI:70B3D5122*
ID_OUI_FROM_DATABASE=Henri Systems Holland bv
+OUI:70B3D5767*
+ ID_OUI_FROM_DATABASE=FRANKLIN FRANCE
+
+OUI:70B3D5465*
+ ID_OUI_FROM_DATABASE=ENERGISME
+
+OUI:70B3D5E09*
+ ID_OUI_FROM_DATABASE=L-3 communications ComCept Division
+
+OUI:70B3D5A07*
+ ID_OUI_FROM_DATABASE=IoTrek Technology Private Limited
+
+OUI:70B3D521D*
+ ID_OUI_FROM_DATABASE=iRF - Intelligent RF Solutions, LLC
+
+OUI:70B3D5E9C*
+ ID_OUI_FROM_DATABASE=ATG UV Technology
+
+OUI:70B3D539E*
+ ID_OUI_FROM_DATABASE=Lanmark Controls Inc.
+
+OUI:70B3D5267*
+ ID_OUI_FROM_DATABASE=Zehntner Testing Instruments
+
+OUI:70B3D5C2E*
+ ID_OUI_FROM_DATABASE=Triax A/S
+
+OUI:70B3D50EF*
+ ID_OUI_FROM_DATABASE=Dextera Labs
+
+OUI:70B3D54C2*
+ ID_OUI_FROM_DATABASE=hera Laborsysteme GmbH
+
+OUI:70B3D50A1*
+ ID_OUI_FROM_DATABASE=PTN Electronics Limited
+
+OUI:70B3D5AA4*
+ ID_OUI_FROM_DATABASE=Pullnet Technology,S.L.
+
+OUI:70B3D5C68*
+ ID_OUI_FROM_DATABASE=Mini Solution Co. Ltd.
+
+OUI:70B3D581A*
+ ID_OUI_FROM_DATABASE=Joehl & Koeferli AG
+
+OUI:70B3D586E*
+ ID_OUI_FROM_DATABASE=Profcon AB
+
+OUI:70B3D50E8*
+ ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG
+
+OUI:70B3D59D9*
+ ID_OUI_FROM_DATABASE=ATX Networks Corp
+
+OUI:70B3D5348*
+ ID_OUI_FROM_DATABASE=BÄR Bahnsicherung AG
+
+OUI:70B3D5A30*
+ ID_OUI_FROM_DATABASE=SHEN ZHEN HUAWANG TECHNOLOGY CO; LTD
+
+OUI:70B3D5DFD*
+ ID_OUI_FROM_DATABASE=Contiweb
+
+OUI:70B3D5B30*
+ ID_OUI_FROM_DATABASE=Systolé Hardware B.V.
+
+OUI:70B3D53BF*
+ ID_OUI_FROM_DATABASE=Star Electronics GmbH & Co. KG
+
+OUI:70B3D5745*
+ ID_OUI_FROM_DATABASE=TMSI LLC
+
+OUI:70B3D5D1C*
+ ID_OUI_FROM_DATABASE=Specialised Imaging Limited
+
+OUI:70B3D5E8E*
+ ID_OUI_FROM_DATABASE=Macnica Technology
+
+OUI:70B3D5ADF*
+ ID_OUI_FROM_DATABASE=Seraphim Optronics Ltd
+
+OUI:70B3D522C*
+ ID_OUI_FROM_DATABASE=Hiquel Elektronik- und Anlagenbau GmbH
+
+OUI:70B3D5DCE*
+ ID_OUI_FROM_DATABASE=Stahl GmbH
+
+OUI:70B3D52A2*
+ ID_OUI_FROM_DATABASE=Visualware, Inc.
+
+OUI:70B3D5D08*
+ ID_OUI_FROM_DATABASE=Veeco Instruments
+
+OUI:70B3D5630*
+ ID_OUI_FROM_DATABASE=LGE
+
+OUI:70B3D5873*
+ ID_OUI_FROM_DATABASE=Vishay Nobel AB
+
+OUI:70B3D5653*
+ ID_OUI_FROM_DATABASE=Luxar Tech, Inc.
+
+OUI:70B3D5F1F*
+ ID_OUI_FROM_DATABASE=HKC Limited
+
+OUI:70B3D5AF6*
+ ID_OUI_FROM_DATABASE=S.C.E. srl
+
+OUI:70B3D5F37*
+ ID_OUI_FROM_DATABASE=Mitsubishi Electric Micro-Computer Application Software Co.,Ltd.
+
+OUI:70B3D58C3*
+ ID_OUI_FROM_DATABASE=Wyebot, Inc.
+
+OUI:70B3D542D*
+ ID_OUI_FROM_DATABASE=RCH Italia SpA
+
+OUI:70B3D5332*
+ ID_OUI_FROM_DATABASE=InnoSenT
+
OUI:70B3D5494*
ID_OUI_FROM_DATABASE=Schildknecht AG
@@ -2225,9 +2450,6 @@ OUI:70B3D5061*
OUI:70B3D5383*
ID_OUI_FROM_DATABASE=LPA Excil Electronics
-OUI:70B3D59F6*
- ID_OUI_FROM_DATABASE=Edgeware AB
-
OUI:70B3D5504*
ID_OUI_FROM_DATABASE=Xsight Systems Ltd.
@@ -3209,15 +3431,108 @@ OUI:70B3D516F*
OUI:70B3D59C0*
ID_OUI_FROM_DATABASE=Schneider Displaytechnik GmbH
-OUI:70B3D5149*
- ID_OUI_FROM_DATABASE=eleven-x
-
OUI:70B3D5E98*
ID_OUI_FROM_DATABASE=JSC Kaluga Astral
OUI:70B3D5443*
ID_OUI_FROM_DATABASE=Slot3 GmbH
+OUI:70B3D5149*
+ ID_OUI_FROM_DATABASE=eleven-x
+
+OUI:70B3D5952*
+ ID_OUI_FROM_DATABASE=REQUEA
+
+OUI:70B3D5BAA*
+ ID_OUI_FROM_DATABASE=Device Solutions Ltd
+
+OUI:70B3D5C5C*
+ ID_OUI_FROM_DATABASE=Layer Logic Inc
+
+OUI:70B3D5F3B*
+ ID_OUI_FROM_DATABASE=Epdm Pty Ltd
+
+OUI:70B3D536F*
+ ID_OUI_FROM_DATABASE=BuddyGuard GmbH
+
+OUI:70B3D59F6*
+ ID_OUI_FROM_DATABASE=Edgeware AB
+
+OUI:70B3D5222*
+ ID_OUI_FROM_DATABASE=Marioff Corporation Oy
+
+OUI:70B3D50E3*
+ ID_OUI_FROM_DATABASE=SinTau SrL
+
+OUI:70B3D52E5*
+ ID_OUI_FROM_DATABASE=Fläkt Woods AB
+
+OUI:70B3D588D*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:70B3D5A8B*
+ ID_OUI_FROM_DATABASE=Giant Power Technology Biomedical Corporation
+
+OUI:70B3D50F1*
+ ID_OUI_FROM_DATABASE=Beijing One City Science & Technology Co., LTD
+
+OUI:70B3D5F70*
+ ID_OUI_FROM_DATABASE=Honeywell
+
+OUI:70B3D59CE*
+ ID_OUI_FROM_DATABASE=Terragene S.A
+
+OUI:70B3D5CEA*
+ ID_OUI_FROM_DATABASE=Computerwise, Inc.
+
+OUI:70B3D5F1D*
+ ID_OUI_FROM_DATABASE=Critical Link LLC
+
+OUI:70B3D5F05*
+ ID_OUI_FROM_DATABASE=Motomuto Aps
+
+OUI:70B3D5FFC*
+ ID_OUI_FROM_DATABASE=Symetrics Industries d.b.a. Extant Aerospace
+
+OUI:70B3D530E*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:70B3D54F8*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:70B3D55E0*
+ ID_OUI_FROM_DATABASE=Hexagon Metrology SAS
+
+OUI:70B3D5B2B*
+ ID_OUI_FROM_DATABASE=Vtron Pty Ltd
+
+OUI:70B3D59D0*
+ ID_OUI_FROM_DATABASE=RJ45 Technologies
+
+OUI:70B3D5672*
+ ID_OUI_FROM_DATABASE=KLEIBER Infrared GmbH
+
+OUI:70B3D5572*
+ ID_OUI_FROM_DATABASE=CRDE
+
+OUI:70B3D5927*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:70B3D5489*
+ ID_OUI_FROM_DATABASE=ard sa
+
+OUI:70B3D52B1*
+ ID_OUI_FROM_DATABASE=WIXCON Co., Ltd
+
+OUI:70B3D5B6A*
+ ID_OUI_FROM_DATABASE=YUYAMA MFG Co.,Ltd
+
+OUI:70B3D5579*
+ ID_OUI_FROM_DATABASE=Chelsea Technologies Group Ltd
+
+OUI:70B3D59B2*
+ ID_OUI_FROM_DATABASE=CONTINENT, Ltd
+
OUI:70B3D566B*
ID_OUI_FROM_DATABASE=Innitive B.V.
@@ -3629,9 +3944,6 @@ OUI:70B3D5010*
OUI:70B3D586D*
ID_OUI_FROM_DATABASE=Census Digital Incorporated
-OUI:70B3D560B*
- ID_OUI_FROM_DATABASE=Edgeware AB
-
OUI:70B3D5ADD*
ID_OUI_FROM_DATABASE=GHL Systems Berhad
@@ -4253,6 +4565,153 @@ OUI:70B3D5542*
OUI:70B3D568E*
ID_OUI_FROM_DATABASE=CEA Technologies Pty Ltd
+OUI:70B3D51E4*
+ ID_OUI_FROM_DATABASE=Tecnologix s.r.l.
+
+OUI:70B3D51C5*
+ ID_OUI_FROM_DATABASE=ELSAG
+
+OUI:70B3D5635*
+ ID_OUI_FROM_DATABASE=Cosylab d.d.
+
+OUI:70B3D5D84*
+ ID_OUI_FROM_DATABASE=Sentry360
+
+OUI:70B3D575A*
+ ID_OUI_FROM_DATABASE=Standard Backhaul Communications
+
+OUI:70B3D5482*
+ ID_OUI_FROM_DATABASE=Aeryon Labs Inc
+
+OUI:70B3D5FBF*
+ ID_OUI_FROM_DATABASE=SenSys (Design Electronics Ltd)
+
+OUI:70B3D5825*
+ ID_OUI_FROM_DATABASE=TATTILE SRL
+
+OUI:70B3D5039*
+ ID_OUI_FROM_DATABASE=DoWoo Digitech
+
+OUI:70B3D527E*
+ ID_OUI_FROM_DATABASE=Mettler Toledo Hi Speed
+
+OUI:70B3D5D37*
+ ID_OUI_FROM_DATABASE=Sicon srl
+
+OUI:70B3D5F83*
+ ID_OUI_FROM_DATABASE=Tata Communications Ltd.
+
+OUI:70B3D560B*
+ ID_OUI_FROM_DATABASE=Edgeware AB
+
+OUI:70B3D50D9*
+ ID_OUI_FROM_DATABASE=Brechbuehler AG
+
+OUI:70B3D537C*
+ ID_OUI_FROM_DATABASE=Merus Power Dynamics Ltd.
+
+OUI:70B3D54CF*
+ ID_OUI_FROM_DATABASE=GREEN HOUSE CO., LTD.
+
+OUI:70B3D5EF8*
+ ID_OUI_FROM_DATABASE=DKS Dienstl.ges. f. Komm.anl. d. Stadt- u. Reg.verk. mbH
+
+OUI:70B3D5D58*
+ ID_OUI_FROM_DATABASE=Idyllic Engineering Pte Ltd
+
+OUI:70B3D5954*
+ ID_OUI_FROM_DATABASE=Dot System S.r.l.
+
+OUI:70B3D5880*
+ ID_OUI_FROM_DATABASE=Skopei B.V.
+
+OUI:70B3D5D40*
+ ID_OUI_FROM_DATABASE=CRDE
+
+OUI:70B3D551C*
+ ID_OUI_FROM_DATABASE=ATX Networks Corp
+
+OUI:70B3D5511*
+ ID_OUI_FROM_DATABASE=Next Sight srl
+
+OUI:70B3D5FBD*
+ ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme
+
+OUI:70B3D5FA7*
+ ID_OUI_FROM_DATABASE=Nordson Corporation
+
+OUI:70B3D585E*
+ ID_OUI_FROM_DATABASE=XLOGIC srl
+
+OUI:70B3D531C*
+ ID_OUI_FROM_DATABASE=FINANCIERE DE L'OMBREE (eolane)
+
+OUI:70B3D5C41*
+ ID_OUI_FROM_DATABASE=Merlin CSI
+
+OUI:70B3D5902*
+ ID_OUI_FROM_DATABASE=Unlimiterhear co.,ltd. taiwan branch
+
+OUI:70B3D5AD1*
+ ID_OUI_FROM_DATABASE=Sensile Technologies SA
+
+OUI:70B3D5637*
+ ID_OUI_FROM_DATABASE=INEO-SENSE
+
+OUI:70B3D5397*
+ ID_OUI_FROM_DATABASE=Guangxi Hunter Information Industry Co.,Ltd
+
+OUI:70B3D5378*
+ ID_OUI_FROM_DATABASE=synchrotron SOLEIL
+
+OUI:70B3D57B2*
+ ID_OUI_FROM_DATABASE=Rail Power Systems GmbH
+
+OUI:70B3D5F12*
+ ID_OUI_FROM_DATABASE=Incoil Induktion AB
+
+OUI:70B3D5997*
+ ID_OUI_FROM_DATABASE=ProTom International
+
+OUI:70B3D5288*
+ ID_OUI_FROM_DATABASE=Bresslergroup
+
+OUI:70B3D54BE*
+ ID_OUI_FROM_DATABASE=GY-FX SAS
+
+OUI:70B3D510F*
+ ID_OUI_FROM_DATABASE=neQis
+
+OUI:70B3D598C*
+ ID_OUI_FROM_DATABASE=University of Wisconsin Madison - Department of High Energy Physics
+
+OUI:70B3D5E04*
+ ID_OUI_FROM_DATABASE=Combilent
+
+OUI:70B3D5022*
+ ID_OUI_FROM_DATABASE=Ravelin Ltd
+
+OUI:70B3D5135*
+ ID_OUI_FROM_DATABASE=DORLET SAU
+
+OUI:70B3D5FF1*
+ ID_OUI_FROM_DATABASE=Data Strategy Limited
+
+OUI:70B3D5002*
+ ID_OUI_FROM_DATABASE=Gogo BA
+
+OUI:70B3D50B0*
+ ID_OUI_FROM_DATABASE=Raven Systems Design, Inc
+
+OUI:70B3D5596*
+ ID_OUI_FROM_DATABASE=Mencom Corporation
+
+OUI:70B3D5138*
+ ID_OUI_FROM_DATABASE=SMITEC S.p.A.
+
+OUI:70B3D517A*
+ ID_OUI_FROM_DATABASE=Gencoa Ltd
+
OUI:70B3D58AB*
ID_OUI_FROM_DATABASE=EMAC, Inc.
@@ -5258,6 +5717,141 @@ OUI:70B3D5FF4*
OUI:70B3D5760*
ID_OUI_FROM_DATABASE=QUALITTEQ LLC
+OUI:70B3D5272*
+ ID_OUI_FROM_DATABASE=TELECOM SANTE
+
+OUI:70B3D520D*
+ ID_OUI_FROM_DATABASE=Engage Technologies
+
+OUI:70B3D5D55*
+ ID_OUI_FROM_DATABASE=WM Design s.r.o
+
+OUI:70B3D5523*
+ ID_OUI_FROM_DATABASE=Tibit Communications
+
+OUI:70B3D5E67*
+ ID_OUI_FROM_DATABASE=APPLIED PROCESSING
+
+OUI:70B3D5241*
+ ID_OUI_FROM_DATABASE=Bolide Technology Group, Inc.
+
+OUI:70B3D5D25*
+ ID_OUI_FROM_DATABASE=ENGenesis
+
+OUI:70B3D54A9*
+ ID_OUI_FROM_DATABASE=WARECUBE,INC
+
+OUI:70B3D52F8*
+ ID_OUI_FROM_DATABASE=Tunstall A/S
+
+OUI:70B3D50A3*
+ ID_OUI_FROM_DATABASE=Solace Systems Inc.
+
+OUI:70B3D5FC2*
+ ID_OUI_FROM_DATABASE=HUNTER LIBERTY CORPORATION
+
+OUI:70B3D561C*
+ ID_OUI_FROM_DATABASE=Earth Works
+
+OUI:70B3D56EA*
+ ID_OUI_FROM_DATABASE=Edgeware AB
+
+OUI:70B3D5A05*
+ ID_OUI_FROM_DATABASE=Transas Marine Limited
+
+OUI:70B3D5AA6*
+ ID_OUI_FROM_DATABASE=Proximus
+
+OUI:70B3D55E5*
+ ID_OUI_FROM_DATABASE=HAIYANG OLIX CO.,LTD.
+
+OUI:70B3D5E2C*
+ ID_OUI_FROM_DATABASE=Fourth Frontier Technologies Private Limited
+
+OUI:70B3D51D4*
+ ID_OUI_FROM_DATABASE=Brinkmann Audio GmbH
+
+OUI:70B3D55CA*
+ ID_OUI_FROM_DATABASE=ACD Elekronik GmbH
+
+OUI:70B3D5427*
+ ID_OUI_FROM_DATABASE=Key Chemical & Equipment Company
+
+OUI:70B3D5753*
+ ID_OUI_FROM_DATABASE=HCH. Kündig & CIE. AG
+
+OUI:70B3D5A18*
+ ID_OUI_FROM_DATABASE=Embedded Systems Lukasz Panasiuk
+
+OUI:70B3D50C2*
+ ID_OUI_FROM_DATABASE=LOOK EASY INTERNATIONAL LIMITED
+
+OUI:70B3D51DE*
+ ID_OUI_FROM_DATABASE=DYCEC, S.A.
+
+OUI:70B3D516C*
+ ID_OUI_FROM_DATABASE=OCEAN
+
+OUI:70B3D5778*
+ ID_OUI_FROM_DATABASE=Lumacron Technology Ltd.
+
+OUI:70B3D505D*
+ ID_OUI_FROM_DATABASE=KOMS Co.,Ltd.
+
+OUI:70B3D5EC8*
+ ID_OUI_FROM_DATABASE=Viko Elektrik-Elektronik A.Åž.
+
+OUI:70B3D53F0*
+ ID_OUI_FROM_DATABASE=Intervala
+
+OUI:70B3D5B1A*
+ ID_OUI_FROM_DATABASE=Aaronia AG
+
+OUI:70B3D5BD1*
+ ID_OUI_FROM_DATABASE=CableLabs
+
+OUI:70B3D5F0D*
+ ID_OUI_FROM_DATABASE=MeQ Inc.
+
+OUI:70B3D5215*
+ ID_OUI_FROM_DATABASE=Dataspeed Inc
+
+OUI:70B3D5115*
+ ID_OUI_FROM_DATABASE=Welltec Corp.
+
+OUI:70B3D5C45*
+ ID_OUI_FROM_DATABASE=Stiebel Eltron GmbH
+
+OUI:70B3D5B56*
+ ID_OUI_FROM_DATABASE=Power Electronics Espana, S.L.
+
+OUI:70B3D5911*
+ ID_OUI_FROM_DATABASE=Equatel
+
+OUI:70B3D5661*
+ ID_OUI_FROM_DATABASE=DesignA Electronics Limited
+
+OUI:70B3D5011*
+ ID_OUI_FROM_DATABASE=Sumer Data S.L
+
+OUI:70B3D52C2*
+ ID_OUI_FROM_DATABASE=Quantum Detectors
+
+OUI:70B3D5BF3*
+ ID_OUI_FROM_DATABASE=CG-WIRELESS
+
+OUI:70B3D59A1*
+ ID_OUI_FROM_DATABASE=ITS Industrial Turbine Services GmbH
+
+OUI:70B3D5861*
+ ID_OUI_FROM_DATABASE=KST technology
+
+OUI:70B3D5442*
+ ID_OUI_FROM_DATABASE=Blair Companies
+
+OUI:70B3D5C74*
+ ID_OUI_FROM_DATABASE=Qtechnology A/S
+
OUI:1C8776D*
ID_OUI_FROM_DATABASE=Qivivo
@@ -5690,9 +6284,6 @@ OUI:78CA83E*
OUI:38B8EBB*
ID_OUI_FROM_DATABASE=ExaScaler Inc.
-OUI:38FDFEC*
- ID_OUI_FROM_DATABASE=New Garden Co., Ltd.
-
OUI:38FDFE5*
ID_OUI_FROM_DATABASE=CaptiveAire Systems Inc.
@@ -6014,6 +6605,96 @@ OUI:8CC8F4C*
OUI:40F385D*
ID_OUI_FROM_DATABASE=Digital Bros S.p.A.
+OUI:40F3854*
+ ID_OUI_FROM_DATABASE=Embedded IQ
+
+OUI:40F3859*
+ ID_OUI_FROM_DATABASE=Fast Precision Technologies Co. Ltd.
+
+OUI:1CA0D32*
+ ID_OUI_FROM_DATABASE=NovTech, Inc.
+
+OUI:40F3850*
+ ID_OUI_FROM_DATABASE=SubPac
+
+OUI:38FDFEC*
+ ID_OUI_FROM_DATABASE=New Garden Co., Ltd.
+
+OUI:1CA0D3E*
+ ID_OUI_FROM_DATABASE=Exicom Tele-Systems Ltd.
+
+OUI:A411630*
+ ID_OUI_FROM_DATABASE=Adetel Equipment
+
+OUI:A411637*
+ ID_OUI_FROM_DATABASE=SHENZHEN YIWANJIA INFORMATION TECHNOLOGY CO.,LTD
+
+OUI:144FD72*
+ ID_OUI_FROM_DATABASE=FedEx Services OTI
+
+OUI:144FD79*
+ ID_OUI_FROM_DATABASE=Emerson Network Power (India) Pvt. Ltd.
+
+OUI:144FD7D*
+ ID_OUI_FROM_DATABASE=Shanghai B&A Technology Co., Ltd
+
+OUI:144FD73*
+ ID_OUI_FROM_DATABASE=Qingdao Wodatong Electronics Co., Ltd.
+
+OUI:98AAFC0*
+ ID_OUI_FROM_DATABASE=Dalian Eastern Display Co., Ltd.
+
+OUI:98AAFC9*
+ ID_OUI_FROM_DATABASE=BEAM Authentic
+
+OUI:98AAFCE*
+ ID_OUI_FROM_DATABASE=Comarch S.A.
+
+OUI:98AAFC8*
+ ID_OUI_FROM_DATABASE=Beijing Tiandi-Marco Electro-Hydraulic Control System Company Ltd.
+
+OUI:98AAFCC*
+ ID_OUI_FROM_DATABASE=dots Inc.
+
+OUI:08ED026*
+ ID_OUI_FROM_DATABASE=SANGO ELECTRONICS CO
+
+OUI:08ED023*
+ ID_OUI_FROM_DATABASE=Jiangsu Logread Network Technology Co., LTD.
+
+OUI:08ED024*
+ ID_OUI_FROM_DATABASE=Fio Corporation
+
+OUI:60D7E3D*
+ ID_OUI_FROM_DATABASE=Quantronix, Inc.
+
+OUI:60D7E36*
+ ID_OUI_FROM_DATABASE=Ameli s.r.l.
+
+OUI:60D7E3B*
+ ID_OUI_FROM_DATABASE=Nextivity
+
+OUI:60D7E30*
+ ID_OUI_FROM_DATABASE=Avalun
+
+OUI:F023B98*
+ ID_OUI_FROM_DATABASE=G3 TECHNOLOGIES< INC
+
+OUI:F023B9E*
+ ID_OUI_FROM_DATABASE=Domotz Ltd
+
+OUI:F023B92*
+ ID_OUI_FROM_DATABASE=Raysgem Electronics and Technology Co.Ltd
+
+OUI:F023B95*
+ ID_OUI_FROM_DATABASE=Audeara Pty. Ltd.
+
+OUI:8C147DC*
+ ID_OUI_FROM_DATABASE=Reynaers Aluminium
+
+OUI:8C147D0*
+ ID_OUI_FROM_DATABASE=Nio
+
OUI:1C8776C*
ID_OUI_FROM_DATABASE=Strone Technology
@@ -6785,6 +7466,78 @@ OUI:8CC8F4A*
OUI:40F3856*
ID_OUI_FROM_DATABASE=Lennox International Incorporated
+OUI:40F3855*
+ ID_OUI_FROM_DATABASE=KATO ENGINEERING INC.
+
+OUI:1CA0D35*
+ ID_OUI_FROM_DATABASE=Dynamic Connect (Suzhou) Hi-Tech Electronic Co.,Ltd.
+
+OUI:1CA0D33*
+ ID_OUI_FROM_DATABASE=SAVELEC
+
+OUI:1CA0D37*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:A411634*
+ ID_OUI_FROM_DATABASE=AlterG, Inc.
+
+OUI:A411631*
+ ID_OUI_FROM_DATABASE=INTER CONTROL Hermann Köhler Elektrik GmbH & Co.KG
+
+OUI:144FD77*
+ ID_OUI_FROM_DATABASE=Shenzhen V-Streaming Technology Co., Ltd.
+
+OUI:144FD7A*
+ ID_OUI_FROM_DATABASE=Unirobot Corporation
+
+OUI:98AAFC1*
+ ID_OUI_FROM_DATABASE=SURTEC
+
+OUI:08ED028*
+ ID_OUI_FROM_DATABASE=HANTAS CO., LTD.
+
+OUI:08ED027*
+ ID_OUI_FROM_DATABASE=Eleven Engineering Incorporated
+
+OUI:08ED022*
+ ID_OUI_FROM_DATABASE=TES Touch Embedded Solutions Inc.
+
+OUI:08ED02E*
+ ID_OUI_FROM_DATABASE=Telstra Corporation Limited
+
+OUI:60D7E3C*
+ ID_OUI_FROM_DATABASE=Zhejiang Send Intelligent Technology,Ltd
+
+OUI:60D7E38*
+ ID_OUI_FROM_DATABASE=HindlePower, Inc
+
+OUI:60D7E3A*
+ ID_OUI_FROM_DATABASE=Wilderness Labs Inc.
+
+OUI:60D7E31*
+ ID_OUI_FROM_DATABASE=Elap s.r.l.
+
+OUI:04714B1*
+ ID_OUI_FROM_DATABASE=uAvionix Corporation
+
+OUI:04714B2*
+ ID_OUI_FROM_DATABASE=Shenzhen WayOS Technology Crop., Ltd.
+
+OUI:04714B8*
+ ID_OUI_FROM_DATABASE=Energport Inc
+
+OUI:8C147D5*
+ ID_OUI_FROM_DATABASE=Unwired Networks
+
+OUI:F023B94*
+ ID_OUI_FROM_DATABASE=EZVIS LIMITED
+
+OUI:F023B9A*
+ ID_OUI_FROM_DATABASE=annapurnalabs
+
+OUI:8C147D2*
+ ID_OUI_FROM_DATABASE=Agilent S.p.A
+
OUI:1C87765*
ID_OUI_FROM_DATABASE=Zhuhai MYZR Technology Co.,Ltd
@@ -7505,9 +8258,6 @@ OUI:AC64DDD*
OUI:AC64DD0*
ID_OUI_FROM_DATABASE=Jia-Teng
-OUI:4CE1731*
- ID_OUI_FROM_DATABASE=Datastorm Technologies Inc.
-
OUI:4CE1733*
ID_OUI_FROM_DATABASE=outpaceIO
@@ -7580,6 +8330,93 @@ OUI:8CC8F48*
OUI:8CC8F4E*
ID_OUI_FROM_DATABASE=Evaporcool Solutions
+OUI:40F385B*
+ ID_OUI_FROM_DATABASE=URMET Home & Building Solutions Pty Ltd
+
+OUI:40F3858*
+ ID_OUI_FROM_DATABASE=Teleepoch Ltd
+
+OUI:1CA0D3B*
+ ID_OUI_FROM_DATABASE=Guang Dong He Zheng Network Technology Co.,Ltd
+
+OUI:1CA0D3D*
+ ID_OUI_FROM_DATABASE=ERATO (HK) Corporation Limited
+
+OUI:1CA0D3A*
+ ID_OUI_FROM_DATABASE=DSM Messtechnik GmbH
+
+OUI:1CA0D38*
+ ID_OUI_FROM_DATABASE=Desarrollos y Soluciones Guinea I+D S.L.
+
+OUI:A411638*
+ ID_OUI_FROM_DATABASE=Dspread Technology (Beijing) Inc.
+
+OUI:A411639*
+ ID_OUI_FROM_DATABASE=accesso Technology Group
+
+OUI:A41163A*
+ ID_OUI_FROM_DATABASE=ISE GmbH
+
+OUI:A411635*
+ ID_OUI_FROM_DATABASE=Carbon, Inc.
+
+OUI:4CE1731*
+ ID_OUI_FROM_DATABASE=Nexoforge Inc.
+
+OUI:144FD70*
+ ID_OUI_FROM_DATABASE=annapurnalabs
+
+OUI:144FD75*
+ ID_OUI_FROM_DATABASE=FLS FINLAND OY
+
+OUI:144FD74*
+ ID_OUI_FROM_DATABASE=Red Technology Limited
+
+OUI:98AAFCD*
+ ID_OUI_FROM_DATABASE=MCS Micronic Computer Systeme GmbH
+
+OUI:98AAFC7*
+ ID_OUI_FROM_DATABASE=Shenzhen Hubsan Technology Co.,LTD.
+
+OUI:08ED02C*
+ ID_OUI_FROM_DATABASE=Guard RFID Solutions
+
+OUI:08ED021*
+ ID_OUI_FROM_DATABASE=Imperx, Inc
+
+OUI:60D7E34*
+ ID_OUI_FROM_DATABASE=Hemisphere GNSS
+
+OUI:60D7E37*
+ ID_OUI_FROM_DATABASE=Phase One A/S
+
+OUI:60D7E33*
+ ID_OUI_FROM_DATABASE=SKS Automaatio oy
+
+OUI:60D7E3E*
+ ID_OUI_FROM_DATABASE=HuBDIC CO.,LTD
+
+OUI:04714BB*
+ ID_OUI_FROM_DATABASE=DIGIBEST TECHNOLOGY CO., LTD.
+
+OUI:04714B6*
+ ID_OUI_FROM_DATABASE=Armstrong Fluid Technology
+
+OUI:04714B4*
+ ID_OUI_FROM_DATABASE=Apparatebau Gauting GmbH
+
+OUI:04714BE*
+ ID_OUI_FROM_DATABASE=Gimso Mobile Ltd
+
+OUI:F023B90*
+ ID_OUI_FROM_DATABASE=Aquametro AG
+
+OUI:F023B99*
+ ID_OUI_FROM_DATABASE=Emu Technology
+
+OUI:F023B91*
+ ID_OUI_FROM_DATABASE=Ubiant
+
OUI:1C8776B*
ID_OUI_FROM_DATABASE=Hekatron Vertriebs GmbH
@@ -8420,6 +9257,87 @@ OUI:8CC8F45*
OUI:8CC8F43*
ID_OUI_FROM_DATABASE=TOHO DENKI IND.CO.,LTD
+OUI:40F385A*
+ ID_OUI_FROM_DATABASE=Creanord
+
+OUI:40F3857*
+ ID_OUI_FROM_DATABASE=PALAZZETTI LELIO SPA
+
+OUI:1CA0D34*
+ ID_OUI_FROM_DATABASE=NPO TELECOM JSC
+
+OUI:1CA0D30*
+ ID_OUI_FROM_DATABASE=OOO Tekhnotronika
+
+OUI:1CA0D3C*
+ ID_OUI_FROM_DATABASE=LYT inc.
+
+OUI:1CA0D39*
+ ID_OUI_FROM_DATABASE=Cirque Audio Technology Co., Ltd
+
+OUI:1CA0D31*
+ ID_OUI_FROM_DATABASE=Jabil circuit italia srl
+
+OUI:A41163B*
+ ID_OUI_FROM_DATABASE=Moog Music Inc.
+
+OUI:A41163D*
+ ID_OUI_FROM_DATABASE=SHENZHEN ZHISHI TECHNOLOGY CO., LTD.
+
+OUI:A411632*
+ ID_OUI_FROM_DATABASE=Allgo Tech. (Beijing) Co.,Ltd
+
+OUI:144FD7C*
+ ID_OUI_FROM_DATABASE=D&S Cable Industries (HK) Limited
+
+OUI:144FD7B*
+ ID_OUI_FROM_DATABASE=Arkus-ST Ltd
+
+OUI:98AAFCA*
+ ID_OUI_FROM_DATABASE=SENKO Co.,Ltd.
+
+OUI:98AAFC6*
+ ID_OUI_FROM_DATABASE=Mekotronics Co., Ltd
+
+OUI:08ED029*
+ ID_OUI_FROM_DATABASE=Savox Communications
+
+OUI:08ED02B*
+ ID_OUI_FROM_DATABASE=Szok Energy and Communication Co., Ltd.
+
+OUI:60D7E39*
+ ID_OUI_FROM_DATABASE=LongSung Technology (Shanghai) Co.,Ltd.
+
+OUI:04714BC*
+ ID_OUI_FROM_DATABASE=KittyHawk Corporation
+
+OUI:04714B7*
+ ID_OUI_FROM_DATABASE=Omylis Pte Ltd
+
+OUI:04714B5*
+ ID_OUI_FROM_DATABASE=Bureau Electronique Appliquee
+
+OUI:04714B0*
+ ID_OUI_FROM_DATABASE=Neurio Technology Inc.
+
+OUI:F023B9B*
+ ID_OUI_FROM_DATABASE=Q Core Medical Ltd
+
+OUI:F023B9D*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:F023B96*
+ ID_OUI_FROM_DATABASE=Xiamen Jinhaode Electronic Co.,Ltd
+
+OUI:F023B9C*
+ ID_OUI_FROM_DATABASE=Shenzhen Lachesis Mhealth Co., Ltd.
+
+OUI:8C147DA*
+ ID_OUI_FROM_DATABASE=Bluemega Document & Print Services
+
+OUI:8C147D1*
+ ID_OUI_FROM_DATABASE=Private
+
OUI:1C87740*
ID_OUI_FROM_DATABASE=Philips Personal Health Solutions
@@ -8861,9 +9779,6 @@ OUI:38FDFEB*
OUI:38FDFE4*
ID_OUI_FROM_DATABASE=New Telecom Solutions LLC
-OUI:38FDFE9*
- ID_OUI_FROM_DATABASE=OOO Group of Industrial Technologies
-
OUI:5CF2860*
ID_OUI_FROM_DATABASE=Hangzhou Signwei Electronics Technology Co., Ltd
@@ -9122,6 +10037,108 @@ OUI:8CC8F44*
OUI:40F3852*
ID_OUI_FROM_DATABASE=Beijing Zongheng Electro-Mechanical Technology Development Co.
+OUI:40F3853*
+ ID_OUI_FROM_DATABASE=IntelliDesign Pty Ltd
+
+OUI:40F3851*
+ ID_OUI_FROM_DATABASE=Johnson Matthey
+
+OUI:40F385C*
+ ID_OUI_FROM_DATABASE=Clixxo Broadband Private Limited
+
+OUI:40F385E*
+ ID_OUI_FROM_DATABASE=BBB Inc.
+
+OUI:1CA0D36*
+ ID_OUI_FROM_DATABASE=Intertecno SRL NISUTA
+
+OUI:A411636*
+ ID_OUI_FROM_DATABASE=Beijing XiaoRui Technology Co., Ltd
+
+OUI:A411633*
+ ID_OUI_FROM_DATABASE=Pax
+
+OUI:A41163C*
+ ID_OUI_FROM_DATABASE=Viloc
+
+OUI:A41163E*
+ ID_OUI_FROM_DATABASE=tinylogics
+
+OUI:144FD78*
+ ID_OUI_FROM_DATABASE=NPort Networks Inc.,
+
+OUI:144FD76*
+ ID_OUI_FROM_DATABASE=i-SENS, Inc.
+
+OUI:144FD71*
+ ID_OUI_FROM_DATABASE=Zehnder Group AG
+
+OUI:144FD7E*
+ ID_OUI_FROM_DATABASE=Edan Instruments, Inc.
+
+OUI:98AAFC5*
+ ID_OUI_FROM_DATABASE=SPM Instrument AB
+
+OUI:98AAFC2*
+ ID_OUI_FROM_DATABASE=Shenzhen UniStrong Science & Technology Co., Ltd
+
+OUI:38FDFE9*
+ ID_OUI_FROM_DATABASE=OOO Group of Industrial Technologies
+
+OUI:98AAFC4*
+ ID_OUI_FROM_DATABASE=RPE RADICO
+
+OUI:98AAFC3*
+ ID_OUI_FROM_DATABASE=Nexus Electrical(Jiaxing) Limited
+
+OUI:98AAFCB*
+ ID_OUI_FROM_DATABASE=Resonant Systems Inc.
+
+OUI:08ED025*
+ ID_OUI_FROM_DATABASE=Vigitron Inc.
+
+OUI:08ED02D*
+ ID_OUI_FROM_DATABASE=Origami Energy Ltd
+
+OUI:08ED020*
+ ID_OUI_FROM_DATABASE=D2SLink Systems
+
+OUI:08ED02A*
+ ID_OUI_FROM_DATABASE=Victiana SRL
+
+OUI:60D7E35*
+ ID_OUI_FROM_DATABASE=Revol Technologies inc
+
+OUI:60D7E32*
+ ID_OUI_FROM_DATABASE=Novo innovations Ltd
+
+OUI:04714B3*
+ ID_OUI_FROM_DATABASE=Griesser Electronic AG
+
+OUI:04714B9*
+ ID_OUI_FROM_DATABASE=Lighthouse AI, Inc
+
+OUI:04714BD*
+ ID_OUI_FROM_DATABASE=Shenzhen BoClouds Technology Co.,Ltd.
+
+OUI:04714BA*
+ ID_OUI_FROM_DATABASE=Observables, Inc.
+
+OUI:F023B97*
+ ID_OUI_FROM_DATABASE=Transcend Building Automation control network corporation
+
+OUI:F023B93*
+ ID_OUI_FROM_DATABASE=BSP RUS Ltd.
+
+OUI:8C147DD*
+ ID_OUI_FROM_DATABASE=Shenzhen Lanxus technology Co. Ltd.
+
+OUI:8C147D3*
+ ID_OUI_FROM_DATABASE=Remotec Technology Limited
+
+OUI:8C147D4*
+ ID_OUI_FROM_DATABASE=Nanjing bilian information Technology Co.,Ltd.
+
OUI:E043DB*
ID_OUI_FROM_DATABASE=Shenzhen ViewAt Technology Co.,Ltd.
@@ -9371,12 +10388,6 @@ OUI:BC7670*
OUI:24DBAC*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:BC3AEA*
- ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-
-OUI:E8BBA8*
- ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-
OUI:0021E8*
ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
@@ -9629,30 +10640,6 @@ OUI:781DBA*
OUI:001E10*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:B0ADAA*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:10CDAE*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:50CD22*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:FCA841*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:3CB15B*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:C8F406*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:2CF4C5*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:7038EE*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
OUI:88F031*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -10577,9 +11564,6 @@ OUI:3C46D8*
OUI:6C0273*
ID_OUI_FROM_DATABASE=Shenzhen Jin Yun Video Equipment Co., Ltd.
-OUI:2CFAA2*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
-
OUI:F0761C*
ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD.
@@ -11369,9 +12353,6 @@ OUI:48F230*
OUI:B0C95B*
ID_OUI_FROM_DATABASE=Beijing Symtech CO.,LTD
-OUI:881544*
- ID_OUI_FROM_DATABASE=Meraki, Inc.
-
OUI:DCA989*
ID_OUI_FROM_DATABASE=MACANDC
@@ -17159,9 +18140,6 @@ OUI:00089D*
OUI:000890*
ID_OUI_FROM_DATABASE=AVILINKS SA
-OUI:000889*
- ID_OUI_FROM_DATABASE=Echostar Technologies Corp
-
OUI:000884*
ID_OUI_FROM_DATABASE=Index Braille AB
@@ -18509,9 +19487,6 @@ OUI:00D00E*
OUI:00D055*
ID_OUI_FROM_DATABASE=KATHREIN-WERKE KG
-OUI:00D095*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent, Enterprise Business Group
-
OUI:00D000*
ID_OUI_FROM_DATABASE=FERRAN SCIENTIFIC, INC.
@@ -20363,9 +21338,6 @@ OUI:000FB0*
OUI:1C7508*
ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD.
-OUI:8C0EE3*
- ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-
OUI:3829DD*
ID_OUI_FROM_DATABASE=ONvocal Inc
@@ -20630,9 +21602,6 @@ OUI:6487D7*
OUI:00E098*
ID_OUI_FROM_DATABASE=AboCom
-OUI:F0A225*
- ID_OUI_FROM_DATABASE=Private
-
OUI:0000B1*
ID_OUI_FROM_DATABASE=Alpha Micro
@@ -20804,18 +21773,6 @@ OUI:E0CBEE*
OUI:64B853*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:988389*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
-OUI:244B03*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
-OUI:FC8F90*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
-OUI:1816C9*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:F4428F*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
@@ -20864,9 +21821,6 @@ OUI:D059E4*
OUI:64B310*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:78ABBB*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:000B3B*
ID_OUI_FROM_DATABASE=devolo AG
@@ -20990,9 +21944,6 @@ OUI:246968*
OUI:8CA2FD*
ID_OUI_FROM_DATABASE=Starry, Inc.
-OUI:14BB6E*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:AC61EA*
ID_OUI_FROM_DATABASE=Apple, Inc.
@@ -21065,9 +22016,6 @@ OUI:D8803C*
OUI:703C03*
ID_OUI_FROM_DATABASE=RadiAnt Co.,Ltd
-OUI:F0D2F1*
- ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
-
OUI:583277*
ID_OUI_FROM_DATABASE=Reliance Communications LLC
@@ -21137,9 +22085,6 @@ OUI:001706*
OUI:30F6B9*
ID_OUI_FROM_DATABASE=Ecocentric Energy
-OUI:1C3ADE*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:004268*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -21713,9 +22658,6 @@ OUI:00B0B3*
OUI:14825B*
ID_OUI_FROM_DATABASE=Hefei Radio Communication Technology Co., Ltd
-OUI:00549F*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
OUI:00562B*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -21839,156 +22781,9 @@ OUI:24E43F*
OUI:A00460*
ID_OUI_FROM_DATABASE=NETGEAR
-OUI:946269*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:D40598*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:78719C*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:E0B70A*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:C83FB4*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:207355*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:900DCB*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:14CFE2*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0015D0*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:E86D52*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:3C438E*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:90B134*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:20E564*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:40B7F3*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:94CCB9*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:00ACE0*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:3C36E4*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0000C5*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:D039B3*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:8C7F3B*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:903EAB*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:CCA462*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001DCD*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001DD4*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001DCE*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0050E3*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:00080E*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:00159A*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:00192C*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:D40AA9*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:384C90*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:44AAF5*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:7085C6*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:D0E54D*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:B4F2E8*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:FC8E7E*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:005094*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:002143*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0023EE*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:64ED57*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0023A3*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:F87B7A*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0025F1*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001A66*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0018C0*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001E46*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001ADE*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0023AF*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:240AC4*
ID_OUI_FROM_DATABASE=Espressif Inc.
-OUI:5856E8*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:E4C1F1*
ID_OUI_FROM_DATABASE=SHENZHEN SPOTMAU INFORMATION TECHNOLIGY CO., Ltd
@@ -22382,9 +23177,6 @@ OUI:A4D9A4*
OUI:484D7E*
ID_OUI_FROM_DATABASE=Dell Inc.
-OUI:8871E5*
- ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
-
OUI:F4B549*
ID_OUI_FROM_DATABASE=Xiamen Yeastar Information Technology Co., Ltd.
@@ -22427,9 +23219,6 @@ OUI:C413E2*
OUI:F09CE9*
ID_OUI_FROM_DATABASE=Aerohive Networks Inc.
-OUI:48D343*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:CCC5EF*
ID_OUI_FROM_DATABASE=Co-Comm Servicios Telecomunicaciones S.L.
@@ -22493,12 +23282,6 @@ OUI:1CEEC9*
OUI:4CB81C*
ID_OUI_FROM_DATABASE=SAM Electronics GmbH
-OUI:F83F51*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
-OUI:6C5C14*
- ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-
OUI:2CDCAD*
ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
@@ -22568,9 +23351,6 @@ OUI:F015B9*
OUI:70700D*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:E02202*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:24A7DC*
ID_OUI_FROM_DATABASE=BSkyB Ltd
@@ -22634,9 +23414,6 @@ OUI:089E08*
OUI:00014F*
ID_OUI_FROM_DATABASE=Adtran Inc
-OUI:D8E0E1*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:045D4B*
ID_OUI_FROM_DATABASE=Sony Corporation
@@ -22685,9 +23462,6 @@ OUI:A49B13*
OUI:542F8A*
ID_OUI_FROM_DATABASE=TELLESCOM INDUSTRIA E COMERCIO EM TELECOMUNICACAO
-OUI:6049C1*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
OUI:DCC64B*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
@@ -22703,6 +23477,540 @@ OUI:6854C1*
OUI:887873*
ID_OUI_FROM_DATABASE=Intel Corporate
+OUI:6C750D*
+ ID_OUI_FROM_DATABASE=WiFiSONG
+
+OUI:E45D51*
+ ID_OUI_FROM_DATABASE=SFR
+
+OUI:346E9D*
+ ID_OUI_FROM_DATABASE=Ericsson AB
+
+OUI:B816DB*
+ ID_OUI_FROM_DATABASE=CHANT SINCERE CO.,LTD
+
+OUI:D461FE*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:54E1AD*
+ ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology co., ltd
+
+OUI:94F551*
+ ID_OUI_FROM_DATABASE=Cadi Scientific Pte Ltd
+
+OUI:BC452E*
+ ID_OUI_FROM_DATABASE=Knowledge Development for POF S.L.
+
+OUI:E8D11B*
+ ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP
+
+OUI:44032C*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:14987D*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:D4CF37*
+ ID_OUI_FROM_DATABASE=Symbolic IO
+
+OUI:283F69*
+ ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
+
+OUI:F0D2F1*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:8871E5*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:7C5049*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:F0A225*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:E048AF*
+ ID_OUI_FROM_DATABASE=Premietech Limited
+
+OUI:2C3311*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:503A7D*
+ ID_OUI_FROM_DATABASE=AlphaTech PLC Int’l Co., Ltd.
+
+OUI:BC024A*
+ ID_OUI_FROM_DATABASE=HMD Global Oy
+
+OUI:9CFCD1*
+ ID_OUI_FROM_DATABASE=Aetheris Technology (Shanghai) Co., Ltd.
+
+OUI:949901*
+ ID_OUI_FROM_DATABASE=Shenzhen YITOA Digital Appliance CO.,LTD
+
+OUI:E89E0C*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:D8A105*
+ ID_OUI_FROM_DATABASE=Syslane, Co., Ltd.
+
+OUI:C4B9CD*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:10954B*
+ ID_OUI_FROM_DATABASE=Megabyte Ltd.
+
+OUI:900628*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:C4700B*
+ ID_OUI_FROM_DATABASE=GUANGZHOU CHIP TECHNOLOGIES CO.,LTD
+
+OUI:D4AE05*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:3C0518*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:04946B*
+ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED
+
+OUI:A04C5B*
+ ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp.
+
+OUI:98DDEA*
+ ID_OUI_FROM_DATABASE=Infinix mobility limited
+
+OUI:D4619D*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:B0481A*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:989E63*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:DCA904*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:48A195*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:6CAB31*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:503237*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:000889*
+ ID_OUI_FROM_DATABASE=Echostar Technologies Corp
+
+OUI:2C029F*
+ ID_OUI_FROM_DATABASE=3ALogics
+
+OUI:58D9D5*
+ ID_OUI_FROM_DATABASE=Tenda Technology Co.,Ltd.Dongguan branch
+
+OUI:60E78A*
+ ID_OUI_FROM_DATABASE=UNISEM
+
+OUI:6C5976*
+ ID_OUI_FROM_DATABASE=Shanghai Tricheer Technology Co.,Ltd.
+
+OUI:F4A739*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:2CFAA2*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Enterprise
+
+OUI:00D095*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Enterprise
+
+OUI:4095BD*
+ ID_OUI_FROM_DATABASE=NTmore.Co.,Ltd
+
+OUI:2CABEB*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:BC66DE*
+ ID_OUI_FROM_DATABASE=Shadow Creator Information Technology Co.,Ltd.
+
+OUI:A0086F*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:C4FF1F*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:7C7B8B*
+ ID_OUI_FROM_DATABASE=Control Concepts, Inc.
+
+OUI:C40BCB*
+ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+
+OUI:D8C06A*
+ ID_OUI_FROM_DATABASE=Hunantv.com Interactive Entertainment Media Co.,Ltd.
+
+OUI:9C32A9*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD
+
+OUI:601466*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:30D386*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:900E83*
+ ID_OUI_FROM_DATABASE=Monico Monitoring, Inc.
+
+OUI:E8BBA8*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:BC3AEA*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:8C0EE3*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:6C5C14*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:F894C2*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:7CB960*
+ ID_OUI_FROM_DATABASE=Shanghai X-Cheng telecom LTD
+
+OUI:A8D579*
+ ID_OUI_FROM_DATABASE=Beijing Chushang Science and Technology Co.,Ltd
+
+OUI:28C63F*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:600837*
+ ID_OUI_FROM_DATABASE=ivvi Scientific(Nanchang)Co.Ltd
+
+OUI:D860B3*
+ ID_OUI_FROM_DATABASE=Guangdong Global Electronic Technology CO.,LTD
+
+OUI:3C9509*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
+OUI:44B412*
+ ID_OUI_FROM_DATABASE=SIUS AG
+
+OUI:3CA308*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:00F82C*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:00C1B1*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:D0F88C*
+ ID_OUI_FROM_DATABASE=Motorola (Wuhan) Mobility Technologies Communication Co., Ltd.
+
+OUI:2CB115*
+ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd.
+
+OUI:78ABBB*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:1816C9*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:FC8F90*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:244B03*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:988389*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:14BB6E*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:1C3ADE*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:F83F51*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:D8E0E1*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:50FF20*
+ ID_OUI_FROM_DATABASE=Keenetic Limited
+
+OUI:ECF342*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:D4C1C8*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:EC237B*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:881544*
+ ID_OUI_FROM_DATABASE=Cisco Meraki
+
+OUI:F44156*
+ ID_OUI_FROM_DATABASE=Arrikto Inc.
+
+OUI:D4258B*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:B4F2E8*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:D0E54D*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:7085C6*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:44AAF5*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:005094*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:FC8E7E*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:00E18C*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:903EAB*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:14CFE2*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:900DCB*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:207355*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:C83FB4*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:E0B70A*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:78719C*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:D40598*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:946269*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:8C7F3B*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:40B7F3*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:20E564*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:90B134*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:3C438E*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:E86D52*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0015D0*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001DCE*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001DD4*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001DCD*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:CCA462*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:D039B3*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0000C5*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:3C36E4*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:00ACE0*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:384C90*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:D40AA9*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:48D343*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:E02202*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:2C1DB8*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:E45740*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0023A3*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:64ED57*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0023EE*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:002143*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0023AF*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001ADE*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:00159A*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:00080E*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0050E3*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:94CCB9*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001E46*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0018C0*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001A66*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:00192C*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0025F1*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:F87B7A*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:5856E8*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:145E45*
+ ID_OUI_FROM_DATABASE=Kaleao Limited
+
+OUI:88D7F6*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:1C1FD4*
+ ID_OUI_FROM_DATABASE=LifeBEAM Technologies LTD
+
+OUI:88BD78*
+ ID_OUI_FROM_DATABASE=Flaircomm Microelectronics,Inc.
+
+OUI:5092B9*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:B4BFF6*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:C8D7B0*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:60720B*
+ ID_OUI_FROM_DATABASE=BLU Products Inc
+
+OUI:F4A997*
+ ID_OUI_FROM_DATABASE=CANON INC.
+
+OUI:3C4CD0*
+ ID_OUI_FROM_DATABASE=CERAGON NETWORKS
+
+OUI:B04E26*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:FC06ED*
+ ID_OUI_FROM_DATABASE=M2Motive Technology Inc.
+
+OUI:54C9DF*
+ ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED
+
+OUI:30C3D9*
+ ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD.
+
+OUI:FC4D8C*
+ ID_OUI_FROM_DATABASE=SHENZHEN PANTE ELECTRONICS TECHNOLOGY CO., LTD
+
+OUI:B01F29*
+ ID_OUI_FROM_DATABASE=Helvetia INC.
+
+OUI:CC0677*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:28070D*
+ ID_OUI_FROM_DATABASE=GUANGZHOU WINSOUND INFORMATION TECHNOLOGY CO.,LTD.
+
+OUI:7038EE*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:2CF4C5*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:C8F406*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:3CB15B*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:FCA841*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:50CD22*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:10CDAE*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:B0ADAA*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:00549F*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:6049C1*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:E0D848*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:145BE1*
+ ID_OUI_FROM_DATABASE=nyantec UG (haftungsbeschränkt)
+
OUI:0C6F9C*
ID_OUI_FROM_DATABASE=Shaw Communications Inc.
@@ -22964,21 +24272,6 @@ OUI:0019C6*
OUI:0015EB*
ID_OUI_FROM_DATABASE=zte corporation
-OUI:A051C6*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:24D921*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:848371*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:7052C5*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:001B4F*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
OUI:F0EBD0*
ID_OUI_FROM_DATABASE=Shanghai Feixun Communication Co.,Ltd.
@@ -23021,12 +24314,6 @@ OUI:80717A*
OUI:F49FF3*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:2C5BB8*
- ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-
-OUI:B0AA36*
- ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-
OUI:784B87*
ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
@@ -23120,15 +24407,6 @@ OUI:00259E*
OUI:001882*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:D4EA0E*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:B4475E*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:90FB5B*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
OUI:00906F*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -23582,9 +24860,6 @@ OUI:84100D*
OUI:D88B4C*
ID_OUI_FROM_DATABASE=KingTing Tech.
-OUI:E81363*
- ID_OUI_FROM_DATABASE=Comstock RD, Inc.
-
OUI:6C9354*
ID_OUI_FROM_DATABASE=Yaojin Technology (Shenzhen) Co., LTD.
@@ -23852,9 +25127,6 @@ OUI:E03560*
OUI:0CB5DE*
ID_OUI_FROM_DATABASE=Alcatel Lucent
-OUI:04C9D9*
- ID_OUI_FROM_DATABASE=EchoStar Technologies Corp
-
OUI:E4CE70*
ID_OUI_FROM_DATABASE=Health & Life co., Ltd.
@@ -24086,9 +25358,6 @@ OUI:68F06D*
OUI:54F876*
ID_OUI_FROM_DATABASE=ABB AG
-OUI:4857DD*
- ID_OUI_FROM_DATABASE=Facebook
-
OUI:84930C*
ID_OUI_FROM_DATABASE=InCoax Networks Europe AB
@@ -24215,9 +25484,6 @@ OUI:18D5B6*
OUI:C8FF77*
ID_OUI_FROM_DATABASE=Dyson Limited
-OUI:C03D46*
- ID_OUI_FROM_DATABASE=Shanghai Mochui Network Technology Co., Ltd
-
OUI:DCF110*
ID_OUI_FROM_DATABASE=Nokia Corporation
@@ -24521,9 +25787,6 @@ OUI:284430*
OUI:9843DA*
ID_OUI_FROM_DATABASE=INTERTECH
-OUI:285767*
- ID_OUI_FROM_DATABASE=Echostar Technologies Corp
-
OUI:B07908*
ID_OUI_FROM_DATABASE=Cummings Engineering
@@ -24803,9 +26066,6 @@ OUI:148692*
OUI:1832A2*
ID_OUI_FROM_DATABASE=LAON TECHNOLOGY CO., LTD.
-OUI:6854ED*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent - Nuage
-
OUI:985C93*
ID_OUI_FROM_DATABASE=SBG Systems SAS
@@ -25358,9 +26618,6 @@ OUI:BC811F*
OUI:34E0CF*
ID_OUI_FROM_DATABASE=zte corporation
-OUI:801DAA*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
OUI:6C40C6*
ID_OUI_FROM_DATABASE=Nimbus Data Systems, Inc.
@@ -26342,9 +27599,6 @@ OUI:948D50*
OUI:94E226*
ID_OUI_FROM_DATABASE=D. ORtiz Consulting, LLC
-OUI:E8E732*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
-
OUI:386E21*
ID_OUI_FROM_DATABASE=Wasion Group Ltd.
@@ -27323,9 +28577,6 @@ OUI:0023D2*
OUI:0024B4*
ID_OUI_FROM_DATABASE=ESCATRONIC GmbH
-OUI:0024AF*
- ID_OUI_FROM_DATABASE=EchoStar Technologies
-
OUI:0024AD*
ID_OUI_FROM_DATABASE=Adolf Thies Gmbh & Co. KG
@@ -29618,9 +30869,6 @@ OUI:00118C*
OUI:001191*
ID_OUI_FROM_DATABASE=CTS-Clima Temperatur Systeme GmbH
-OUI:00118B*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent, Enterprise Business Group
-
OUI:001196*
ID_OUI_FROM_DATABASE=Actuality Systems, Inc.
@@ -31667,9 +32915,6 @@ OUI:00049B*
OUI:00049C*
ID_OUI_FROM_DATABASE=Surgient Networks, Inc.
-OUI:000496*
- ID_OUI_FROM_DATABASE=Extreme Networks
-
OUI:00048F*
ID_OUI_FROM_DATABASE=TD Systems Corporation
@@ -32741,9 +33986,6 @@ OUI:00E0AD*
OUI:00E025*
ID_OUI_FROM_DATABASE=dit Co., Ltd.
-OUI:00E0B1*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent, Enterprise Business Group
-
OUI:00E0E4*
ID_OUI_FROM_DATABASE=FANUC ROBOTICS NORTH AMERICA, Inc.
@@ -32897,9 +34139,6 @@ OUI:00A05B*
OUI:00A08D*
ID_OUI_FROM_DATABASE=JACOMO CORPORATION
-OUI:00A06F*
- ID_OUI_FROM_DATABASE=THE APPCON GROUP, INC.
-
OUI:00A08E*
ID_OUI_FROM_DATABASE=Check Point Software Technologies
@@ -33488,9 +34727,6 @@ OUI:004020*
OUI:00406E*
ID_OUI_FROM_DATABASE=COROLLARY, INC.
-OUI:004066*
- ID_OUI_FROM_DATABASE=Hitachi Metals, Ltd.
-
OUI:004016*
ID_OUI_FROM_DATABASE=ADC - Global Connectivity Solutions Division
@@ -33578,9 +34814,6 @@ OUI:008002*
OUI:00805C*
ID_OUI_FROM_DATABASE=AGILIS CORPORATION
-OUI:0080E7*
- ID_OUI_FROM_DATABASE=LYNWOOD SCIENTIFIC DEV. LTD.
-
OUI:008070*
ID_OUI_FROM_DATABASE=COMPUTADORAS MICRON
@@ -34223,12 +35456,6 @@ OUI:001802*
OUI:ECCD6D*
ID_OUI_FROM_DATABASE=Allied Telesis, Inc.
-OUI:74C246*
- ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
-
-OUI:F0272D*
- ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
-
OUI:00225F*
ID_OUI_FROM_DATABASE=Liteon Technology Corporation
@@ -34388,9 +35615,6 @@ OUI:B0EC71*
OUI:3CBBFD*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:24F5AA*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:2CAE2B*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
@@ -34421,9 +35645,6 @@ OUI:680571*
OUI:6C2F2C*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:5056BF*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:000136*
ID_OUI_FROM_DATABASE=CyberTAN Technology Inc.
@@ -34634,9 +35855,6 @@ OUI:0090F9*
OUI:04C103*
ID_OUI_FROM_DATABASE=Clover Network, Inc.
-OUI:F877B8*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:1C553A*
ID_OUI_FROM_DATABASE=QianGua Corp.
@@ -35000,9 +36218,6 @@ OUI:B824F0*
OUI:B456B9*
ID_OUI_FROM_DATABASE=Teraspek Technologies Co.,Ltd
-OUI:A009ED*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
OUI:68B35E*
ID_OUI_FROM_DATABASE=Shenzhen Neostra Technology Co.Ltd
@@ -35258,162 +36473,6 @@ OUI:84C7EA*
OUI:8C6102*
ID_OUI_FROM_DATABASE=Beijing Baofengmojing Technologies Co., Ltd
-OUI:1005B1*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:10868C*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:1C1B68*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:44E137*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:E83381*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:8461A0*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0CF893*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:14ABF0*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:ACB313*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0026D9*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:28C87A*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:54E2E0*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:A055DE*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:A0C562*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:FC6FB7*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001A1B*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:00149A*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001371*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001DBE*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001E5A*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001D6B*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001CC1*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001C11*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001F7E*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:002495*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:2C9E5F*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:C8AA21*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:341FE4*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:400D10*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001596*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0015A2*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001311*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0015CE*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:002040*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0011AE*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:000F9F*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:306023*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001DD6*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001DD1*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:601971*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0000CA*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001ADB*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:002375*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0024A1*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:A4ED4E*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:002642*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:000B06*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:00152F*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:00111A*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001626*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0018A4*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:00D037*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:FC9114*
ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
@@ -35570,9 +36629,6 @@ OUI:9CFBD5*
OUI:583112*
ID_OUI_FROM_DATABASE=DRUST
-OUI:7C2634*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:58696C*
ID_OUI_FROM_DATABASE=Ruijie Networks Co.,LTD
@@ -36143,9 +37199,6 @@ OUI:00234A*
OUI:88C626*
ID_OUI_FROM_DATABASE=Logitech, Inc
-OUI:B85001*
- ID_OUI_FROM_DATABASE=Zebra Technologies Inc.
-
OUI:28E31F*
ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
@@ -36209,9 +37262,6 @@ OUI:78FC14*
OUI:1062EB*
ID_OUI_FROM_DATABASE=D-Link International
-OUI:1C48CE*
- ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-
OUI:E0A700*
ID_OUI_FROM_DATABASE=Verkada Inc
@@ -36269,9 +37319,6 @@ OUI:0C3CCD*
OUI:B04089*
ID_OUI_FROM_DATABASE=Senient Systems LTD
-OUI:682737*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:002445*
ID_OUI_FROM_DATABASE=Adtran Inc
@@ -36350,6 +37397,480 @@ OUI:143004*
OUI:D481D7*
ID_OUI_FROM_DATABASE=Dell Inc.
+OUI:7C4685*
+ ID_OUI_FROM_DATABASE=Motorola (Wuhan) Mobility Technologies Communication Co., Ltd.
+
+OUI:E05163*
+ ID_OUI_FROM_DATABASE=Arcadyan Corporation
+
+OUI:00A06F*
+ ID_OUI_FROM_DATABASE=Color Sentinel Systems, LLC
+
+OUI:0C5F35*
+ ID_OUI_FROM_DATABASE=Niagara Video Corporation
+
+OUI:7C3866*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:50F14A*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:9C1D58*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:B85001*
+ ID_OUI_FROM_DATABASE=Extreme Networks
+
+OUI:000496*
+ ID_OUI_FROM_DATABASE=Extreme Networks
+
+OUI:500FF5*
+ ID_OUI_FROM_DATABASE=Tenda Technology Co.,Ltd.Dongguan branch
+
+OUI:1C1EE3*
+ ID_OUI_FROM_DATABASE=Hui Zhou Gaoshengda Technology Co.,LTD
+
+OUI:F0272D*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:74C246*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:08B258*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:F4C4D6*
+ ID_OUI_FROM_DATABASE=Shenzhen Xinfa Electronic Co.,ltd
+
+OUI:C03D46*
+ ID_OUI_FROM_DATABASE=Shanghai Sango Network Technology Co.,Ltd
+
+OUI:E89FEC*
+ ID_OUI_FROM_DATABASE=CHENGDU KT ELECTRONIC HI-TECH CO.,LTD
+
+OUI:D47DFC*
+ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED
+
+OUI:BCA042*
+ ID_OUI_FROM_DATABASE=SHANGHAI FLYCO ELECTRICAL APPLIANCE CO.,LTD
+
+OUI:14568E*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:6837E9*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:8058F8*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company
+
+OUI:443708*
+ ID_OUI_FROM_DATABASE=MRV Comunications
+
+OUI:F0D7AA*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company
+
+OUI:28FF3E*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:70F087*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:886B6E*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:4C74BF*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:285767*
+ ID_OUI_FROM_DATABASE=Echostar Technologies Corp
+
+OUI:0024AF*
+ ID_OUI_FROM_DATABASE=Echostar Technologies Corp
+
+OUI:04C9D9*
+ ID_OUI_FROM_DATABASE=Echostar Technologies Corp
+
+OUI:C49DED*
+ ID_OUI_FROM_DATABASE=Microsoft Corporation
+
+OUI:98A40E*
+ ID_OUI_FROM_DATABASE=Snap, Inc.
+
+OUI:D0498B*
+ ID_OUI_FROM_DATABASE=ZOOM SERVER
+
+OUI:AC7409*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:2C5A0F*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:4C8120*
+ ID_OUI_FROM_DATABASE=Taicang T&W Electronics
+
+OUI:E8E732*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Enterprise
+
+OUI:00118B*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Enterprise
+
+OUI:00E0B1*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Enterprise
+
+OUI:E037BF*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
+
+OUI:6854ED*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
+
+OUI:E8DE8E*
+ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd.
+
+OUI:B42A0E*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:40C8CB*
+ ID_OUI_FROM_DATABASE=AM Telecom co., Ltd.
+
+OUI:14A0F8*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:28B448*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:E442A6*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:6045CB*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:74C9A3*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:84AFEC*
+ ID_OUI_FROM_DATABASE=BUFFALO.INC
+
+OUI:AC202E*
+ ID_OUI_FROM_DATABASE=Hitron Technologies. Inc
+
+OUI:3C5282*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:48A74E*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:004066*
+ ID_OUI_FROM_DATABASE=APRESIA Systems Ltd
+
+OUI:B0AA36*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:2C5BB8*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:1C48CE*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:9CAC6D*
+ ID_OUI_FROM_DATABASE=Universal Electronics, Inc.
+
+OUI:B03D96*
+ ID_OUI_FROM_DATABASE=Vision Valley FZ LLC
+
+OUI:B02628*
+ ID_OUI_FROM_DATABASE=Broadcom Limited
+
+OUI:24792A*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:0080E7*
+ ID_OUI_FROM_DATABASE=Leonardo Tactical Systems.
+
+OUI:44AA50*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:E81363*
+ ID_OUI_FROM_DATABASE=Comstock RD, Inc.
+
+OUI:688DB6*
+ ID_OUI_FROM_DATABASE=AETEK INC.
+
+OUI:481063*
+ ID_OUI_FROM_DATABASE=NTT Innovation Institute, Inc.
+
+OUI:24F5AA*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:F877B8*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:5056BF*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:682737*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:D428D5*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:405CFD*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:041B6D*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:FC6FB7*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:A0C562*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:A055DE*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:54E2E0*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:28C87A*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0026D9*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:C8AA21*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:2C9E5F*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:002495*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:002642*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:A4ED4E*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0024A1*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001D6B*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001E5A*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001DBE*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001371*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:00149A*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001A1B*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0018A4*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:002375*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001ADB*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001F7E*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001C11*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001CC1*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:400D10*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:341FE4*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:00D037*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001DD6*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:306023*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:ACB313*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:14ABF0*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0CF893*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:8461A0*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:E83381*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:44E137*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0015CE*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001311*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0015A2*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001596*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0000CA*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:601971*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001DD1*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001626*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:00111A*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:00152F*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:000B06*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:000F9F*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0011AE*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:002040*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:1C1B68*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:10868C*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:1005B1*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:7C2634*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:A0094C*
+ ID_OUI_FROM_DATABASE=CenturyLink
+
+OUI:00A38E*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:DCC8F5*
+ ID_OUI_FROM_DATABASE=Shanghai UMEinfo CO.,LTD.
+
+OUI:64DFE9*
+ ID_OUI_FROM_DATABASE=ATEME
+
+OUI:9097F3*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:58C5CB*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:ACAFB9*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:308976*
+ ID_OUI_FROM_DATABASE=DALIAN LAMBA TECHNOLOGY CO.,LTD
+
+OUI:447BBB*
+ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd
+
+OUI:A4F4C2*
+ ID_OUI_FROM_DATABASE=VNPT TECHNOLOGY
+
+OUI:C0A5DD*
+ ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.
+
+OUI:1835D1*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:4C38D8*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:DCBE7A*
+ ID_OUI_FROM_DATABASE=Zhejiang Nurotron Biotechnology Co.
+
+OUI:206BE7*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:4857DD*
+ ID_OUI_FROM_DATABASE=Facebook Inc
+
+OUI:30074D*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND)
+
+OUI:681DEF*
+ ID_OUI_FROM_DATABASE=Shenzhen CYX Technology Co., Ltd.
+
+OUI:AC203E*
+ ID_OUI_FROM_DATABASE=Wuhan Tianyu Information Industry Co., Ltd.
+
+OUI:00A3D1*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:801DAA*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:001B4F*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:7052C5*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:848371*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:24D921*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:A051C6*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:90EC50*
+ ID_OUI_FROM_DATABASE=C.O.B.O. SPA
+
+OUI:B4475E*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:D4EA0E*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:A009ED*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:90FB5B*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
OUI:5846E1*
ID_OUI_FROM_DATABASE=Baxter International Inc
@@ -36365,9 +37886,6 @@ OUI:D084B0*
OUI:00FEC8*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:0030C5*
- ID_OUI_FROM_DATABASE=CADENCE DESIGN SYSTEMS, INC.
-
OUI:EC2280*
ID_OUI_FROM_DATABASE=D-Link International
@@ -36449,9 +37967,6 @@ OUI:984BE1*
OUI:68B599*
ID_OUI_FROM_DATABASE=Hewlett Packard
-OUI:0C47C9*
- ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
-
OUI:14D64D*
ID_OUI_FROM_DATABASE=D-Link International
@@ -36659,9 +38174,6 @@ OUI:808917*
OUI:5C899A*
ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-OUI:A81B5A*
- ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-
OUI:E422A5*
ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
@@ -36680,18 +38192,6 @@ OUI:005053*
OUI:00500F*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:048A15*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:44322A*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:FC8399*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:00040D*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
OUI:D842AC*
ID_OUI_FROM_DATABASE=Shanghai Feixun Communication Co.,Ltd.
@@ -36797,24 +38297,6 @@ OUI:308730*
OUI:002568*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:D47856*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:C057BC*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:38BB3C*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:E45D52*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:A4251B*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:6CA849*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
OUI:30D17E*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
@@ -37265,9 +38747,6 @@ OUI:54A3FA*
OUI:9023EC*
ID_OUI_FROM_DATABASE=Availink, Inc.
-OUI:7467F7*
- ID_OUI_FROM_DATABASE=Zebra Technologoes
-
OUI:3891D5*
ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
@@ -37805,9 +39284,6 @@ OUI:FCD5D9*
OUI:007532*
ID_OUI_FROM_DATABASE=INID BV
-OUI:A002DC*
- ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
-
OUI:907EBA*
ID_OUI_FROM_DATABASE=UTEK TECHNOLOGY (SHENZHEN) CO.,LTD
@@ -38486,9 +39962,6 @@ OUI:BC261D*
OUI:888964*
ID_OUI_FROM_DATABASE=GSI Electronics Inc.
-OUI:4C82CF*
- ID_OUI_FROM_DATABASE=Echostar Technologies
-
OUI:9CA577*
ID_OUI_FROM_DATABASE=Osorno Enterprises Inc.
@@ -38693,9 +40166,6 @@ OUI:48B8DE*
OUI:1065CF*
ID_OUI_FROM_DATABASE=IQSIM
-OUI:B877C3*
- ID_OUI_FROM_DATABASE=Decagon Devices, Inc.
-
OUI:849DC5*
ID_OUI_FROM_DATABASE=Centera Photonics Inc.
@@ -39455,9 +40925,6 @@ OUI:FC2E2D*
OUI:E84E06*
ID_OUI_FROM_DATABASE=EDUP INTERNATIONAL (HK) CO., LTD
-OUI:B4C799*
- ID_OUI_FROM_DATABASE=Zebra Technologies Inc
-
OUI:70B921*
ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
@@ -40073,9 +41540,6 @@ OUI:58570D*
OUI:0C826A*
ID_OUI_FROM_DATABASE=Wuhan Huagong Genuine Optics Technology Co., Ltd
-OUI:5C0E8B*
- ID_OUI_FROM_DATABASE=Zebra Technologies Inc
-
OUI:38C7BA*
ID_OUI_FROM_DATABASE=CS Services Co.,Ltd.
@@ -40430,9 +41894,6 @@ OUI:00268F*
OUI:6C8CDB*
ID_OUI_FROM_DATABASE=Otus Technologies Ltd
-OUI:B4417A*
- ID_OUI_FROM_DATABASE=ShenZhen Gongjin Electronics Co.,Ltd
-
OUI:401597*
ID_OUI_FROM_DATABASE=Protect America, Inc.
@@ -44078,9 +45539,6 @@ OUI:000940*
OUI:00093F*
ID_OUI_FROM_DATABASE=Double-Win Enterpirse CO., LTD
-OUI:00093A*
- ID_OUI_FROM_DATABASE=Molex Fiber Optics
-
OUI:000933*
ID_OUI_FROM_DATABASE=Ophit Co.Ltd.
@@ -46070,9 +47528,6 @@ OUI:00E0CE*
OUI:00E05F*
ID_OUI_FROM_DATABASE=e-Net, Inc.
-OUI:00E02B*
- ID_OUI_FROM_DATABASE=EXTREME NETWORKS
-
OUI:00E0C7*
ID_OUI_FROM_DATABASE=EUROTECH SRL
@@ -47306,9 +48761,6 @@ OUI:001B38*
OUI:E46F13*
ID_OUI_FROM_DATABASE=D-Link International
-OUI:DC6DCD*
- ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-
OUI:94C150*
ID_OUI_FROM_DATABASE=2Wire Inc
@@ -47516,18 +48968,12 @@ OUI:18FE34*
OUI:54F6C5*
ID_OUI_FROM_DATABASE=FUJIAN STAR-NET COMMUNICATION CO.,LTD
-OUI:28EF01*
- ID_OUI_FROM_DATABASE=Private
-
OUI:5C338E*
ID_OUI_FROM_DATABASE=Alpha Networks Inc.
OUI:001AEB*
ID_OUI_FROM_DATABASE=Allied Telesis R&D Center K.K.
-OUI:747548*
- ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
-
OUI:A43111*
ID_OUI_FROM_DATABASE=ZIV
@@ -47714,21 +49160,6 @@ OUI:0CB319*
OUI:08EE8B*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:84A466*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
-OUI:981DFA*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
-OUI:FCF136*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
-OUI:0C8910*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
-OUI:54FA3E*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:A89FBA*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
@@ -47801,9 +49232,6 @@ OUI:A4EBD3*
OUI:28987B*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:1867B0*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:F40E22*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
@@ -48086,9 +49514,6 @@ OUI:1866DA*
OUI:981FB1*
ID_OUI_FROM_DATABASE=Shenzhen Lemon Network Technology Co.,Ltd
-OUI:CCB11A*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:40476A*
ID_OUI_FROM_DATABASE=AG Acquisition Corp. d.b.a. ASTRO Gaming
@@ -48371,12 +49796,6 @@ OUI:C09727*
OUI:2C5A8D*
ID_OUI_FROM_DATABASE=SYSTRONIK Elektronik u. Systemtechnik GmbH
-OUI:B8BBAF*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
-OUI:60C5AD*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:8C897A*
ID_OUI_FROM_DATABASE=AUGTEK
@@ -48836,9 +50255,6 @@ OUI:70FF76*
OUI:507224*
ID_OUI_FROM_DATABASE=Texas Instruments
-OUI:440444*
- ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-
OUI:506583*
ID_OUI_FROM_DATABASE=Texas Instruments
@@ -48872,138 +50288,6 @@ OUI:981E0F*
OUI:548CA0*
ID_OUI_FROM_DATABASE=Liteon Technology Corporation
-OUI:001AAD*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:00195E*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001404*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001BDD*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0023A2*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001E8D*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0003E0*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:707E43*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:1C1448*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:A47AA4*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:E83EFC*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:E8892C*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001DD3*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0015D1*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:203D66*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:6455B1*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:C005C2*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:3CDFA9*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:8C09F4*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:083E0C*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001225*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:00128A*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:D404CD*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:002493*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:E46449*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:745612*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:74EAE8*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:A811FC*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:044E5A*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:94E8C5*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:F8A097*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:00230B*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001B52*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0023ED*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:002395*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0022B4*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:002136*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0024C1*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:3C754A*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:40FC89*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:BC644B*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:347A60*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:84E058*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:003676*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:001CA8*
ID_OUI_FROM_DATABASE=AirTies Wireless Networks
@@ -49232,12 +50516,6 @@ OUI:B072BF*
OUI:600B03*
ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
-OUI:C09F05*
- ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-
-OUI:AC63BE*
- ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
-
OUI:A41437*
ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd.
@@ -49340,9 +50618,6 @@ OUI:9C8BA0*
OUI:9840BB*
ID_OUI_FROM_DATABASE=Dell Inc.
-OUI:CC2D83*
- ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-
OUI:E04FBD*
ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD
@@ -49406,9 +50681,6 @@ OUI:407183*
OUI:0059DC*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:14612F*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
OUI:ACF85C*
ID_OUI_FROM_DATABASE=Private
@@ -49430,9 +50702,6 @@ OUI:701CE7*
OUI:CC9470*
ID_OUI_FROM_DATABASE=Kinestral Technologies, Inc.
-OUI:446AB7*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:F0219D*
ID_OUI_FROM_DATABASE=Cal-Comp Electronics & Communications Company Ltd.
@@ -49451,9 +50720,6 @@ OUI:506B8D*
OUI:0038DF*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:2C9924*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:006BF1*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -49535,9 +50801,6 @@ OUI:0060BD*
OUI:AC83F3*
ID_OUI_FROM_DATABASE=AMPAK Technology, Inc.
-OUI:707C69*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
OUI:18DBF2*
ID_OUI_FROM_DATABASE=Dell Inc.
@@ -49712,9 +50975,6 @@ OUI:B0F1EC*
OUI:B0C46C*
ID_OUI_FROM_DATABASE=Senseit
-OUI:105611*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:148951*
ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology co., ltd
@@ -49733,6 +50993,507 @@ OUI:04DEF2*
OUI:00D071*
ID_OUI_FROM_DATABASE=ECHELON CORP.
+OUI:0030C5*
+ ID_OUI_FROM_DATABASE=CADENCE DESIGN SYSTEMS, INC.
+
+OUI:504061*
+ ID_OUI_FROM_DATABASE=Nokia
+
+OUI:7467F7*
+ ID_OUI_FROM_DATABASE=Extreme Networks
+
+OUI:B4C799*
+ ID_OUI_FROM_DATABASE=Extreme Networks
+
+OUI:54E3F6*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
+
+OUI:5C0E8B*
+ ID_OUI_FROM_DATABASE=Extreme Networks
+
+OUI:00E02B*
+ ID_OUI_FROM_DATABASE=Extreme Networks
+
+OUI:B0C205*
+ ID_OUI_FROM_DATABASE=BIONIME
+
+OUI:0C61CF*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:7C2664*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+
+OUI:E47DEB*
+ ID_OUI_FROM_DATABASE=Shanghai Notion Information Technology CO.,LTD.
+
+OUI:A002DC*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:0C47C9*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:28EF01*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:747548*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:AC63BE*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:DCA4CA*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:8C8FE9*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:40FA7F*
+ ID_OUI_FROM_DATABASE=Preh Car Connect GmbH
+
+OUI:F8AB05*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+
+OUI:C0028D*
+ ID_OUI_FROM_DATABASE=WINSTAR Display CO.,Ltd
+
+OUI:D83214*
+ ID_OUI_FROM_DATABASE=Tenda Technology Co.,Ltd.Dongguan branch
+
+OUI:7C787E*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:C0D3C0*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:F097E5*
+ ID_OUI_FROM_DATABASE=TAMIO, INC
+
+OUI:F4E4AD*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:F85971*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:9810E8*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:B49CDF*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:4C82CF*
+ ID_OUI_FROM_DATABASE=Echostar Technologies Corp
+
+OUI:F49634*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:F470AB*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:341A35*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:6C4B90*
+ ID_OUI_FROM_DATABASE=LiteON
+
+OUI:08028E*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:F8FF0B*
+ ID_OUI_FROM_DATABASE=Electronic Technology Inc.
+
+OUI:38F135*
+ ID_OUI_FROM_DATABASE=SensorTec-Canada
+
+OUI:90F305*
+ ID_OUI_FROM_DATABASE=HUMAX Co., Ltd.
+
+OUI:00093A*
+ ID_OUI_FROM_DATABASE=Molex
+
+OUI:B8D50B*
+ ID_OUI_FROM_DATABASE=Sunitec Enterprise Co.,Ltd
+
+OUI:28A6DB*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:C8F86D*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
+
+OUI:D45F25*
+ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd
+
+OUI:9CE951*
+ ID_OUI_FROM_DATABASE=Shenzhen Sang Fei Consumer Communications Ltd., Co.
+
+OUI:DC0856*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Enterprise
+
+OUI:E8FDE8*
+ ID_OUI_FROM_DATABASE=CeLa Link Corporation
+
+OUI:181212*
+ ID_OUI_FROM_DATABASE=Cepton Technologies
+
+OUI:B4417A*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
+OUI:F4DE0C*
+ ID_OUI_FROM_DATABASE=ESPOD Ltd.
+
+OUI:BC8AE8*
+ ID_OUI_FROM_DATABASE=QING DAO HAIER TELECOM CO.,LTD.
+
+OUI:440444*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:C09F05*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:CC2D83*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:38295A*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:4C1A3D*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:A81B5A*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:DC6DCD*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:70D379*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:7C4F7D*
+ ID_OUI_FROM_DATABASE=Sawwave
+
+OUI:185207*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD
+
+OUI:9874DA*
+ ID_OUI_FROM_DATABASE=Infinix mobility limited
+
+OUI:143F27*
+ ID_OUI_FROM_DATABASE=Noccela Oy
+
+OUI:64351C*
+ ID_OUI_FROM_DATABASE=e-CON SYSTEMS INDIA PVT LTD
+
+OUI:5C6A80*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
+OUI:A8B86E*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:0CB912*
+ ID_OUI_FROM_DATABASE=JM-DATA GmbH
+
+OUI:1893D7*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:EC363F*
+ ID_OUI_FROM_DATABASE=Markov Corporation
+
+OUI:54FA3E*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:0C8910*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:FCF136*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:981DFA*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:84A466*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:1867B0*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:CCB11A*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:B8BBAF*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:60C5AD*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:28395E*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:C4AE12*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:10D07A*
+ ID_OUI_FROM_DATABASE=AMPAK Technology, Inc.
+
+OUI:80B234*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:B877C3*
+ ID_OUI_FROM_DATABASE=METER Group
+
+OUI:003676*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:84E058*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:F07485*
+ ID_OUI_FROM_DATABASE=NGD Systems, Inc.
+
+OUI:347A60*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:BC644B*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:F8A097*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:94E8C5*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:044E5A*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:74EAE8*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:A811FC*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:745612*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:E46449*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:C005C2*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:6455B1*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:203D66*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:D404CD*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:446AB7*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:2C9924*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001BDD*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001404*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:00195E*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001AAD*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:A47AA4*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:1C1448*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:002493*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:40FC89*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:3C754A*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0024C1*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:002136*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0022B4*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:002395*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0023ED*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001B52*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:00230B*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001E8D*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0023A2*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0015D1*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001DD3*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:E8892C*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:E83EFC*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:707E43*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0003E0*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:00128A*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001225*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:083E0C*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:8C09F4*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:3CDFA9*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:105611*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:2C3AE8*
+ ID_OUI_FROM_DATABASE=Espressif Inc.
+
+OUI:DC74A8*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:C087EB*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:E8B6C2*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:B0DAF9*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:74F61C*
+ ID_OUI_FROM_DATABASE=HTC Corporation
+
+OUI:3438B7*
+ ID_OUI_FROM_DATABASE=HUMAX Co., Ltd.
+
+OUI:5C1A6F*
+ ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd.
+
+OUI:B089C2*
+ ID_OUI_FROM_DATABASE=Zyptonite
+
+OUI:F0D4F6*
+ ID_OUI_FROM_DATABASE=Lars Thrane A/S
+
+OUI:487D2E*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:0403D6*
+ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd
+
+OUI:A0AFBD*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:34D954*
+ ID_OUI_FROM_DATABASE=WiBotic Inc.
+
+OUI:6C60EB*
+ ID_OUI_FROM_DATABASE=ZHI YUAN ELECTRONICS CO., LIMITED
+
+OUI:AC4E2E*
+ ID_OUI_FROM_DATABASE=Shenzhen JingHanDa Electronics Co.Ltd
+
+OUI:B40016*
+ ID_OUI_FROM_DATABASE=INGENICO TERMINALS SAS
+
+OUI:0027E3*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:A0341B*
+ ID_OUI_FROM_DATABASE=TrackR, Inc
+
+OUI:FCA667*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:784501*
+ ID_OUI_FROM_DATABASE=Biamp Systems
+
+OUI:488D36*
+ ID_OUI_FROM_DATABASE=Arcadyan Corporation
+
+OUI:986F60*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:4C189A*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:E45D52*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:38BB3C*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:C057BC*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:D47856*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:14612F*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:707C69*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:A47886*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:44322A*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:048A15*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:6CA849*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:A4251B*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:00040D*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:FC8399*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
OUI:D86CE9*
ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
@@ -50099,24 +51860,6 @@ OUI:F4C714*
OUI:286ED4*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:A01290*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:F81547*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:506184*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:BCADAB*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:B4A95A*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:3C3A73*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
OUI:04F938*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
@@ -50825,9 +52568,6 @@ OUI:F46A92*
OUI:14AEDB*
ID_OUI_FROM_DATABASE=VTech Telecommunications Ltd.
-OUI:EC4F82*
- ID_OUI_FROM_DATABASE=Calix Inc.
-
OUI:B8C3BF*
ID_OUI_FROM_DATABASE=Henan Chengshi NetWork Technology Co.,Ltd
@@ -51245,9 +52985,6 @@ OUI:90DA6A*
OUI:A45DA1*
ID_OUI_FROM_DATABASE=ADB Broadband Italia
-OUI:A43D78*
- ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-
OUI:E8EF89*
ID_OUI_FROM_DATABASE=OPMEX Tech.
@@ -51956,9 +53693,6 @@ OUI:D81EDE*
OUI:6897E8*
ID_OUI_FROM_DATABASE=Society of Motion Picture &amp; Television Engineers
-OUI:24EA40*
- ID_OUI_FROM_DATABASE=Systeme Helmholz GmbH
-
OUI:FC58FA*
ID_OUI_FROM_DATABASE=Shen Zhen Shi Xin Zhong Xin Technology Co.,Ltd.
@@ -52013,9 +53747,6 @@ OUI:7CD844*
OUI:F4C6D7*
ID_OUI_FROM_DATABASE=blackned GmbH
-OUI:68A40E*
- ID_OUI_FROM_DATABASE=BSH Bosch and Siemens Home Appliances GmbH
-
OUI:4CCA53*
ID_OUI_FROM_DATABASE=Skyera, Inc.
@@ -52868,9 +54599,6 @@ OUI:B826D4*
OUI:14E4EC*
ID_OUI_FROM_DATABASE=mLogic LLC
-OUI:FC0A81*
- ID_OUI_FROM_DATABASE=Zebra Technologies Inc
-
OUI:AC0DFE*
ID_OUI_FROM_DATABASE=Ekon GmbH - myGEKKO
@@ -54089,9 +55817,6 @@ OUI:6CAC60*
OUI:DC0265*
ID_OUI_FROM_DATABASE=Meditech Kft
-OUI:986DC8*
- ID_OUI_FROM_DATABASE=TOSHIBA MITSUBISHI-ELECTRIC INDUSTRIAL SYSTEMS CORPORATION
-
OUI:68A1B7*
ID_OUI_FROM_DATABASE=Honghao Mingchuan Technology (Beijing) CO.,Ltd.
@@ -55616,9 +57341,6 @@ OUI:0018FB*
OUI:0019EE*
ID_OUI_FROM_DATABASE=CARLO GAVAZZI CONTROLS SPA-Controls Division
-OUI:0019F0*
- ID_OUI_FROM_DATABASE=UNIONMAN TECHNOLOGY CO.,LTD
-
OUI:0019F5*
ID_OUI_FROM_DATABASE=Imagination Technologies Ltd
@@ -56246,9 +57968,6 @@ OUI:0014B3*
OUI:00149B*
ID_OUI_FROM_DATABASE=Nokota Communications, LLC
-OUI:00143F*
- ID_OUI_FROM_DATABASE=Hotway Technology Corporation
-
OUI:001431*
ID_OUI_FROM_DATABASE=PDL Electronics Ltd
@@ -56891,9 +58610,6 @@ OUI:000FFD*
OUI:000FEE*
ID_OUI_FROM_DATABASE=XTec, Incorporated
-OUI:000FF4*
- ID_OUI_FROM_DATABASE=Guntermann & Drunck GmbH
-
OUI:001275*
ID_OUI_FROM_DATABASE=Sentilla Corporation
@@ -58373,9 +60089,6 @@ OUI:000641*
OUI:00063D*
ID_OUI_FROM_DATABASE=Microwave Data Systems Inc.
-OUI:000631*
- ID_OUI_FROM_DATABASE=Calix
-
OUI:000630*
ID_OUI_FROM_DATABASE=Adtranz Sweden
@@ -59651,9 +61364,6 @@ OUI:00E019*
OUI:00E0D7*
ID_OUI_FROM_DATABASE=SUNSHINE ELECTRONICS, INC.
-OUI:00E0DA*
- ID_OUI_FROM_DATABASE=Alcatel North America ESD
-
OUI:00E068*
ID_OUI_FROM_DATABASE=MERRIMAC SYSTEMS INC.
@@ -60335,9 +62045,6 @@ OUI:004000*
OUI:0040C5*
ID_OUI_FROM_DATABASE=MICOM COMMUNICATIONS INC.
-OUI:0040AA*
- ID_OUI_FROM_DATABASE=Metso Automation
-
OUI:004023*
ID_OUI_FROM_DATABASE=LOGIC CORPORATION
@@ -60980,9 +62687,6 @@ OUI:5464D9*
OUI:00023F*
ID_OUI_FROM_DATABASE=COMPAL ELECTRONICS, INC.
-OUI:0080C2*
- ID_OUI_FROM_DATABASE=IEEE 802.1
-
OUI:C46699*
ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
@@ -61241,12 +62945,6 @@ OUI:001D6A*
OUI:0000F4*
ID_OUI_FROM_DATABASE=Allied Telesis, Inc.
-OUI:10AE60*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:F04F7C*
- ID_OUI_FROM_DATABASE=Private
-
OUI:70F1A1*
ID_OUI_FROM_DATABASE=Liteon Technology Corporation
@@ -61496,15 +63194,6 @@ OUI:A80600*
OUI:6CF373*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:90F1AA*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
-OUI:C4576E*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
-OUI:78BDBC*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:3872C0*
ID_OUI_FROM_DATABASE=Comtrend Corporation
@@ -61757,9 +63446,6 @@ OUI:1CABC0*
OUI:84E323*
ID_OUI_FROM_DATABASE=Green Wave Telecommunication SDN BHD
-OUI:44650D*
- ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
-
OUI:D897BA*
ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
@@ -61985,9 +63671,6 @@ OUI:749D8F*
OUI:346AC2*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:50F5DA*
- ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
-
OUI:8CD2E9*
ID_OUI_FROM_DATABASE=NIPPON SMT Co.Ltd
@@ -62318,141 +64001,9 @@ OUI:343DC4*
OUI:6CEFC6*
ID_OUI_FROM_DATABASE=SHENZHEN TWOWING TECHNOLOGIES CO.,LTD.
-OUI:986B3D*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:CC65AD*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:789684*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:90C792*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0015CF*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:386BBB*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:00E06F*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0004BD*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:5C571A*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001DD0*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001DD5*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001DCF*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:E8ED05*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:901ACA*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:002A10*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:74E7C6*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:74F612*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:DC4517*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:F80BBE*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:6CC1D2*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:145BD1*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:B077AC*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:B81619*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:A41588*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:38700C*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:FC51A4*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:287AEE*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:641269*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001CC3*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:14D4FE*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:70B14E*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:D82522*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:707630*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:000CE5*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:000E5C*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0015A8*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001700*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0019A6*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0014E8*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:002180*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0026BA*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:002641*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:002374*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0025F2*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0019C0*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:886AB1*
ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
@@ -63107,12 +64658,6 @@ OUI:7C95B1*
OUI:206C8A*
ID_OUI_FROM_DATABASE=Aerohive Networks Inc.
-OUI:5CE30E*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:7823AE*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:E49E12*
ID_OUI_FROM_DATABASE=FREEBOX SAS
@@ -63281,9 +64826,6 @@ OUI:C4836F*
OUI:C87324*
ID_OUI_FROM_DATABASE=Sow Cheng Technology Co. Ltd.
-OUI:6854FD*
- ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
-
OUI:3CF862*
ID_OUI_FROM_DATABASE=Intel Corporate
@@ -63317,9 +64859,6 @@ OUI:00238A*
OUI:34E70B*
ID_OUI_FROM_DATABASE=HAN Networks Co., Ltd
-OUI:D47AE2*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:903809*
ID_OUI_FROM_DATABASE=Ericsson AB
@@ -63329,12 +64868,6 @@ OUI:542B57*
OUI:00111B*
ID_OUI_FROM_DATABASE=Targa Systems Div L-3 Communications
-OUI:2C7E81*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:EC01EE*
- ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-
OUI:B8224F*
ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD
@@ -63356,6 +64889,465 @@ OUI:98D3D2*
OUI:F4DC41*
ID_OUI_FROM_DATABASE=YOUNGZONE CULTURE (SHANGHAI) CORP
+OUI:9800C1*
+ ID_OUI_FROM_DATABASE=GuangZhou CREATOR Technology Co.,Ltd.(CHINA)
+
+OUI:3034D2*
+ ID_OUI_FROM_DATABASE=Availink, Inc.
+
+OUI:CCCE1E*
+ ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH
+
+OUI:501E2D*
+ ID_OUI_FROM_DATABASE=StreamUnlimited Engineering GmbH
+
+OUI:40B034*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:FC0A81*
+ ID_OUI_FROM_DATABASE=Extreme Networks
+
+OUI:C8B5AD*
+ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
+
+OUI:88E628*
+ ID_OUI_FROM_DATABASE=Shenzhen Kezhonglong Optoelectronic Technology Co.,Ltd
+
+OUI:6091F3*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:9CDA3E*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:3CA067*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
+OUI:D8325A*
+ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd
+
+OUI:44650D*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:50F5DA*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:6854FD*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:40B4CD*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:2C86D2*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:F04F7C*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:10AE60*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:802689*
+ ID_OUI_FROM_DATABASE=D-Link International
+
+OUI:BC2F3D*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:409F38*
+ ID_OUI_FROM_DATABASE=AzureWave Technology Inc.
+
+OUI:C4D197*
+ ID_OUI_FROM_DATABASE=Ventia Utility Services
+
+OUI:58821D*
+ ID_OUI_FROM_DATABASE=H. Schomäcker GmbH
+
+OUI:CCBE59*
+ ID_OUI_FROM_DATABASE=Calix Inc.
+
+OUI:EC4F82*
+ ID_OUI_FROM_DATABASE=Calix Inc.
+
+OUI:000631*
+ ID_OUI_FROM_DATABASE=Calix Inc.
+
+OUI:B8D7AF*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
+OUI:3096FB*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:F0EE10*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:A8A198*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:107D1A*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:C0D012*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:D4DCCD*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:484BAA*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:F80377*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:14BD61*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:0827CE*
+ ID_OUI_FROM_DATABASE=NAGANO KEIKI CO., LTD.
+
+OUI:00D318*
+ ID_OUI_FROM_DATABASE=SPG Controls
+
+OUI:2C3124*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:F40343*
+ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
+
+OUI:00143F*
+ ID_OUI_FROM_DATABASE=Hotway Technology Corporation
+
+OUI:F8BE0D*
+ ID_OUI_FROM_DATABASE=A2UICT Co.,Ltd.
+
+OUI:08EA40*
+ ID_OUI_FROM_DATABASE=SHENZHEN BILIAN ELECTRONIC CO.,LTD
+
+OUI:00E0DA*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Enterprise
+
+OUI:5CC6E9*
+ ID_OUI_FROM_DATABASE=Edifier International
+
+OUI:E8C1D7*
+ ID_OUI_FROM_DATABASE=Philips
+
+OUI:1868CB*
+ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd.
+
+OUI:F80BCB*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:9CC8AE*
+ ID_OUI_FROM_DATABASE=Becton, Dickinson and Company
+
+OUI:B0359F*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:24EA40*
+ ID_OUI_FROM_DATABASE=Helmholz GmbH & Co. KG
+
+OUI:84A9C4*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:A0F479*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:100501*
+ ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
+
+OUI:046E02*
+ ID_OUI_FROM_DATABASE=OpenRTLS Group
+
+OUI:000FF4*
+ ID_OUI_FROM_DATABASE=Guntermann & Drunck GmbH
+
+OUI:70DB98*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:A43D78*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:EC01EE*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:B83765*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:4448C1*
+ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
+
+OUI:FC539E*
+ ID_OUI_FROM_DATABASE=Shanghai Wind Technologies Co.,Ltd
+
+OUI:9CAF6F*
+ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED
+
+OUI:105887*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:9C061B*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:907065*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:C4ABB2*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:B8FFB3*
+ ID_OUI_FROM_DATABASE=MitraStar Technology Corp.
+
+OUI:A08E78*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+
+OUI:E0D55E*
+ ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
+
+OUI:C4576E*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:90F1AA*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:78BDBC*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:20F452*
+ ID_OUI_FROM_DATABASE=Shanghai IUV Software Development Co. Ltd
+
+OUI:D47AE2*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:88D274*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:986DC8*
+ ID_OUI_FROM_DATABASE=TOSHIBA MITSUBISHI-ELECTRIC INDUSTRIAL SYSTEMS CORPORATION
+
+OUI:982DBA*
+ ID_OUI_FROM_DATABASE=Fibergate Inc.
+
+OUI:0040AA*
+ ID_OUI_FROM_DATABASE=Valmet Automation
+
+OUI:0080C2*
+ ID_OUI_FROM_DATABASE=IEEE 802.1 Working Group
+
+OUI:68A40E*
+ ID_OUI_FROM_DATABASE=BSH Hausgeräte GmbH
+
+OUI:847933*
+ ID_OUI_FROM_DATABASE=profichip GmbH
+
+OUI:A0C9A0*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
+OUI:001CC3*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:641269*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:287AEE*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:FC51A4*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:38700C*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:A41588*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:B81619*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:B077AC*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:145BD1*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:6CC1D2*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:F80BBE*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:DC4517*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:74F612*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:74E7C6*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0025F2*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0015A8*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:000E5C*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:000CE5*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0004BD*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:00E06F*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:386BBB*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0015CF*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001DCF*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001DD5*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001DD0*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:5C571A*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:D82522*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:70B14E*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:14D4FE*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:002374*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:002641*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0026BA*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:002180*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0019C0*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0014E8*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0019A6*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001700*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:901ACA*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:E8ED05*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:707630*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:90C792*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:789684*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:CC65AD*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:986B3D*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:5CE30E*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:7823AE*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:447F77*
+ ID_OUI_FROM_DATABASE=Connected Home
+
+OUI:2C7E81*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:009AD2*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:84C0EF*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:7C1C68*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:745427*
+ ID_OUI_FROM_DATABASE=SHENZHEN FAST TECHNOLOGIES CO.,LTD
+
+OUI:F40E83*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:7C8BCA*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:88B111*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:54D751*
+ ID_OUI_FROM_DATABASE=Proximus
+
+OUI:D8F1F0*
+ ID_OUI_FROM_DATABASE=Pepxim International Limited
+
+OUI:0019F0*
+ ID_OUI_FROM_DATABASE=UNIONMAN TECHNOLOGY CO.,LTD
+
+OUI:506E92*
+ ID_OUI_FROM_DATABASE=Innocent Technology Co., Ltd.
+
+OUI:CC4B73*
+ ID_OUI_FROM_DATABASE=AMPAK Technology, Inc.
+
+OUI:900A1A*
+ ID_OUI_FROM_DATABASE=Taicang T&W Electronics
+
+OUI:CC03D9*
+ ID_OUI_FROM_DATABASE=Cisco Meraki
+
+OUI:506184*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:F81547*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:A01290*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:B4A95A*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:BCADAB*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:3C3A73*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:60271C*
+ ID_OUI_FROM_DATABASE=VIDEOR E. Hartig GmbH
+
OUI:2C3996*
ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
@@ -63626,9 +65618,6 @@ OUI:9060F1*
OUI:EC26CA*
ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-OUI:A09347*
- ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-
OUI:2C088C*
ID_OUI_FROM_DATABASE=HUMAX Co., Ltd.
@@ -63686,12 +65675,6 @@ OUI:08181A*
OUI:002512*
ID_OUI_FROM_DATABASE=zte corporation
-OUI:CCF954*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:703018*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
OUI:B0A37E*
ID_OUI_FROM_DATABASE=Qingdao Haier Telecom Co.,Ltd
@@ -63755,30 +65738,6 @@ OUI:84A8E4*
OUI:202BC1*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:3475C7*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:6CFA58*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:64A7DD*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:646A52*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:F873A2*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:64C354*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:B4B017*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
-OUI:581626*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
OUI:741BB2*
ID_OUI_FROM_DATABASE=Apple, Inc.
@@ -64958,9 +66917,6 @@ OUI:E85D6B*
OUI:8C3357*
ID_OUI_FROM_DATABASE=HiteVision Digital Media Technology Co.,Ltd.
-OUI:506787*
- ID_OUI_FROM_DATABASE=iTellus
-
OUI:F4D261*
ID_OUI_FROM_DATABASE=SEMOCON Co., Ltd
@@ -65153,9 +67109,6 @@ OUI:90DFB7*
OUI:B843E4*
ID_OUI_FROM_DATABASE=Vlatacom
-OUI:8425A4*
- ID_OUI_FROM_DATABASE=Tariox Limited
-
OUI:E07F53*
ID_OUI_FROM_DATABASE=TECHBOARD SRL
@@ -65987,9 +67940,6 @@ OUI:2CEDEB*
OUI:381C4A*
ID_OUI_FROM_DATABASE=SIMCom Wireless Solutions Co.,Ltd.
-OUI:C8DE51*
- ID_OUI_FROM_DATABASE=Integra Networks, Inc.
-
OUI:901EDD*
ID_OUI_FROM_DATABASE=GREAT COMPUTER CORPORATION
@@ -66929,9 +68879,6 @@ OUI:C4D489*
OUI:1C7C11*
ID_OUI_FROM_DATABASE=EID
-OUI:F43E61*
- ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co., Ltd
-
OUI:B0B32B*
ID_OUI_FROM_DATABASE=Slican Sp. z o.o.
@@ -67157,9 +69104,6 @@ OUI:9C4563*
OUI:E42771*
ID_OUI_FROM_DATABASE=Smartlabs
-OUI:C4EEF5*
- ID_OUI_FROM_DATABASE=Oclaro, Inc.
-
OUI:0876FF*
ID_OUI_FROM_DATABASE=Thomson Telecom Belgium
@@ -68624,9 +70568,6 @@ OUI:001FAA*
OUI:001FA5*
ID_OUI_FROM_DATABASE=Blue-White Industries
-OUI:001FA4*
- ID_OUI_FROM_DATABASE=ShenZhen Gongjin Electronics Co.,Ltd
-
OUI:001FA0*
ID_OUI_FROM_DATABASE=A10 Networks
@@ -68840,9 +70781,6 @@ OUI:001D4D*
OUI:001D49*
ID_OUI_FROM_DATABASE=Innovation Wireless Inc.
-OUI:001D44*
- ID_OUI_FROM_DATABASE=KROHNE Messtechnik GmbH
-
OUI:001D3D*
ID_OUI_FROM_DATABASE=Avidyne Corporation
@@ -69623,9 +71561,6 @@ OUI:00181D*
OUI:001811*
ID_OUI_FROM_DATABASE=Neuros Technology International, LLC.
-OUI:00180A*
- ID_OUI_FROM_DATABASE=Meraki, Inc.
-
OUI:001801*
ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
@@ -70691,9 +72626,6 @@ OUI:000F1D*
OUI:000F10*
ID_OUI_FROM_DATABASE=RDM Corporation
-OUI:000F17*
- ID_OUI_FROM_DATABASE=Insta Elektro GmbH
-
OUI:000F1E*
ID_OUI_FROM_DATABASE=Chengdu KT Electric Co.of High & New Technology
@@ -71054,9 +72986,6 @@ OUI:000C03*
OUI:000CA4*
ID_OUI_FROM_DATABASE=Prompttec Product Management GmbH
-OUI:000CAB*
- ID_OUI_FROM_DATABASE=COMMEND International
-
OUI:000C98*
ID_OUI_FROM_DATABASE=LETEK Communications Inc.
@@ -72665,9 +74594,6 @@ OUI:000232*
OUI:00012A*
ID_OUI_FROM_DATABASE=Telematica Sistems Inteligente
-OUI:000130*
- ID_OUI_FROM_DATABASE=Extreme Networks
-
OUI:000137*
ID_OUI_FROM_DATABASE=IT Farm Corporation
@@ -73832,9 +75758,6 @@ OUI:002054*
OUI:0020A7*
ID_OUI_FROM_DATABASE=PAIRGAIN TECHNOLOGIES, INC.
-OUI:0020DA*
- ID_OUI_FROM_DATABASE=Alcatel North America ESD
-
OUI:002005*
ID_OUI_FROM_DATABASE=SIMPLE TECHNOLOGY
@@ -74735,9 +76658,6 @@ OUI:88AE1D*
OUI:5C353B*
ID_OUI_FROM_DATABASE=Compal Broadband Networks, Inc.
-OUI:C8F230*
- ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-
OUI:1C4419*
ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
@@ -74978,21 +76898,12 @@ OUI:DC0B1A*
OUI:74888B*
ID_OUI_FROM_DATABASE=ADB Broadband Italia
-OUI:84D6D0*
- ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
-
-OUI:E0CB1D*
- ID_OUI_FROM_DATABASE=Private
-
OUI:ACD074*
ID_OUI_FROM_DATABASE=Espressif Inc.
OUI:D05349*
ID_OUI_FROM_DATABASE=Liteon Technology Corporation
-OUI:00BB3A*
- ID_OUI_FROM_DATABASE=Private
-
OUI:000941*
ID_OUI_FROM_DATABASE=Allied Telesis R&D Center K.K.
@@ -75203,24 +77114,9 @@ OUI:18227E*
OUI:00F46F*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:BC1485*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:9CE6E7*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:380195*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
-OUI:5CF6DC*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
-OUI:1077B1*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
-OUI:508569*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:0090A2*
ID_OUI_FROM_DATABASE=CyberTAN Technology Inc.
@@ -75461,9 +77357,6 @@ OUI:0C5A9E*
OUI:00C164*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:C4BED4*
- ID_OUI_FROM_DATABASE=Avaya Inc
-
OUI:98E7F5*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
@@ -75521,9 +77414,6 @@ OUI:E0071B*
OUI:A86AC1*
ID_OUI_FROM_DATABASE=HanbitEDS Co., Ltd.
-OUI:40163B*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:88B1E1*
ID_OUI_FROM_DATABASE=Mojo Networks, Inc.
@@ -75800,9 +77690,6 @@ OUI:E811CA*
OUI:ECD68A*
ID_OUI_FROM_DATABASE=Shenzhen JMicron Intelligent Technology Developmen
-OUI:1C77F6*
- ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-
OUI:08D0B7*
ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd.
@@ -76019,135 +77906,9 @@ OUI:BC8AA3*
OUI:70A84C*
ID_OUI_FROM_DATABASE=MONAD., Inc.
-OUI:00D088*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001675*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0016B5*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001784*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0017E2*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:CC7D37*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001A77*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:984B4A*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0015A4*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0015A3*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:7CBFB1*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:8096B1*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:00909C*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001180*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0017EE*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:407009*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:94877C*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001DD2*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:9C3426*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:5C8FE0*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:6CCA08*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:5465DE*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:F8EDA5*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:00A289*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:ACEC80*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:3C7A8A*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:000FCC*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:BCCAB5*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:80F503*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:8496D8*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:D42C0F*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:E0B7B1*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0024A0*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:C0C522*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:5CB066*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:002210*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:00211E*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:E48399*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:002636*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:0012C9*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001CFB*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001C12*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:001FC4*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:6C1E90*
ID_OUI_FROM_DATABASE=Hansol Technics Co., Ltd.
@@ -76754,9 +78515,6 @@ OUI:FCFAF7*
OUI:C8E776*
ID_OUI_FROM_DATABASE=PTCOM Technology
-OUI:5C497D*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:949AA9*
ID_OUI_FROM_DATABASE=Microsoft Corporation
@@ -76889,9 +78647,6 @@ OUI:9C5D12*
OUI:001F82*
ID_OUI_FROM_DATABASE=Cal-Comp Electronics & Communications Company Ltd.
-OUI:E47DBD*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:0C0227*
ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
@@ -76910,9 +78665,6 @@ OUI:B49691*
OUI:9CD9CB*
ID_OUI_FROM_DATABASE=Lesira Manufacturing Pty Ltd
-OUI:34D270*
- ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
-
OUI:002590*
ID_OUI_FROM_DATABASE=Super Micro Computer, Inc.
@@ -76970,18 +78722,12 @@ OUI:20780B*
OUI:24D51C*
ID_OUI_FROM_DATABASE=Zhongtian broadband technology co., LTD
-OUI:E44790*
- ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-
OUI:28FECD*
ID_OUI_FROM_DATABASE=Lemobile Information Technology (Beijing) Co., Ltd.
OUI:001992*
ID_OUI_FROM_DATABASE=Adtran Inc
-OUI:002365*
- ID_OUI_FROM_DATABASE=Insta Elektro GmbH
-
OUI:4C1694*
ID_OUI_FROM_DATABASE=shenzhen sibituo Technology Co., Ltd
@@ -77026,3 +78772,495 @@ OUI:B81DAA*
OUI:407D0F*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:3805AC*
+ ID_OUI_FROM_DATABASE=Piller Group GmbH
+
+OUI:F8BBBF*
+ ID_OUI_FROM_DATABASE=eero inc.
+
+OUI:0CF4D5*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:000130*
+ ID_OUI_FROM_DATABASE=Extreme Networks
+
+OUI:706DEC*
+ ID_OUI_FROM_DATABASE=Wifi-soft LLC
+
+OUI:AC6B0F*
+ ID_OUI_FROM_DATABASE=CADENCE DESIGN SYSTEMS INC
+
+OUI:00BB3A*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:E0CB1D*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:84D6D0*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:34D270*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:CC82EB*
+ ID_OUI_FROM_DATABASE=KYOCERA CORPORATION
+
+OUI:5082D5*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:9C84BF*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:7894B4*
+ ID_OUI_FROM_DATABASE=Sercomm Corporation.
+
+OUI:000F17*
+ ID_OUI_FROM_DATABASE=Insta Elektro GmbH
+
+OUI:002365*
+ ID_OUI_FROM_DATABASE=Insta Elektro GmbH
+
+OUI:C4EEF5*
+ ID_OUI_FROM_DATABASE=II-VI Incorporated
+
+OUI:002CC8*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:70AF24*
+ ID_OUI_FROM_DATABASE=TP Vision Belgium NV
+
+OUI:7CE97C*
+ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED
+
+OUI:285F2F*
+ ID_OUI_FROM_DATABASE=RNware Co.,Ltd.
+
+OUI:E0C0D1*
+ ID_OUI_FROM_DATABASE=CK Telecom (Shenzhen) Limited
+
+OUI:948BC1*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:4827EA*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:049573*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:001D44*
+ ID_OUI_FROM_DATABASE=Krohne
+
+OUI:48BF6B*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:245BA7*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:BCA920*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:D055B2*
+ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd.
+
+OUI:A49BF5*
+ ID_OUI_FROM_DATABASE=Hybridserver Tec GmbH
+
+OUI:B436E3*
+ ID_OUI_FROM_DATABASE=KBVISION GROUP
+
+OUI:488803*
+ ID_OUI_FROM_DATABASE=ManTechnology Inc.
+
+OUI:7C6BF7*
+ ID_OUI_FROM_DATABASE=NTI co., ltd.
+
+OUI:54E061*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD
+
+OUI:B47C9C*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:E81367*
+ ID_OUI_FROM_DATABASE=AIRSOUND Inc.
+
+OUI:64D154*
+ ID_OUI_FROM_DATABASE=Routerboard.com
+
+OUI:0020DA*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Enterprise
+
+OUI:1CDA27*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:345BBB*
+ ID_OUI_FROM_DATABASE=GD Midea Air-Conditioning Equipment Co.,Ltd.
+
+OUI:34CE00*
+ ID_OUI_FROM_DATABASE=XIAOMI Electronics,CO.,LTD
+
+OUI:F82F08*
+ ID_OUI_FROM_DATABASE=Molex
+
+OUI:68262A*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD
+
+OUI:680235*
+ ID_OUI_FROM_DATABASE=Konten Networks Inc.
+
+OUI:3C678C*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:D06F82*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:844765*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:A0C4A5*
+ ID_OUI_FROM_DATABASE=SYGN HOUSE CO.,LTD
+
+OUI:506787*
+ ID_OUI_FROM_DATABASE=Planet Networks
+
+OUI:C83A6B*
+ ID_OUI_FROM_DATABASE=Roku, Inc
+
+OUI:B4C6F8*
+ ID_OUI_FROM_DATABASE=Axilspot Communication
+
+OUI:70D923*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:B83A08*
+ ID_OUI_FROM_DATABASE=Tenda Technology Co.,Ltd.Dongguan branch
+
+OUI:388C50*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
+OUI:50D37F*
+ ID_OUI_FROM_DATABASE=Yu Fly Mikly Way Science and Technology Co., Ltd.
+
+OUI:D8D866*
+ ID_OUI_FROM_DATABASE=SHENZHEN TOZED TECHNOLOGIES CO.,LTD.
+
+OUI:F43E61*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
+OUI:001FA4*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
+OUI:1C5A0B*
+ ID_OUI_FROM_DATABASE=Tegile Systems
+
+OUI:38AC3D*
+ ID_OUI_FROM_DATABASE=Nephos Inc
+
+OUI:A09347*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:C8F230*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:1C77F6*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:E44790*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:D4503F*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:8425A4*
+ ID_OUI_FROM_DATABASE=Tariox Limited
+
+OUI:D8C8E9*
+ ID_OUI_FROM_DATABASE=Phicomm (Shanghai) Co., Ltd.
+
+OUI:CC90E8*
+ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd
+
+OUI:88CC45*
+ ID_OUI_FROM_DATABASE=Skyworth Digital Technology(Shenzhen) Co.,Ltd
+
+OUI:605317*
+ ID_OUI_FROM_DATABASE=Sandstone Technologies
+
+OUI:50338B*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:986C5C*
+ ID_OUI_FROM_DATABASE=Jiangxi Gosun Guard Security Co.,Ltd
+
+OUI:F4FCB1*
+ ID_OUI_FROM_DATABASE=JJ Corp
+
+OUI:543B30*
+ ID_OUI_FROM_DATABASE=duagon AG
+
+OUI:60BA18*
+ ID_OUI_FROM_DATABASE=nextLAP GmbH
+
+OUI:704CA5*
+ ID_OUI_FROM_DATABASE=Fortinet, Inc.
+
+OUI:40163B*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:5C497D*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:E47DBD*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:503DA1*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:A040A0*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:508569*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:1077B1*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:5CF6DC*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:380195*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:BC1485*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:88D50C*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:509A4C*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:00180A*
+ ID_OUI_FROM_DATABASE=Cisco Meraki
+
+OUI:AC2205*
+ ID_OUI_FROM_DATABASE=Compal Broadband Networks, Inc.
+
+OUI:80A036*
+ ID_OUI_FROM_DATABASE=Shanghai MXCHIP Information Technology Co., Ltd.
+
+OUI:0012C9*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:984B4A*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001A77*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:CC7D37*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0017E2*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001784*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0016B5*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001675*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:00D088*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0017EE*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001180*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:00909C*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:8096B1*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:7CBFB1*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0015A3*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0015A4*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:9C3426*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001DD2*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:00211E*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:002210*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001FC4*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001C12*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:001CFB*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:D42C0F*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:8496D8*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:80F503*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:5CB066*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:C0C522*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:0024A0*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:002636*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:E48399*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:E0B7B1*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:94877C*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:407009*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:F8EDA5*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:5465DE*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:6CCA08*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:5C8FE0*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:8C395C*
+ ID_OUI_FROM_DATABASE=Bit4id Srl
+
+OUI:BCCAB5*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:000FCC*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:3C7A8A*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:ACEC80*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:2CA17D*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:309C23*
+ ID_OUI_FROM_DATABASE=Micro-Star INTL CO., LTD.
+
+OUI:947BE7*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:2C2617*
+ ID_OUI_FROM_DATABASE=Oculus VR, LLC
+
+OUI:98F7D7*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:2C41A1*
+ ID_OUI_FROM_DATABASE=Bose Corporation
+
+OUI:C8DE51*
+ ID_OUI_FROM_DATABASE=IntegraOptics
+
+OUI:182CB4*
+ ID_OUI_FROM_DATABASE=Nectarsoft Co., Ltd.
+
+OUI:14780B*
+ ID_OUI_FROM_DATABASE=PerkinElmer Technologies GmbH & Co. KG
+
+OUI:74DADA*
+ ID_OUI_FROM_DATABASE=D-Link International
+
+OUI:4C910C*
+ ID_OUI_FROM_DATABASE=Corporativo Lanix S.A. de C.V.
+
+OUI:BCD713*
+ ID_OUI_FROM_DATABASE=Owl Labs
+
+OUI:E8E1E1*
+ ID_OUI_FROM_DATABASE=Gemtek Technology Co., Ltd.
+
+OUI:98F2B3*
+ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
+
+OUI:BC1C81*
+ ID_OUI_FROM_DATABASE=Sichuan iLink Technology Co., Ltd.
+
+OUI:CCF954*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:581626*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:B4B017*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:64C354*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:F873A2*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:646A52*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:64A7DD*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:6CFA58*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:3475C7*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:C4BED4*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:30FE31*
+ ID_OUI_FROM_DATABASE=Nokia
+
+OUI:703018*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:78B28D*
+ ID_OUI_FROM_DATABASE=Beijing Tengling Technology CO.Ltd
+
+OUI:000CAB*
+ ID_OUI_FROM_DATABASE=Commend International GmbH
diff --git a/hwdb/20-acpi-vendor.hwdb b/hwdb/20-acpi-vendor.hwdb
index c0fe421c11..886e61aa38 100644
--- a/hwdb/20-acpi-vendor.hwdb
+++ b/hwdb/20-acpi-vendor.hwdb
@@ -6,6 +6,9 @@
#
# With various additions from other sources
+acpi:3GVR*:
+ ID_VENDOR_FROM_DATABASE=VR Technology Holdings Limited
+
acpi:3NOD*:
ID_VENDOR_FROM_DATABASE=Shenzhen three Connaught Information Technology Co., Ltd. (3nod Group)
@@ -1947,6 +1950,9 @@ acpi:DPL*:
acpi:DPM*:
ID_VENDOR_FROM_DATABASE=ADPM Synthesis sas
+acpi:DPN*:
+ ID_VENDOR_FROM_DATABASE=Shanghai Lexiang Technology Limited
+
acpi:DPS*:
ID_VENDOR_FROM_DATABASE=Digital Processing Systems
@@ -1983,6 +1989,9 @@ acpi:DSD*:
acpi:DSI*:
ID_VENDOR_FROM_DATABASE=Digitan Systems Inc
+acpi:DSJ*:
+ ID_VENDOR_FROM_DATABASE=VR Technology Holdings Limited
+
acpi:DSM*:
ID_VENDOR_FROM_DATABASE=DSM Digital Services GmbH
@@ -3489,6 +3498,9 @@ acpi:IVI*:
acpi:IVM*:
ID_VENDOR_FROM_DATABASE=Iiyama North America
+acpi:IVR*:
+ ID_VENDOR_FROM_DATABASE=Inlife-Handnet Co., Ltd.
+
acpi:IVS*:
ID_VENDOR_FROM_DATABASE=Intevac Photonics Inc.
@@ -5367,6 +5379,9 @@ acpi:PVN*:
acpi:PVP*:
ID_VENDOR_FROM_DATABASE=Klos Technologies, Inc.
+acpi:PVR*:
+ ID_VENDOR_FROM_DATABASE=Pimax Tech. CO., LTD
+
acpi:PXC*:
ID_VENDOR_FROM_DATABASE=Phoenix Contact
@@ -6780,6 +6795,9 @@ acpi:TVD*:
acpi:TVI*:
ID_VENDOR_FROM_DATABASE=Truevision
+acpi:TVL*:
+ ID_VENDOR_FROM_DATABASE=Total Vision LTD
+
acpi:TVM*:
ID_VENDOR_FROM_DATABASE=Taiwan Video & Monitor Corporation
diff --git a/hwdb/20-pci-vendor-model.hwdb b/hwdb/20-pci-vendor-model.hwdb
index ea190ff7ca..83ff9f3668 100644
--- a/hwdb/20-pci-vendor-model.hwdb
+++ b/hwdb/20-pci-vendor-model.hwdb
@@ -68,12 +68,18 @@ pci:v0000021Bd00008139*
pci:v00000270*
ID_VENDOR_FROM_DATABASE=Hauppauge computer works Inc. (Wrong ID)
+pci:v00000291*
+ ID_VENDOR_FROM_DATABASE=Davicom Semiconductor, Inc. (Wrong ID)
+
pci:v000002AC*
ID_VENDOR_FROM_DATABASE=SpeedStream
pci:v000002ACd00001012*
ID_MODEL_FROM_DATABASE=1012 PCMCIA 10/100 Ethernet Card [RTL81xx]
+pci:v000002E0*
+ ID_VENDOR_FROM_DATABASE=XFX Pine Group Inc. (Wrong ID)
+
pci:v00000303*
ID_VENDOR_FROM_DATABASE=Hewlett-Packard Company (Wrong ID)
@@ -653,6 +659,9 @@ pci:v00001000d00000014sv00001028sd00001FD4*
pci:v00001000d00000014sv00001D49sd00000602*
ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3516 (ThinkSystem RAID 930-16i 4GB Flash PCIe 12Gb Adapter)
+pci:v00001000d00000015*
+ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3416
+
pci:v00001000d00000016*
ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3508
@@ -1547,6 +1556,9 @@ pci:v00001000d00000097sv00001028sd00001FD2*
pci:v00001000d00000097sv00001028sd00001FD3*
ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (HBA330 MMZ)
+pci:v00001000d00000097sv00001BD4sd00000011*
+ ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (Inspur 12Gb 8i-3008 IT SAS HBA)
+
pci:v00001000d000000AB*
ID_MODEL_FROM_DATABASE=SAS3516 Fusion-MPT Tri-Mode RAID On Chip (ROC)
@@ -1554,10 +1566,10 @@ pci:v00001000d000000AC*
ID_MODEL_FROM_DATABASE=SAS3416 Fusion-MPT Tri-Mode I/O Controller Chip (IOC)
pci:v00001000d000000ACsv00001D49sd00000201*
- ID_MODEL_FROM_DATABASE=SAS3416 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (ThinkSystem 9400-16i PCIe 12Gb HBA)
+ ID_MODEL_FROM_DATABASE=SAS3416 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (ThinkSystem 430-16i SAS/SATA 12Gb HBA)
pci:v00001000d000000ACsv00001D49sd00000203*
- ID_MODEL_FROM_DATABASE=SAS3416 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (ThinkSystem 9400-16e PCIe 12Gb HBA)
+ ID_MODEL_FROM_DATABASE=SAS3416 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (ThinkSystem 430-16e SAS/SATA 12Gb HBA)
pci:v00001000d000000AE*
ID_MODEL_FROM_DATABASE=SAS3508 Fusion-MPT Tri-Mode RAID On Chip (ROC)
@@ -1566,10 +1578,10 @@ pci:v00001000d000000AF*
ID_MODEL_FROM_DATABASE=SAS3408 Fusion-MPT Tri-Mode I/O Controller Chip (IOC)
pci:v00001000d000000AFsv00001D49sd00000200*
- ID_MODEL_FROM_DATABASE=SAS3408 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (ThinkSystem 9400-8i PCIe 12Gb HBA)
+ ID_MODEL_FROM_DATABASE=SAS3408 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (ThinkSystem 430-8i SAS/SATA 12Gb HBA)
pci:v00001000d000000AFsv00001D49sd00000202*
- ID_MODEL_FROM_DATABASE=SAS3408 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (ThinkSystem 9400-8e PCIe 12Gb HBA)
+ ID_MODEL_FROM_DATABASE=SAS3408 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (ThinkSystem 430-8e SAS/SATA 12Gb HBA)
pci:v00001000d000000BE*
ID_MODEL_FROM_DATABASE=SAS3504 Fusion-MPT Tri-Mode RAID On Chip (ROC)
@@ -6476,6 +6488,21 @@ pci:v00001002d000067BE*
pci:v00001002d000067C0*
ID_MODEL_FROM_DATABASE=Ellesmere [Polaris10]
+pci:v00001002d000067C4*
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon Pro WX 7100]
+
+pci:v00001002d000067C7*
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon Pro WX 5100]
+
+pci:v00001002d000067CA*
+ ID_MODEL_FROM_DATABASE=Ellesmere [Polaris10]
+
+pci:v00001002d000067CC*
+ ID_MODEL_FROM_DATABASE=Ellesmere [Polaris10]
+
+pci:v00001002d000067CF*
+ ID_MODEL_FROM_DATABASE=Ellesmere [Polaris10]
+
pci:v00001002d000067DF*
ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480]
@@ -6527,6 +6554,9 @@ pci:v00001002d000067E0*
pci:v00001002d000067E1*
ID_MODEL_FROM_DATABASE=Baffin [Polaris11]
+pci:v00001002d000067E3*
+ ID_MODEL_FROM_DATABASE=Baffin [Radeon Pro WX 4100]
+
pci:v00001002d000067E8*
ID_MODEL_FROM_DATABASE=Baffin [Polaris11]
@@ -6611,6 +6641,9 @@ pci:v00001002d00006811sv00001458sd00002016*
pci:v00001002d00006811sv00001462sd00002016*
ID_MODEL_FROM_DATABASE=Curacao PRO [Radeon R7 370 / R9 270/370 OEM] (Trinidad PRO [Radeon R9 370 OEM])
+pci:v00001002d00006811sv00001462sd00003050*
+ ID_MODEL_FROM_DATABASE=Curacao PRO [Radeon R7 370 / R9 270/370 OEM] (R9 270 Gaming OC)
+
pci:v00001002d00006811sv0000148Csd00002016*
ID_MODEL_FROM_DATABASE=Curacao PRO [Radeon R7 370 / R9 270/370 OEM] (Trinidad PRO [Radeon R9 370 OEM])
@@ -8636,6 +8669,24 @@ pci:v00001002d00006939sv0000148Csd00009380*
pci:v00001002d00006939sv0000174Bsd0000E308*
ID_MODEL_FROM_DATABASE=Tonga PRO [Radeon R9 285/380] (Radeon R9 380 Nitro 4G D5)
+pci:v00001002d00006980*
+ ID_MODEL_FROM_DATABASE=Polaris12
+
+pci:v00001002d00006981*
+ ID_MODEL_FROM_DATABASE=Polaris12
+
+pci:v00001002d00006985*
+ ID_MODEL_FROM_DATABASE=Polaris12
+
+pci:v00001002d00006986*
+ ID_MODEL_FROM_DATABASE=Polaris12
+
+pci:v00001002d00006987*
+ ID_MODEL_FROM_DATABASE=Polaris12
+
+pci:v00001002d0000699F*
+ ID_MODEL_FROM_DATABASE=Polaris12
+
pci:v00001002d0000700F*
ID_MODEL_FROM_DATABASE=RS100 AGP Bridge
@@ -15086,6 +15137,9 @@ pci:v00001043d00000675sv00000675sd00001707*
pci:v00001043d00000675sv000010CFsd0000105E*
ID_MODEL_FROM_DATABASE=ISDNLink P-IN100-ST-D (ISDN Adapter (PCI Bus, DV, W))
+pci:v00001043d000013A0*
+ ID_MODEL_FROM_DATABASE=Transformer Book T101HA-GR030R
+
pci:v00001043d00009602*
ID_MODEL_FROM_DATABASE=AMD RS780/RS880 PCI to PCI bridge (int gfx)
@@ -16304,6 +16358,12 @@ pci:v0000104Dd0000808A*
pci:v0000104Dd000081CE*
ID_MODEL_FROM_DATABASE=SxS Pro memory card
+pci:v0000104Dd0000905C*
+ ID_MODEL_FROM_DATABASE=SxS Pro memory card
+
+pci:v0000104Dd0000907F*
+ ID_MODEL_FROM_DATABASE=SxS Pro+ memory card
+
pci:v0000104Dd0000908F*
ID_MODEL_FROM_DATABASE=Aeolia ACPI
@@ -16328,6 +16388,9 @@ pci:v0000104Dd000090A3*
pci:v0000104Dd000090A4*
ID_MODEL_FROM_DATABASE=Aeolia USB 3.0 xHCI Host Controller
+pci:v0000104Dd000090BC*
+ ID_MODEL_FROM_DATABASE=SxS Pro+ memory card
+
pci:v0000104E*
ID_VENDOR_FROM_DATABASE=Oak Technology, Inc
@@ -18017,6 +18080,48 @@ pci:v00001077d00008031*
pci:v00001077d00008032*
ID_MODEL_FROM_DATABASE=8300 Series 10GbE Converged Network Adapter (iSCSI)
+pci:v00001077d00008070*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller
+
+pci:v00001077d00008070sv00001077sd00000011*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FastLinQ QL41212H 25GbE Adapter)
+
+pci:v00001077d00008070sv00001077sd00000012*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FastLinQ QL41112H 10GbE Adapter)
+
+pci:v00001077d00008080*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE)
+
+pci:v00001077d00008080sv00001077sd0000000D*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) (FastLinQ QL41262H 25GbE FCoE Adapter)
+
+pci:v00001077d00008080sv00001077sd0000000E*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) (FastLinQ QL41162H 10GbE FCoE Adapter)
+
+pci:v00001077d00008084*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI)
+
+pci:v00001077d00008084sv00001077sd0000000D*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (FastLinQ QL41262H 25GbE iSCSI Adapter)
+
+pci:v00001077d00008084sv00001077sd0000000E*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (FastLinQ QL41162H 10GbE iSCSI Adapter)
+
+pci:v00001077d00008090*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF)
+
+pci:v00001077d00008090sv00001077sd0000000D*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (FastLinQ QL41262H 25GbE FCoE Adapter (SR-IOV VF))
+
+pci:v00001077d00008090sv00001077sd0000000E*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (FastLinQ QL41162H 10GbE iSCSI Adapter (SR-IOV VF))
+
+pci:v00001077d00008090sv00001077sd00000011*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (FastLinQ QL41212H 25GbE Adapter (SR-IOV VF))
+
+pci:v00001077d00008090sv00001077sd00000012*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (FastLinQ QL41112H 10GbE Adapter (SR-IOV VF))
+
pci:v00001077d00008430*
ID_MODEL_FROM_DATABASE=ISP8324 1/10GbE Converged Network Controller (NIC VF)
@@ -22317,7 +22422,7 @@ pci:v000010B5d00009733*
ID_MODEL_FROM_DATABASE=PEX 9733 33-lane, 9-port PCI Express Gen 3 (8.0 GT/s) Switch
pci:v000010B5d00009733sv00001D49sd00000001*
- ID_MODEL_FROM_DATABASE=PEX 9733 33-lane, 9-port PCI Express Gen 3 (8.0 GT/s) Switch (ThinkSystem P310W-4P NVMe Switch Card)
+ ID_MODEL_FROM_DATABASE=PEX 9733 33-lane, 9-port PCI Express Gen 3 (8.0 GT/s) Switch (ThinkSystem 1610-4P NVMe Switch Adapter)
pci:v000010B5d00009749*
ID_MODEL_FROM_DATABASE=PEX 9749 49-lane, 13-port PCI Express Gen 3 (8.0 GT/s) Switch
@@ -24836,6 +24941,9 @@ pci:v000010DEd00000103sv00001048sd00000C4A*
pci:v000010DEd00000103sv00001048sd00000C4B*
ID_MODEL_FROM_DATABASE=NV10GL [Quadro] (GLoria II-64 Pro DVII)
+pci:v000010DEd00000103sv000010A9sd00009002*
+ ID_MODEL_FROM_DATABASE=NV10GL [Quadro] (VPro VR3)
+
pci:v000010DEd00000110*
ID_MODEL_FROM_DATABASE=NV11 [GeForce2 MX/MX 400]
@@ -29882,6 +29990,9 @@ pci:v000010DEd000010C5*
pci:v000010DEd000010D8*
ID_MODEL_FROM_DATABASE=GT218 [NVS 300]
+pci:v000010DEd000010EF*
+ ID_MODEL_FROM_DATABASE=GP102 HDMI Audio Controller
+
pci:v000010DEd000010F0*
ID_MODEL_FROM_DATABASE=GP104 High Definition Audio Controller
@@ -31349,6 +31460,9 @@ pci:v000010DEd00001348*
pci:v000010DEd00001349*
ID_MODEL_FROM_DATABASE=GM108M [GeForce 930M]
+pci:v000010DEd0000134B*
+ ID_MODEL_FROM_DATABASE=GM108M [GeForce 940MX]
+
pci:v000010DEd0000134D*
ID_MODEL_FROM_DATABASE=GM108M [GeForce 940MX]
@@ -31445,6 +31559,12 @@ pci:v000010DEd000013B2*
pci:v000010DEd000013B3*
ID_MODEL_FROM_DATABASE=GM107GLM [Quadro K2200M]
+pci:v000010DEd000013B4*
+ ID_MODEL_FROM_DATABASE=GM107GLM [Quadro M620 Mobile]
+
+pci:v000010DEd000013B6*
+ ID_MODEL_FROM_DATABASE=GM107GLM [Quadro M1200 Mobile]
+
pci:v000010DEd000013B9*
ID_MODEL_FROM_DATABASE=GM107GL [NVS 810]
@@ -31506,7 +31626,7 @@ pci:v000010DEd000013F3*
ID_MODEL_FROM_DATABASE=GM204GL [Tesla M6]
pci:v000010DEd000013F8*
- ID_MODEL_FROM_DATABASE=GM204GLM [Quadro M5000M]
+ ID_MODEL_FROM_DATABASE=GM204GLM [Quadro M5000M / M5000 SE]
pci:v000010DEd000013F9*
ID_MODEL_FROM_DATABASE=GM204GLM [Quadro M4000M]
@@ -31541,17 +31661,23 @@ pci:v000010DEd00001430*
pci:v000010DEd00001431*
ID_MODEL_FROM_DATABASE=GM206GL [Tesla M4]
+pci:v000010DEd00001436*
+ ID_MODEL_FROM_DATABASE=GM206GLM [Quadro M2200 Mobile]
+
pci:v000010DEd000015F0*
ID_MODEL_FROM_DATABASE=GP100GL
pci:v000010DEd000015F1*
ID_MODEL_FROM_DATABASE=GP100GL
+pci:v000010DEd000015F7*
+ ID_MODEL_FROM_DATABASE=GP100GL [Tesla P100 PCIe 12GB]
+
pci:v000010DEd000015F8*
- ID_MODEL_FROM_DATABASE=GP100GL
+ ID_MODEL_FROM_DATABASE=GP100GL [Tesla P100 PCIe 16GB]
pci:v000010DEd000015F9*
- ID_MODEL_FROM_DATABASE=GP100GL
+ ID_MODEL_FROM_DATABASE=GP100GL [Tesla P100 SMX2 16GB]
pci:v000010DEd00001617*
ID_MODEL_FROM_DATABASE=GM204M [GeForce GTX 980M]
@@ -31622,11 +31748,14 @@ pci:v000010DEd00001B82*
pci:v000010DEd00001B83*
ID_MODEL_FROM_DATABASE=GP104
+pci:v000010DEd00001B84*
+ ID_MODEL_FROM_DATABASE=GP104 [GeForce GTX 1060 3GB]
+
pci:v000010DEd00001BA0*
- ID_MODEL_FROM_DATABASE=GP104M [GeForce GTX 1080]
+ ID_MODEL_FROM_DATABASE=GP104M [GeForce GTX 1080 Mobile]
pci:v000010DEd00001BA1*
- ID_MODEL_FROM_DATABASE=GP104M [GeForce GTX 1070]
+ ID_MODEL_FROM_DATABASE=GP104M [GeForce GTX 1070 Mobile]
pci:v000010DEd00001BB0*
ID_MODEL_FROM_DATABASE=GP104GL [Quadro P5000]
@@ -31634,14 +31763,26 @@ pci:v000010DEd00001BB0*
pci:v000010DEd00001BB1*
ID_MODEL_FROM_DATABASE=GP104GL
+pci:v000010DEd00001BB3*
+ ID_MODEL_FROM_DATABASE=GP104GL [Tesla P4]
+
pci:v000010DEd00001BB4*
ID_MODEL_FROM_DATABASE=GP104GL
+pci:v000010DEd00001BB6*
+ ID_MODEL_FROM_DATABASE=GP104GLM [Quadro P5000 Mobile]
+
+pci:v000010DEd00001BB7*
+ ID_MODEL_FROM_DATABASE=GP104GLM [Quadro P4000 Mobile]
+
+pci:v000010DEd00001BB8*
+ ID_MODEL_FROM_DATABASE=GP104GLM [Quadro P3000 Mobile]
+
pci:v000010DEd00001BE0*
- ID_MODEL_FROM_DATABASE=GP104M [GeForce GTX 1080]
+ ID_MODEL_FROM_DATABASE=GP104M [GeForce GTX 1080 Mobile]
pci:v000010DEd00001BE1*
- ID_MODEL_FROM_DATABASE=GP104M [GeForce GTX 1070]
+ ID_MODEL_FROM_DATABASE=GP104M [GeForce GTX 1070 Mobile]
pci:v000010DEd00001C00*
ID_MODEL_FROM_DATABASE=GP106
@@ -31656,7 +31797,7 @@ pci:v000010DEd00001C03*
ID_MODEL_FROM_DATABASE=GP106 [GeForce GTX 1060 6GB]
pci:v000010DEd00001C20*
- ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1060]
+ ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1060 Mobile]
pci:v000010DEd00001C30*
ID_MODEL_FROM_DATABASE=GP106GL
@@ -31665,7 +31806,7 @@ pci:v000010DEd00001C35*
ID_MODEL_FROM_DATABASE=GP106
pci:v000010DEd00001C60*
- ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1060]
+ ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1060 Mobile]
pci:v000010DEd00001C70*
ID_MODEL_FROM_DATABASE=GP106GL
@@ -31679,6 +31820,15 @@ pci:v000010DEd00001C81*
pci:v000010DEd00001C82*
ID_MODEL_FROM_DATABASE=GP107 [GeForce GTX 1050 Ti]
+pci:v000010DEd00001C8C*
+ ID_MODEL_FROM_DATABASE=GP107M [GeForce GTX 1050 Ti Mobile]
+
+pci:v000010DEd00001C8D*
+ ID_MODEL_FROM_DATABASE=GP107M [GeForce GTX 1050 Mobile]
+
+pci:v000010DEd00001C8E*
+ ID_MODEL_FROM_DATABASE=GP107M
+
pci:v000010DEd00001CA7*
ID_MODEL_FROM_DATABASE=GP107GL
@@ -35886,7 +36036,16 @@ pci:v0000111Fd00005243*
ID_MODEL_FROM_DATABASE=Frame capture bus interface
pci:v00001120*
- ID_VENDOR_FROM_DATABASE=EMC Corporation
+ ID_VENDOR_FROM_DATABASE=Dell EMC
+
+pci:v00001120d00002306*
+ ID_MODEL_FROM_DATABASE=Unity Fibre Channel Controller
+
+pci:v00001120d00002501*
+ ID_MODEL_FROM_DATABASE=Unity Ethernet Controller
+
+pci:v00001120d00002505*
+ ID_MODEL_FROM_DATABASE=Unity Fibre Channel Controller
pci:v00001121*
ID_VENDOR_FROM_DATABASE=Zilog
@@ -39152,6 +39311,9 @@ pci:v0000119Ed00000003*
pci:v0000119F*
ID_VENDOR_FROM_DATABASE=Bull HN Information Systems
+pci:v0000119Fd00001081*
+ ID_MODEL_FROM_DATABASE=BXI Host Channel Adapter
+
pci:v000011A0*
ID_VENDOR_FROM_DATABASE=Convex Computer Corporation
@@ -40742,6 +40904,9 @@ pci:v000011F8d00007384*
pci:v000011F8d00008000*
ID_MODEL_FROM_DATABASE=PM8000 [SPC - SAS Protocol Controller]
+pci:v000011F8d00008009*
+ ID_MODEL_FROM_DATABASE=PM8009 SPCve 8x6G
+
pci:v000011F8d00008032*
ID_MODEL_FROM_DATABASE=ATTO Celerity FC8xEN
@@ -40781,6 +40946,12 @@ pci:v000011F8d00008072*
pci:v000011F8d00008073*
ID_MODEL_FROM_DATABASE=PM8073 Tachyon SPCve 12G 16-port SAS/SATA controller
+pci:v000011F8d00008531*
+ ID_MODEL_FROM_DATABASE=PM8531 PFX 24xG3 Fanout PCIe Switches
+
+pci:v000011F8d00008546*
+ ID_MODEL_FROM_DATABASE=PM8546 B-FEIP PSX 96xG3 PCIe Storage Switch
+
pci:v000011F9*
ID_VENDOR_FROM_DATABASE=I-Cube Inc
@@ -47379,7 +47550,7 @@ pci:v00001425d00005083*
ID_MODEL_FROM_DATABASE=T540-5083 Unified Wire Ethernet Controller
pci:v00001425d00005084*
- ID_MODEL_FROM_DATABASE=T580-5084 Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T540-5084 Unified Wire Ethernet Controller
pci:v00001425d00005085*
ID_MODEL_FROM_DATABASE=T580-5085 Unified Wire Ethernet Controller
@@ -47435,6 +47606,18 @@ pci:v00001425d0000509B*
pci:v00001425d0000509C*
ID_MODEL_FROM_DATABASE=T520-509C Unified Wire Ethernet Controller
+pci:v00001425d0000509D*
+ ID_MODEL_FROM_DATABASE=T540-509D Unified Wire Ethernet Controller
+
+pci:v00001425d0000509E*
+ ID_MODEL_FROM_DATABASE=T520-509E Unified Wire Ethernet Controller
+
+pci:v00001425d0000509F*
+ ID_MODEL_FROM_DATABASE=T540-509F Unified Wire Ethernet Controller
+
+pci:v00001425d000050A0*
+ ID_MODEL_FROM_DATABASE=T540-50A0 Unified Wire Ethernet Controller
+
pci:v00001425d00005401*
ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller
@@ -47520,7 +47703,7 @@ pci:v00001425d00005483*
ID_MODEL_FROM_DATABASE=T540-5083 Unified Wire Ethernet Controller
pci:v00001425d00005484*
- ID_MODEL_FROM_DATABASE=T580-5084 Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T540-5084 Unified Wire Ethernet Controller
pci:v00001425d00005485*
ID_MODEL_FROM_DATABASE=T580-5085 Unified Wire Ethernet Controller
@@ -47576,6 +47759,18 @@ pci:v00001425d0000549B*
pci:v00001425d0000549C*
ID_MODEL_FROM_DATABASE=T520-509C Unified Wire Ethernet Controller
+pci:v00001425d0000549D*
+ ID_MODEL_FROM_DATABASE=T540-509D Unified Wire Ethernet Controller
+
+pci:v00001425d0000549E*
+ ID_MODEL_FROM_DATABASE=T520-509E Unified Wire Ethernet Controller
+
+pci:v00001425d0000549F*
+ ID_MODEL_FROM_DATABASE=T540-509F Unified Wire Ethernet Controller
+
+pci:v00001425d000054A0*
+ ID_MODEL_FROM_DATABASE=T540-50A0 Unified Wire Ethernet Controller
+
pci:v00001425d00005501*
ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Storage Controller
@@ -47661,7 +47856,7 @@ pci:v00001425d00005583*
ID_MODEL_FROM_DATABASE=T540-5083 Unified Wire Storage Controller
pci:v00001425d00005584*
- ID_MODEL_FROM_DATABASE=T580-5084 Unified Wire Storage Controller
+ ID_MODEL_FROM_DATABASE=T540-5084 Unified Wire Storage Controller
pci:v00001425d00005585*
ID_MODEL_FROM_DATABASE=T580-5085 Unified Wire Storage Controller
@@ -47717,6 +47912,18 @@ pci:v00001425d0000559B*
pci:v00001425d0000559C*
ID_MODEL_FROM_DATABASE=T520-509C Unified Wire Storage Controller
+pci:v00001425d0000559D*
+ ID_MODEL_FROM_DATABASE=T540-509D Unified Wire Storage Controller
+
+pci:v00001425d0000559E*
+ ID_MODEL_FROM_DATABASE=T520-509E Unified Wire Storage Controller
+
+pci:v00001425d0000559F*
+ ID_MODEL_FROM_DATABASE=T540-509F Unified Wire Storage Controller
+
+pci:v00001425d000055A0*
+ ID_MODEL_FROM_DATABASE=T540-50A0 Unified Wire Storage Controller
+
pci:v00001425d00005601*
ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Storage Controller
@@ -47802,7 +48009,7 @@ pci:v00001425d00005683*
ID_MODEL_FROM_DATABASE=T540-5083 Unified Wire Storage Controller
pci:v00001425d00005684*
- ID_MODEL_FROM_DATABASE=T580-5084 Unified Wire Storage Controller
+ ID_MODEL_FROM_DATABASE=T540-5084 Unified Wire Storage Controller
pci:v00001425d00005685*
ID_MODEL_FROM_DATABASE=T580-5085 Unified Wire Storage Controller
@@ -47858,6 +48065,18 @@ pci:v00001425d0000569B*
pci:v00001425d0000569C*
ID_MODEL_FROM_DATABASE=T520-509C Unified Wire Storage Controller
+pci:v00001425d0000569D*
+ ID_MODEL_FROM_DATABASE=T540-509D Unified Wire Storage Controller
+
+pci:v00001425d0000569E*
+ ID_MODEL_FROM_DATABASE=T520-509E Unified Wire Storage Controller
+
+pci:v00001425d0000569F*
+ ID_MODEL_FROM_DATABASE=T540-509F Unified Wire Storage Controller
+
+pci:v00001425d000056A0*
+ ID_MODEL_FROM_DATABASE=T540-50A0 Unified Wire Storage Controller
+
pci:v00001425d00005701*
ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller
@@ -48060,7 +48279,7 @@ pci:v00001425d00005883*
ID_MODEL_FROM_DATABASE=T540-5083 Unified Wire Ethernet Controller [VF]
pci:v00001425d00005884*
- ID_MODEL_FROM_DATABASE=T580-5084 Unified Wire Ethernet Controller [VF]
+ ID_MODEL_FROM_DATABASE=T540-5084 Unified Wire Ethernet Controller [VF]
pci:v00001425d00005885*
ID_MODEL_FROM_DATABASE=T580-5085 Unified Wire Ethernet Controller [VF]
@@ -48116,6 +48335,18 @@ pci:v00001425d0000589B*
pci:v00001425d0000589C*
ID_MODEL_FROM_DATABASE=T520-509C Unified Wire Ethernet Controller [VF]
+pci:v00001425d0000589D*
+ ID_MODEL_FROM_DATABASE=T540-509D Unified Wire Ethernet Controller [VF]
+
+pci:v00001425d0000589E*
+ ID_MODEL_FROM_DATABASE=T520-509E Unified Wire Ethernet Controller [VF]
+
+pci:v00001425d0000589F*
+ ID_MODEL_FROM_DATABASE=T540-509F Unified Wire Ethernet Controller [VF]
+
+pci:v00001425d000058A0*
+ ID_MODEL_FROM_DATABASE=T540-50A0 Unified Wire Ethernet Controller [VF]
+
pci:v00001425d00006001*
ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Ethernet Controller
@@ -48155,6 +48386,12 @@ pci:v00001425d00006014*
pci:v00001425d00006015*
ID_MODEL_FROM_DATABASE=T6201-BT Unified Wire Ethernet Controller
+pci:v00001425d00006080*
+ ID_MODEL_FROM_DATABASE=T6225-6080 Unified Wire Ethernet Controller
+
+pci:v00001425d00006081*
+ ID_MODEL_FROM_DATABASE=T62100-6081 Unified Wire Ethernet Controller
+
pci:v00001425d00006401*
ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Ethernet Controller
@@ -48194,6 +48431,12 @@ pci:v00001425d00006414*
pci:v00001425d00006415*
ID_MODEL_FROM_DATABASE=T6201-BT Unified Wire Ethernet Controller
+pci:v00001425d00006480*
+ ID_MODEL_FROM_DATABASE=T6225-6080 Unified Wire Ethernet Controller
+
+pci:v00001425d00006481*
+ ID_MODEL_FROM_DATABASE=T62100-6081 Unified Wire Ethernet Controller
+
pci:v00001425d00006501*
ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Storage Controller
@@ -48233,6 +48476,12 @@ pci:v00001425d00006514*
pci:v00001425d00006515*
ID_MODEL_FROM_DATABASE=T6201-BT Unified Wire Storage Controller
+pci:v00001425d00006580*
+ ID_MODEL_FROM_DATABASE=T6225-6080 Unified Wire Storage Controller
+
+pci:v00001425d00006581*
+ ID_MODEL_FROM_DATABASE=T62100-6081 Unified Wire Storage Controller
+
pci:v00001425d00006601*
ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Storage Controller
@@ -48272,6 +48521,12 @@ pci:v00001425d00006614*
pci:v00001425d00006615*
ID_MODEL_FROM_DATABASE=T6201-BT Unified Wire Storage Controller
+pci:v00001425d00006680*
+ ID_MODEL_FROM_DATABASE=T6225-6080 Unified Wire Storage Controller
+
+pci:v00001425d00006681*
+ ID_MODEL_FROM_DATABASE=T62100-6081 Unified Wire Storage Controller
+
pci:v00001425d00006801*
ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Ethernet Controller [VF]
@@ -48311,6 +48566,12 @@ pci:v00001425d00006814*
pci:v00001425d00006815*
ID_MODEL_FROM_DATABASE=T6201-BT Unified Wire Ethernet Controller [VF]
+pci:v00001425d00006880*
+ ID_MODEL_FROM_DATABASE=T6225-6080 Unified Wire Ethernet Controller [VF]
+
+pci:v00001425d00006881*
+ ID_MODEL_FROM_DATABASE=T62100-6081 Unified Wire Ethernet Controller [VF]
+
pci:v00001425d0000A000*
ID_MODEL_FROM_DATABASE=PE10K Unified Wire Ethernet Controller
@@ -48516,7 +48777,10 @@ pci:v0000144Dd0000A800*
ID_MODEL_FROM_DATABASE=XP941 PCIe SSD
pci:v0000144Dd0000A802*
- ID_MODEL_FROM_DATABASE=NVMe SSD Controller
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller SM951/PM951
+
+pci:v0000144Dd0000A804*
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller SM961/PM961
pci:v0000144Dd0000A820*
ID_MODEL_FROM_DATABASE=NVMe SSD Controller 171X
@@ -48890,6 +49154,9 @@ pci:v000014A3*
pci:v000014A4*
ID_VENDOR_FROM_DATABASE=Lite-On Technology Corporation
+pci:v000014A4d000022F1*
+ ID_MODEL_FROM_DATABASE=M8Pe Series NVMe SSD
+
pci:v000014A4d00004318*
ID_MODEL_FROM_DATABASE=Broadcom BCM4318 [AirForce One 54g] 802.11g WLAN Controller
@@ -50396,6 +50663,9 @@ pci:v000014E4d000016BE*
pci:v000014E4d000016BF*
ID_MODEL_FROM_DATABASE=BCM57765/57785 xD-Picture Card Reader
+pci:v000014E4d000016C1*
+ ID_MODEL_FROM_DATABASE=NetXtreme-E RDMA Virtual Function
+
pci:v000014E4d000016C6*
ID_MODEL_FROM_DATABASE=NetXtreme BCM5702A3 Gigabit Ethernet
@@ -50534,9 +50804,15 @@ pci:v000014E4d000016E9*
pci:v000014E4d000016EC*
ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E Ethernet Partition
+pci:v000014E4d000016ED*
+ ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E RDMA Partition
+
pci:v000014E4d000016EE*
ID_MODEL_FROM_DATABASE=BCM57416 NetXtreme-E Ethernet Partition
+pci:v000014E4d000016EF*
+ ID_MODEL_FROM_DATABASE=BCM57416 NetXtreme-E RDMA Partition
+
pci:v000014E4d000016F3*
ID_MODEL_FROM_DATABASE=NetXtreme BCM5727 Gigabit Ethernet PCIe
@@ -53156,6 +53432,9 @@ pci:v0000159A*
pci:v0000159B*
ID_VENDOR_FROM_DATABASE=Faraday Technology Corp
+pci:v0000159Bd00004321*
+ ID_MODEL_FROM_DATABASE=StorLink SL3516 (Gemini) Host Bridge
+
pci:v0000159C*
ID_VENDOR_FROM_DATABASE=Stratus Computer Systems
@@ -53285,6 +53564,9 @@ pci:v000015B3d00000191*
pci:v000015B3d000001F6*
ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3 Flash Recovery]
+pci:v000015B3d000001F8*
+ ID_MODEL_FROM_DATABASE=MT27520 Family [ConnectX-3 Pro Flash Recovery]
+
pci:v000015B3d000001FF*
ID_MODEL_FROM_DATABASE=MT27600 Family [Connect-IB Flash Recovery]
@@ -53297,6 +53579,12 @@ pci:v000015B3d0000020B*
pci:v000015B3d0000020D*
ID_MODEL_FROM_DATABASE=MT28800 Family [ConnectX-5 Flash Recovery]
+pci:v000015B3d0000020F*
+ ID_MODEL_FROM_DATABASE=MT28908A0 Family [ConnectX-6 Flash Recovery]
+
+pci:v000015B3d00000211*
+ ID_MODEL_FROM_DATABASE=MT416842 Family [BlueField SoC Flash Recovery]
+
pci:v000015B3d0000024E*
ID_MODEL_FROM_DATABASE=MT53100 [Spectrum-2, Flash recovery mode]
@@ -53309,6 +53597,9 @@ pci:v000015B3d00000262*
pci:v000015B3d00000263*
ID_MODEL_FROM_DATABASE=MT27710 [ConnectX-4 Lx Programmable Virtual Function] EN
+pci:v000015B3d00000281*
+ ID_MODEL_FROM_DATABASE=NPS-600 Flash Recovery
+
pci:v000015B3d00001002*
ID_MODEL_FROM_DATABASE=MT25400 Family [ConnectX-2 Virtual Function]
@@ -53421,10 +53712,10 @@ pci:v000015B3d0000101A*
ID_MODEL_FROM_DATABASE=MT28800 Family [ConnectX-5 Ex Virtual Function]
pci:v000015B3d0000101B*
- ID_MODEL_FROM_DATABASE=MT28831
+ ID_MODEL_FROM_DATABASE=MT28908 Family [ConnectX-6]
pci:v000015B3d0000101C*
- ID_MODEL_FROM_DATABASE=MT28840
+ ID_MODEL_FROM_DATABASE=MT28908 Family [ConnectX-6 Virtual Function]
pci:v000015B3d0000101D*
ID_MODEL_FROM_DATABASE=MT28841
@@ -53553,10 +53844,10 @@ pci:v000015B3d00007123*
ID_MODEL_FROM_DATABASE=NPS-600 network interface VF
pci:v000015B3d0000A2D0*
- ID_MODEL_FROM_DATABASE=MT416842
+ ID_MODEL_FROM_DATABASE=MT416842 BlueField SoC Crypto enabled
pci:v000015B3d0000A2D1*
- ID_MODEL_FROM_DATABASE=MT416842
+ ID_MODEL_FROM_DATABASE=MT416842 BlueField SoC Crypto disabled
pci:v000015B3d0000A2D3*
ID_MODEL_FROM_DATABASE=MT416842 BlueField multicore SoC family VF
@@ -55523,6 +55814,9 @@ pci:v000016D5d00007014*
pci:v000016D5d00007016*
ID_MODEL_FROM_DATABASE=AP470 48-Channel TTL Level Digital Input/Output Module
+pci:v000016D5d00007017*
+ ID_MODEL_FROM_DATABASE=AP323 16-bit, 20 or 40 Channel Analog Input Module
+
pci:v000016D5d00007018*
ID_MODEL_FROM_DATABASE=AP408: 32-Channel Digital I/O Module
@@ -55830,6 +56124,15 @@ pci:v0000177Dd00009702sv0000177Dsd00000003*
ID_MODEL_FROM_DATABASE=CN23XX [LiquidIO II] Intelligent Adapter (CN2350 [LiquidIO II] 2-port 10GbE Intelligent adapter)
pci:v0000177Dd00009702sv0000177Dsd00000004*
+ ID_MODEL_FROM_DATABASE=CN23XX [LiquidIO II] Intelligent Adapter (CN2350 [LiquidIO II] 2-port 10GbE Intelligent adapter)
+
+pci:v0000177Dd00009702sv0000177Dsd00000005*
+ ID_MODEL_FROM_DATABASE=CN23XX [LiquidIO II] Intelligent Adapter (CN2360 [LiquidIO II] 2-port 10GbE Intelligent adapter)
+
+pci:v0000177Dd00009702sv0000177Dsd00000006*
+ ID_MODEL_FROM_DATABASE=CN23XX [LiquidIO II] Intelligent Adapter (CN2360 [LiquidIO II] 2-port 25GbE Intelligent adapter)
+
+pci:v0000177Dd00009702sv0000177Dsd00000007*
ID_MODEL_FROM_DATABASE=CN23XX [LiquidIO II] Intelligent Adapter (CN2350 [LiquidIO II] 2-port 25GbE Intelligent adapter)
pci:v0000177Dd00009703*
@@ -55841,6 +56144,18 @@ pci:v0000177Dd00009712*
pci:v0000177Dd00009712sv0000177Dsd00000003*
ID_MODEL_FROM_DATABASE=CN23XX [LiquidIO II] SRIOV Virtual Function (CN2350 [LiquidIO II] 2-port 10GbE SRIOV Virtual Function)
+pci:v0000177Dd00009712sv0000177Dsd00000004*
+ ID_MODEL_FROM_DATABASE=CN23XX [LiquidIO II] SRIOV Virtual Function (CN2350 [LiquidIO II] 2-port 10GbE SRIOV Virtual Function)
+
+pci:v0000177Dd00009712sv0000177Dsd00000005*
+ ID_MODEL_FROM_DATABASE=CN23XX [LiquidIO II] SRIOV Virtual Function (CN2360 [LiquidIO II] 2-port 10GbE SRIOV Virtual Function)
+
+pci:v0000177Dd00009712sv0000177Dsd00000006*
+ ID_MODEL_FROM_DATABASE=CN23XX [LiquidIO II] SRIOV Virtual Function (CN2360 [LiquidIO II] 2-port 25GbE SRIOV Virtual Function)
+
+pci:v0000177Dd00009712sv0000177Dsd00000007*
+ ID_MODEL_FROM_DATABASE=CN23XX [LiquidIO II] SRIOV Virtual Function (CN2350 [LiquidIO II] 2-port 25GbE SRIOV Virtual Function)
+
pci:v0000177Dd00009713*
ID_MODEL_FROM_DATABASE=CN23XX [LiquidIO II] NVMe SRIOV Virtual Function
@@ -56267,6 +56582,9 @@ pci:v000017D3d00001170*
pci:v000017D3d00001201*
ID_MODEL_FROM_DATABASE=ARC-1200 2-Port PCI-Express to SATA II RAID Controller
+pci:v000017D3d00001203*
+ ID_MODEL_FROM_DATABASE=ARC-1203 2/4/8 Port PCIe 2.0 to SATA 6Gb RAID Controller
+
pci:v000017D3d00001210*
ID_MODEL_FROM_DATABASE=ARC-1210 4-Port PCI-Express to SATA RAID Controller
@@ -57206,7 +57524,7 @@ pci:v000018C3*
pci:v000018C3d00000720*
ID_MODEL_FROM_DATABASE=nGene PCI-Express Multimedia Controller
-pci:v000018C3d00000720sv000007CAsd0000032E*
+pci:v000018C3d00000720sv00001461sd0000032E*
ID_MODEL_FROM_DATABASE=nGene PCI-Express Multimedia Controller (Hybrid M779 PCI-E)
pci:v000018C8*
@@ -57488,6 +57806,12 @@ pci:v000018F4d00000165*
pci:v000018F4d00000175*
ID_MODEL_FROM_DATABASE=NT20E3-2-PTP Network Adapter 2x10Gb
+pci:v000018F4d00000185*
+ ID_MODEL_FROM_DATABASE=NT40A01 Network Adapter
+
+pci:v000018F4d000001A5*
+ ID_MODEL_FROM_DATABASE=NT200A01 Network Adapter
+
pci:v000018F6*
ID_VENDOR_FROM_DATABASE=NextIO
@@ -57753,208 +58077,214 @@ pci:v00001924d00000710sv00001924sd00005202*
ID_MODEL_FROM_DATABASE=SFC4000 rev B [Solarstorm] (SFN4112F-R2)
pci:v00001924d00000803*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm]
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller
pci:v00001924d00000803sv00001014sd00000478*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (2-port 10GbE Low-Latency (R7))
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (2-port 10GbE Low-Latency (R7))
pci:v00001924d00000803sv00001014sd00000479*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (2-port 10GbE OpenOnload (R7))
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (2-port 10GbE OpenOnload (R7))
pci:v00001924d00000803sv00001014sd000004A7*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (Solarflare 10Gb Low-latency Dual-port HBA (R7))
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (Solarflare 10Gb Low-latency Dual-port HBA (R7))
pci:v00001924d00000803sv00001014sd000004A8*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (Solarflare 10Gb Dual-port HBA (R7))
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (Solarflare 10Gb Dual-port HBA (R7))
pci:v00001924d00000803sv0000103Csd00002132*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (Ethernet 10Gb 2-port 570FLR-SFP+ Adapter (R1))
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (Ethernet 10Gb 2-port 570FLR-SFP+ Adapter (R1))
pci:v00001924d00000803sv0000103Csd00002136*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (Ethernet 10Gb 2-port 570SFP+ Adapter (R7))
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (Ethernet 10Gb 2-port 570SFP+ Adapter (R7))
pci:v00001924d00000803sv00001924sd00001201*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFA6902F-R1 SFP+ AOE Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFA6902F-R1 SFP+ AOE Adapter)
pci:v00001924d00000803sv00001924sd00006200*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5122F-R0 SFP+ Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFN5122F-R0 SFP+ Server Adapter)
pci:v00001924d00000803sv00001924sd00006201*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5122F-R1 SFP+ Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFN5122F-R1 SFP+ Server Adapter)
pci:v00001924d00000803sv00001924sd00006202*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5122F-R2 SFP+ Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFN5122F-R2 SFP+ Server Adapter)
pci:v00001924d00000803sv00001924sd00006204*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5122F-R4 SFP+ Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFN5122F-R4 SFP+ Server Adapter)
pci:v00001924d00000803sv00001924sd00006205*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5122F-R5 SFP+ Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFN5122F-R5 SFP+ Server Adapter)
pci:v00001924d00000803sv00001924sd00006206*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5122F-R6 SFP+ Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFN5122F-R6 SFP+ Server Adapter)
pci:v00001924d00000803sv00001924sd00006207*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5122F-R7 SFP+ Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFN5122F-R7 SFP+ Server Adapter)
pci:v00001924d00000803sv00001924sd00006210*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5322F-R0 SFP+ Precision Time Synchronization Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFN5322F-R0 SFP+ Precision Time Synchronization Server Adapter)
pci:v00001924d00000803sv00001924sd00006211*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5322F-R1 SFP+ Precision Time Synchronization Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFN5322F-R1 SFP+ Precision Time Synchronization Server Adapter)
pci:v00001924d00000803sv00001924sd00006217*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5322F-R7 SFP+ Precision Time Synchronization Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFN5322F-R7 SFP+ Precision Time Synchronization Server Adapter)
pci:v00001924d00000803sv00001924sd00006227*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN6122F-R7 SFP+ Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFN6122F-R7 SFP+ Server Adapter)
pci:v00001924d00000803sv00001924sd00006237*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN6322F-R7 SFP+ Precision Time Synchronization Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFN6322F-R7 SFP+ Precision Time Synchronization Server Adapter)
pci:v00001924d00000803sv00001924sd00006501*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5802K-R1 Mezzanine Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFN5802K-R1 Mezzanine Adapter)
pci:v00001924d00000803sv00001924sd00006511*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5814H-R1 Mezzanine Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFN5814H-R1 Mezzanine Adapter)
pci:v00001924d00000803sv00001924sd00006521*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5812H-R1 Mezzanine Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFN5812H-R1 Mezzanine Adapter)
pci:v00001924d00000803sv00001924sd00006562*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN6832F-R2 SFP+ Mezzanine Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFN6832F-R2 SFP+ Mezzanine Adapter)
pci:v00001924d00000803sv00001924sd00006A05*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5112F-R5 SFP+ Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFN5112F-R5 SFP+ Server Adapter)
pci:v00001924d00000803sv00001924sd00006A06*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5112F-R6 SFP+ Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFN5112F-R6 SFP+ Server Adapter)
pci:v00001924d00000803sv00001924sd00007206*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5162F-R6 SFP+ Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFN5162F-R6 SFP+ Server Adapter)
pci:v00001924d00000803sv00001924sd00007207*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5162F-R7 SFP+ Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFN5162F-R7 SFP+ Server Adapter)
pci:v00001924d00000803sv00001924sd00007A06*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5152F-R6 SFP+ Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFN5152F-R6 SFP+ Server Adapter)
pci:v00001924d00000803sv00001924sd00007A07*
- ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5152F-R7 SFP+ Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (SFN5152F-R7 SFP+ Server Adapter)
pci:v00001924d00000813*
- ID_MODEL_FROM_DATABASE=SFL9021 [Solarstorm]
+ ID_MODEL_FROM_DATABASE=SFL9021 10GBASE-T Ethernet Controller
pci:v00001924d00000813sv00001924sd00006100*
- ID_MODEL_FROM_DATABASE=SFL9021 [Solarstorm] (SFN5121T-R0 10GBASE-T Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFL9021 10GBASE-T Ethernet Controller (SFN5121T-R0 10GBASE-T Server Adapter)
pci:v00001924d00000813sv00001924sd00006102*
- ID_MODEL_FROM_DATABASE=SFL9021 [Solarstorm] (SFN5121T-R2 10GBASE-T Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFL9021 10GBASE-T Ethernet Controller (SFN5121T-R2 10GBASE-T Server Adapter)
pci:v00001924d00000813sv00001924sd00006103*
- ID_MODEL_FROM_DATABASE=SFL9021 [Solarstorm] (SFN5121T-R3 10GBASE-T Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFL9021 10GBASE-T Ethernet Controller (SFN5121T-R3 10GBASE-T Server Adapter)
pci:v00001924d00000813sv00001924sd00006104*
- ID_MODEL_FROM_DATABASE=SFL9021 [Solarstorm] (SFN5121T-R4 10GBASE-T Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFL9021 10GBASE-T Ethernet Controller (SFN5121T-R4 10GBASE-T Server Adapter)
pci:v00001924d00000813sv00001924sd00006902*
- ID_MODEL_FROM_DATABASE=SFL9021 [Solarstorm] (SFN5111T-R2 10GBASE-T Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFL9021 10GBASE-T Ethernet Controller (SFN5111T-R2 10GBASE-T Server Adapter)
pci:v00001924d00000813sv00001924sd00006904*
- ID_MODEL_FROM_DATABASE=SFL9021 [Solarstorm] (SFN5111T-R4 10GBASE-T Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFL9021 10GBASE-T Ethernet Controller (SFN5111T-R4 10GBASE-T Server Adapter)
pci:v00001924d00000813sv00001924sd00007104*
- ID_MODEL_FROM_DATABASE=SFL9021 [Solarstorm] (SFN5161T-R4 10GBASE-T Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFL9021 10GBASE-T Ethernet Controller (SFN5161T-R4 10GBASE-T Server Adapter)
pci:v00001924d00000813sv00001924sd00007904*
- ID_MODEL_FROM_DATABASE=SFL9021 [Solarstorm] (SFN5151T-R4 10GBASE-T Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFL9021 10GBASE-T Ethernet Controller (SFN5151T-R4 10GBASE-T Server Adapter)
pci:v00001924d00000903*
- ID_MODEL_FROM_DATABASE=SFC9120
+ ID_MODEL_FROM_DATABASE=SFC9120 10G Ethernet Controller
pci:v00001924d00000903sv00001014sd000004CC*
- ID_MODEL_FROM_DATABASE=SFC9120 (SFN7122F-R2 2x10GbE SFP+ Flareon Ultra)
+ ID_MODEL_FROM_DATABASE=SFC9120 10G Ethernet Controller (SFN7122F-R2 2x10GbE SFP+ Flareon Ultra)
pci:v00001924d00000903sv00001924sd00008002*
- ID_MODEL_FROM_DATABASE=SFC9120 (SFN7122F-R1 SFP+ Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9120 10G Ethernet Controller (SFN7122F-R1 SFP+ Server Adapter)
pci:v00001924d00000903sv00001924sd00008003*
- ID_MODEL_FROM_DATABASE=SFC9120 (SFN7x41Q-R1 Flareon Ultra 7000 Series 10/40G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9120 10G Ethernet Controller (SFN7x41Q-R1 Flareon Ultra 7000 Series 10/40G Adapter)
pci:v00001924d00000903sv00001924sd00008006*
- ID_MODEL_FROM_DATABASE=SFC9120 (SFN7022F-R1 SFP+ Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9120 10G Ethernet Controller (SFN7022F-R1 SFP+ Server Adapter)
pci:v00001924d00000903sv00001924sd00008007*
- ID_MODEL_FROM_DATABASE=SFC9120 (SFN7322F-R2 Precision Time SFP+ Server Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9120 10G Ethernet Controller (SFN7322F-R2 Precision Time SFP+ Server Adapter)
pci:v00001924d00000903sv00001924sd00008009*
- ID_MODEL_FROM_DATABASE=SFC9120 (SFN7x22F-R2 Flareon Ultra 7000 Series 10G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9120 10G Ethernet Controller (SFN7x22F-R2 Flareon Ultra 7000 Series 10G Adapter)
pci:v00001924d00000903sv00001924sd0000800A*
- ID_MODEL_FROM_DATABASE=SFC9120 (SFN7x02F-R2 Flareon 7000 Series 10G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9120 10G Ethernet Controller (SFN7x02F-R2 Flareon 7000 Series 10G Adapter)
pci:v00001924d00000903sv00001924sd0000800C*
- ID_MODEL_FROM_DATABASE=SFC9120 (SFN7x22F-R3 Flareon Ultra 7000 Series 10G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9120 10G Ethernet Controller (SFN7x22F-R3 Flareon Ultra 7000 Series 10G Adapter)
pci:v00001924d00000903sv00001924sd0000800D*
- ID_MODEL_FROM_DATABASE=SFC9120 (SFN7x02F-R3 Flareon 7000 Series 10G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9120 10G Ethernet Controller (SFN7x02F-R3 Flareon 7000 Series 10G Adapter)
pci:v00001924d00000903sv00001924sd00008010*
- ID_MODEL_FROM_DATABASE=SFC9120 (SFA7942Q-R1 QSFP+ AOE Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9120 10G Ethernet Controller (SFA7942Q-R1 QSFP+ AOE Adapter)
pci:v00001924d00000903sv00001924sd00008015*
- ID_MODEL_FROM_DATABASE=SFC9120 (SFA7942Q-A5-0-R1 QSFP+ AOE Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9120 10G Ethernet Controller (SFA7942Q-A5-0-R1 QSFP+ AOE Adapter)
pci:v00001924d00000923*
- ID_MODEL_FROM_DATABASE=SFC9140
+ ID_MODEL_FROM_DATABASE=SFC9140 10/40G Ethernet Controller
pci:v00001924d00000923sv00001924sd0000800B*
- ID_MODEL_FROM_DATABASE=SFC9140 (SFN7x42Q-R1 Flareon Ultra 7000 Series 10/40G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9140 10/40G Ethernet Controller (SFN7x42Q-R1 Flareon Ultra 7000 Series 10/40G Adapter)
pci:v00001924d00000923sv00001924sd0000800E*
- ID_MODEL_FROM_DATABASE=SFC9140 (SFN7x42Q-R2 Flareon Ultra 7000 Series 10/40G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9140 10/40G Ethernet Controller (SFN7x42Q-R2 Flareon Ultra 7000 Series 10/40G Adapter)
pci:v00001924d00000923sv00001924sd0000800F*
- ID_MODEL_FROM_DATABASE=SFC9140 (SFN7xx4F-R1 Flareon Ultra 7000 Series 10G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9140 10/40G Ethernet Controller (SFN7xx4F-R1 Flareon Ultra 7000 Series 10G Adapter)
pci:v00001924d00000A03*
- ID_MODEL_FROM_DATABASE=SFC9220
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller
pci:v00001924d00000A03sv00001924sd00008011*
- ID_MODEL_FROM_DATABASE=SFC9220 (SFN 8022-R1 Solarflare Flareon 8000 Series 10G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8022-R1 Flareon 8000 Series 10G Adapter)
pci:v00001924d00000A03sv00001924sd00008012*
- ID_MODEL_FROM_DATABASE=SFC9220 (SFN8522-R1 Flareon Ultra 8000 Series 10G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8522-R1 Flareon Ultra 8000 Series 10G Adapter)
pci:v00001924d00000A03sv00001924sd00008013*
- ID_MODEL_FROM_DATABASE=SFC9220 (SFN8042-R1 Solarflare Flareon 8000 Series 10/40G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8042-R1 Flareon 8000 Series 10/40G Adapter)
pci:v00001924d00000A03sv00001924sd00008014*
- ID_MODEL_FROM_DATABASE=SFC9220 (SFN8542-R1 Flareon Ultra 8000 Series 10/40G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8542-R1 Flareon Ultra 8000 Series 10/40G Adapter)
pci:v00001924d00000A03sv00001924sd00008016*
- ID_MODEL_FROM_DATABASE=SFC9220 (SFN8022-R2 Flareon 8000 Series 10G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8022-R2 Flareon 8000 Series 10G Adapter)
pci:v00001924d00000A03sv00001924sd00008017*
- ID_MODEL_FROM_DATABASE=SFC9220 (SFN8522-R2 Flareon Ultra 8000 Series 10G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8522-R2 Flareon Ultra 8000 Series 10G Adapter)
pci:v00001924d00000A03sv00001924sd00008018*
- ID_MODEL_FROM_DATABASE=SFC9220 (SFN8042-R2 Flareon 8000 Series 10/40G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8042-R2 Flareon 8000 Series 10/40G Adapter)
pci:v00001924d00000A03sv00001924sd00008019*
- ID_MODEL_FROM_DATABASE=SFC9220 (SFN8542-R2 Flareon Ultra 8000 Series 10/40G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8542-R2 Flareon Ultra 8000 Series 10/40G Adapter)
+
+pci:v00001924d00000A03sv00001924sd0000801A*
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8722-R1 Flareon Ultra 8000 Series OCP 10G Adapter)
pci:v00001924d00001803*
- ID_MODEL_FROM_DATABASE=SFC9020 Virtual Function [Solarstorm]
+ ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (Virtual Function)
pci:v00001924d00001813*
- ID_MODEL_FROM_DATABASE=SFL9021 Virtual Function [Solarstorm]
+ ID_MODEL_FROM_DATABASE=SFL9021 10GBASE-T Ethernet Controller (Virtual Function)
pci:v00001924d00001903*
- ID_MODEL_FROM_DATABASE=SFC9120 Virtual Function
+ ID_MODEL_FROM_DATABASE=SFC9120 10G Ethernet Controller (Virtual Function)
pci:v00001924d00001923*
- ID_MODEL_FROM_DATABASE=SFC9140 Virtual Function
+ ID_MODEL_FROM_DATABASE=SFC9140 10/40G Ethernet Controller (Virtual Function)
+
+pci:v00001924d00001A03*
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (Virtual Function)
pci:v00001924d00006703*
ID_MODEL_FROM_DATABASE=SFC4000 rev A iSCSI/Onload [Solarstorm]
@@ -58793,6 +59123,12 @@ pci:v000019E3d00005808*
pci:v000019E3d0000DD52*
ID_MODEL_FROM_DATABASE=DDRdrive X1-30
+pci:v000019E5*
+ ID_VENDOR_FROM_DATABASE=Huawei Technologies Co., Ltd.
+
+pci:v000019E5d00001711*
+ ID_MODEL_FROM_DATABASE=Hi1710 [iBMC Intelligent Management system chip w/VGA support]
+
pci:v000019E7*
ID_VENDOR_FROM_DATABASE=NET (Network Equipment Technologies)
@@ -59352,7 +59688,7 @@ pci:v00001B03d00007000*
ID_MODEL_FROM_DATABASE=D7 Multiformat Broadcast HD/SD Encoder/Decoder/Transcoder
pci:v00001B08*
- ID_VENDOR_FROM_DATABASE=MSC Vertriebs GmbH
+ ID_VENDOR_FROM_DATABASE=MSC Technologies GmbH
pci:v00001B0A*
ID_VENDOR_FROM_DATABASE=Pegatron
@@ -59921,9 +60257,15 @@ pci:v00001C2Cd000000A6*
pci:v00001C2Cd000000A9*
ID_MODEL_FROM_DATABASE=FBC2XGHH Capture 2x10Gb
+pci:v00001C2Cd000000AD*
+ ID_MODEL_FROM_DATABASE=FBC2CGG3HL Capture 2x200Gb
+
pci:v00001C2Cd000000AF*
ID_MODEL_FROM_DATABASE=Capture slave device
+pci:v00001C2Cd0000A001*
+ ID_MODEL_FROM_DATABASE=FBC2CGG3 Capture 2x200Gb
+
pci:v00001C32*
ID_VENDOR_FROM_DATABASE=Highland Technology, Inc.
@@ -59957,6 +60299,12 @@ pci:v00001C58d00000003sv00001014sd000004F5*
pci:v00001C58d00000003sv00001014sd000004F6*
ID_MODEL_FROM_DATABASE=Ultrastar SN100 Series NVMe SSD (PCIe3 3.2TB NVMe Flash Adapter)
+pci:v00001C5F*
+ ID_VENDOR_FROM_DATABASE=Beijing Memblaze Technology Co. Ltd.
+
+pci:v00001C5Fd00000540*
+ ID_MODEL_FROM_DATABASE=PBlaze4 NVMe SSD
+
pci:v00001C63*
ID_VENDOR_FROM_DATABASE=Science and Research Centre of Computer Technology (JSC "NICEVT")
@@ -60020,6 +60368,12 @@ pci:v00001CD2d00000304*
pci:v00001CD2d00000305*
ID_MODEL_FROM_DATABASE=Simulyzer-RT CompactPCI Serial CAN-1 card
+pci:v00001CD7*
+ ID_VENDOR_FROM_DATABASE=Nanjing Magewell Electronics Co., Ltd.
+
+pci:v00001CD7d00000010*
+ ID_MODEL_FROM_DATABASE=Pro Capture Endpoint
+
pci:v00001CDD*
ID_VENDOR_FROM_DATABASE=secunet Security Networks AG
@@ -60041,6 +60395,9 @@ pci:v00001CE4d00000004*
pci:v00001CE4d00000005*
ID_MODEL_FROM_DATABASE=ExaNIC X40
+pci:v00001CE4d00000006*
+ ID_MODEL_FROM_DATABASE=ExaNIC X10-HPT
+
pci:v00001CF7*
ID_VENDOR_FROM_DATABASE=Subspace Dynamics
@@ -60143,15 +60500,24 @@ pci:v00001D6Cd0000100C*
pci:v00001D6Cd0000100D*
ID_MODEL_FROM_DATABASE=AR-ARKA-FX0 [Arkville 32B DPDK Data Mover]
+pci:v00001D6Cd0000100Dsv00001D6Csd00002001*
+ ID_MODEL_FROM_DATABASE=AR-ARKA-FX0 [Arkville 32B DPDK Data Mover] (DPDK-Aware Virtual Function [Arkville VF])
+
pci:v00001D6Cd0000100E*
ID_MODEL_FROM_DATABASE=AR-ARKA-FX1 [Arkville 64B DPDK Data Mover]
+pci:v00001D6Cd0000100Esv00001D6Csd00002001*
+ ID_MODEL_FROM_DATABASE=AR-ARKA-FX1 [Arkville 64B DPDK Data Mover] (DPDK-Aware Virtual Function [Arkville VF])
+
pci:v00001D6Cd00004200*
ID_MODEL_FROM_DATABASE=A5PL-E1-10GETI [10 GbE Ethernet Traffic Instrument]
pci:v00001D78*
ID_VENDOR_FROM_DATABASE=DERA
+pci:v00001D7C*
+ ID_VENDOR_FROM_DATABASE=Aerotech, Inc.
+
pci:v00001D8F*
ID_VENDOR_FROM_DATABASE=Enyx
@@ -60282,7 +60648,7 @@ pci:v00001FC9d00004022sv00001186sd00004D00*
ID_MODEL_FROM_DATABASE=TN9310 10GbE SFP+ Ethernet Adapter (DXE-810S 10GbE SFP+ Ethernet Adapter)
pci:v00001FC9d00004022sv00001432sd00008103*
- ID_MODEL_FROM_DATABASE=TN9310 10GbE SFP+ Ethernet Adapter (EN-8102PF 10GbE SPF+ Ethernet Adapter)
+ ID_MODEL_FROM_DATABASE=TN9310 10GbE SFP+ Ethernet Adapter (10 Gigabit Ethernet SFP+ PCI Express Adapter)
pci:v00001FC9d00004022sv00001FC9sd00003015*
ID_MODEL_FROM_DATABASE=TN9310 10GbE SFP+ Ethernet Adapter (Ethernet Adapter)
@@ -60300,7 +60666,7 @@ pci:v00001FC9d00004025sv00001186sd00002900*
ID_MODEL_FROM_DATABASE=TN9510 10GBase-T/NBASE-T Ethernet Adapter (DXE-810T 10GBase-T Ethernet Adapter)
pci:v00001FC9d00004025sv00001432sd00008102*
- ID_MODEL_FROM_DATABASE=TN9510 10GBase-T/NBASE-T Ethernet Adapter (EN-8102P 10GbE Ethernet Adapter)
+ ID_MODEL_FROM_DATABASE=TN9510 10GBase-T/NBASE-T Ethernet Adapter (10 Gigabit Ethernet PCI Express Adapter)
pci:v00001FC9d00004025sv00001FC9sd00003015*
ID_MODEL_FROM_DATABASE=TN9510 10GBase-T/NBASE-T Ethernet Adapter (Ethernet Adapter)
@@ -60311,6 +60677,12 @@ pci:v00001FC9d00004026*
pci:v00001FC9d00004027*
ID_MODEL_FROM_DATABASE=TN9710P 10GBase-T/NBASE-T Ethernet Adapter
+pci:v00001FC9d00004027sv00001432sd00008104*
+ ID_MODEL_FROM_DATABASE=TN9710P 10GBase-T/NBASE-T Ethernet Adapter (10 Gigabit Ethernet PCI Express Adapter)
+
+pci:v00001FC9d00004027sv00001FC9sd00003015*
+ ID_MODEL_FROM_DATABASE=TN9710P 10GBase-T/NBASE-T Ethernet Adapter (Ethernet Adapter)
+
pci:v00001FC9d00004527*
ID_MODEL_FROM_DATABASE=TN9710Q 5GBase-T/NBASE-T Ethernet Adapter
@@ -60404,6 +60776,9 @@ pci:v00003000*
pci:v00003112*
ID_VENDOR_FROM_DATABASE=Satelco Ingenieria S.A.
+pci:v00003130*
+ ID_VENDOR_FROM_DATABASE=AUDIOTRAK
+
pci:v00003142*
ID_VENDOR_FROM_DATABASE=Post Impression Systems.
@@ -63062,6 +63437,69 @@ pci:v00008086d00000814*
pci:v00008086d00000815*
ID_MODEL_FROM_DATABASE=Moorestown SSP0
+pci:v00008086d00000817*
+ ID_MODEL_FROM_DATABASE=Medfield Serial IO I2C Controller #3
+
+pci:v00008086d00000818*
+ ID_MODEL_FROM_DATABASE=Medfield Serial IO I2C Controller #4
+
+pci:v00008086d00000819*
+ ID_MODEL_FROM_DATABASE=Medfield Serial IO I2C Controller #5
+
+pci:v00008086d0000081A*
+ ID_MODEL_FROM_DATABASE=Medfield GPIO Controller [Core]
+
+pci:v00008086d0000081B*
+ ID_MODEL_FROM_DATABASE=Medfield Serial IO HSUART Controller #1
+
+pci:v00008086d0000081C*
+ ID_MODEL_FROM_DATABASE=Medfield Serial IO HSUART Controller #2
+
+pci:v00008086d0000081D*
+ ID_MODEL_FROM_DATABASE=Medfield Serial IO HSUART Controller #3
+
+pci:v00008086d0000081E*
+ ID_MODEL_FROM_DATABASE=Medfield Serial IO HSUART DMA Controller
+
+pci:v00008086d0000081F*
+ ID_MODEL_FROM_DATABASE=Medfield GPIO Controller [AON]
+
+pci:v00008086d00000820*
+ ID_MODEL_FROM_DATABASE=Medfield SD Host Controller
+
+pci:v00008086d00000821*
+ ID_MODEL_FROM_DATABASE=Medfield SDIO Controller #1
+
+pci:v00008086d00000822*
+ ID_MODEL_FROM_DATABASE=Medfield SDIO Controller #2
+
+pci:v00008086d00000823*
+ ID_MODEL_FROM_DATABASE=Medfield eMMC Controller #0
+
+pci:v00008086d00000824*
+ ID_MODEL_FROM_DATABASE=Medfield eMMC Controller #1
+
+pci:v00008086d00000827*
+ ID_MODEL_FROM_DATABASE=Medfield Serial IO DMA Controller
+
+pci:v00008086d00000828*
+ ID_MODEL_FROM_DATABASE=Medfield Power Management Unit
+
+pci:v00008086d00000829*
+ ID_MODEL_FROM_DATABASE=Medfield USB Device Controller (OTG)
+
+pci:v00008086d0000082A*
+ ID_MODEL_FROM_DATABASE=Medfield SCU IPC
+
+pci:v00008086d0000082C*
+ ID_MODEL_FROM_DATABASE=Medfield Serial IO I2C Controller #0
+
+pci:v00008086d0000082D*
+ ID_MODEL_FROM_DATABASE=Medfield Serial IO I2C Controller #1
+
+pci:v00008086d0000082E*
+ ID_MODEL_FROM_DATABASE=Medfield Serial IO I2C Controller #2
+
pci:v00008086d00000885*
ID_MODEL_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150
@@ -63707,6 +64145,9 @@ pci:v00008086d00000A2A*
pci:v00008086d00000A2E*
ID_MODEL_FROM_DATABASE=Haswell-ULT Integrated Graphics Controller
+pci:v00008086d00000A53*
+ ID_MODEL_FROM_DATABASE=DC P3520 SSD
+
pci:v00008086d00000BE0*
ID_MODEL_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller
@@ -64779,7 +65220,7 @@ pci:v00008086d00001019sv00008086sd00003025*
ID_MODEL_FROM_DATABASE=82547EI Gigabit Ethernet Controller (D875PBZ motherboard)
pci:v00008086d00001019sv00008086sd0000302C*
- ID_MODEL_FROM_DATABASE=82547EI Gigabit Ethernet Controller (Intel 82865G Mainboard (D865GBF))
+ ID_MODEL_FROM_DATABASE=82547EI Gigabit Ethernet Controller (D865GBF Mainboard)
pci:v00008086d00001019sv00008086sd00003427*
ID_MODEL_FROM_DATABASE=82547EI Gigabit Ethernet Controller (S875WP1-E mainboard)
@@ -65373,7 +65814,7 @@ pci:v00008086d00001096sv000015D9sd00008680*
ID_MODEL_FROM_DATABASE=80003ES2LAN Gigabit Ethernet Controller (Copper) (X7DVL-E-O motherboard)
pci:v00008086d00001096sv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=80003ES2LAN Gigabit Ethernet Controller (Copper) (Intel S5000PSLSATA Server Board)
+ ID_MODEL_FROM_DATABASE=80003ES2LAN Gigabit Ethernet Controller (Copper) (S5000PSLSATA Server Board)
pci:v00008086d00001097*
ID_MODEL_FROM_DATABASE=631xESB/632xESB DPT LAN Controller (Fiber)
@@ -65834,6 +66275,9 @@ pci:v00008086d000010F8sv0000103Csd000018D0*
pci:v00008086d000010F8sv00001059sd00000111*
ID_MODEL_FROM_DATABASE=82599 10 Gigabit Dual Port Backplane Connection (T4007 10GbE interface)
+pci:v00008086d000010F8sv00001059sd00000130*
+ ID_MODEL_FROM_DATABASE=82599 10 Gigabit Dual Port Backplane Connection (T4009 10GbE interface)
+
pci:v00008086d000010F8sv00008086sd0000000C*
ID_MODEL_FROM_DATABASE=82599 10 Gigabit Dual Port Backplane Connection (Ethernet X520 10GbE Dual Port KX4-KR Mezz)
@@ -65984,6 +66428,42 @@ pci:v00008086d00001161sv00008086sd00001161*
pci:v00008086d00001162*
ID_MODEL_FROM_DATABASE=Xscale 80200 Big Endian Companion Chip
+pci:v00008086d00001190*
+ ID_MODEL_FROM_DATABASE=Merrifield SD/SDIO/eMMC Controller
+
+pci:v00008086d00001191*
+ ID_MODEL_FROM_DATABASE=Merrifield Serial IO HSUART Controller
+
+pci:v00008086d00001192*
+ ID_MODEL_FROM_DATABASE=Merrifield Serial IO HSUART DMA Controller
+
+pci:v00008086d00001194*
+ ID_MODEL_FROM_DATABASE=Merrifield Serial IO SPI Controller
+
+pci:v00008086d00001195*
+ ID_MODEL_FROM_DATABASE=Merrifield Serial IO I2C Controller
+
+pci:v00008086d00001196*
+ ID_MODEL_FROM_DATABASE=Merrifield Serial IO I2C Controller
+
+pci:v00008086d00001199*
+ ID_MODEL_FROM_DATABASE=Merrifield GPIO Controller
+
+pci:v00008086d0000119E*
+ ID_MODEL_FROM_DATABASE=Merrifield USB Device Controller (OTG)
+
+pci:v00008086d000011A0*
+ ID_MODEL_FROM_DATABASE=Merrifield SCU IPC
+
+pci:v00008086d000011A1*
+ ID_MODEL_FROM_DATABASE=Merrifield Power Management Unit
+
+pci:v00008086d000011A2*
+ ID_MODEL_FROM_DATABASE=Merrifield Serial IO DMA Controller
+
+pci:v00008086d000011A5*
+ ID_MODEL_FROM_DATABASE=Merrifield Serial IO PWM Controller
+
pci:v00008086d00001200*
ID_MODEL_FROM_DATABASE=IXP1200 Network Processor
@@ -66968,6 +67448,12 @@ pci:v00008086d00001529*
pci:v00008086d0000152A*
ID_MODEL_FROM_DATABASE=82599 10 Gigabit Dual Port Backplane Connection with FCoE
+pci:v00008086d0000152E*
+ ID_MODEL_FROM_DATABASE=82599 Virtual Function
+
+pci:v00008086d00001530*
+ ID_MODEL_FROM_DATABASE=X540 Virtual Function
+
pci:v00008086d00001533*
ID_MODEL_FROM_DATABASE=I210 Gigabit Network Connection
@@ -67007,6 +67493,9 @@ pci:v00008086d00001537sv00001059sd00000111*
pci:v00008086d00001537sv00001059sd00000120*
ID_MODEL_FROM_DATABASE=I210 Gigabit Backplane Connection (T4008 1GbE interface)
+pci:v00008086d00001537sv00001059sd00000130*
+ ID_MODEL_FROM_DATABASE=I210 Gigabit Backplane Connection (T4009 1GbE interface)
+
pci:v00008086d00001538*
ID_MODEL_FROM_DATABASE=I210 Gigabit Network Connection
@@ -67133,6 +67622,9 @@ pci:v00008086d00001563sv00008086sd0000001A*
pci:v00008086d00001563sv00008086sd00000022*
ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Ethernet Converged Network Adapter X550-T2)
+pci:v00008086d00001564*
+ ID_MODEL_FROM_DATABASE=X550 Virtual Function
+
pci:v00008086d00001565*
ID_MODEL_FROM_DATABASE=X550 Virtual Function
@@ -67191,17 +67683,23 @@ pci:v00008086d00001572sv0000103Csd000022FD*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (HP Ethernet 10Gb 2-port 562SFP+ Adapter)
pci:v00008086d00001572sv00001137sd00000000*
- ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Converged NIC X710-4)
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Converged NIC X710-DA)
pci:v00008086d00001572sv00001137sd0000013B*
- ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Converged NIC X710-4)
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Converged NIC X710-DA4)
+
+pci:v00008086d00001572sv00001137sd0000020A*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Converged NIC X710-DA2)
pci:v00008086d00001572sv00001590sd00000000*
- ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet 10GbE 4P 563SFP+ Adapter)
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+
pci:v00008086d00001572sv00001590sd00000225*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet 10GbE 4P 563SFP+ Adapter)
+pci:v00008086d00001572sv00001590sd0000022F*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet 10Gb 2-port 564i Communication Board)
+
pci:v00008086d00001572sv000017AAsd00000000*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (ThinkServer X710 AnyFabric for 10GbE SFP+)
@@ -67251,7 +67749,7 @@ pci:v00008086d00001572sv00008086sd00000010*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Converged Network Adapter X710)
pci:v00008086d00001572sv00008086sd00004005*
- ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Controller XL710 for 10 Gigabit SFP+)
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+
pci:v00008086d00001572sv00008086sd00004006*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+
@@ -67386,10 +67884,10 @@ pci:v00008086d00001588*
ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 20GbE backplane
pci:v00008086d00001588sv0000103Csd00000000*
- ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 20GbE backplane (HPE Ethernet 10/20Gb 2-port 660M Adapter)
+ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 20GbE backplane (Ethernet 10/20Gb 2-port 660M Adapter)
pci:v00008086d00001588sv0000103Csd000022FF*
- ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 20GbE backplane (HPE Ethernet 10/20Gb 2-port 660M Adapter)
+ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 20GbE backplane (Ethernet 10/20Gb 2-port 660M Adapter)
pci:v00008086d00001589*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710/X557-AT 10GBASE-T
@@ -67466,6 +67964,9 @@ pci:v00008086d000015A5*
pci:v00008086d000015A8*
ID_MODEL_FROM_DATABASE=Ethernet Connection X552 Virtual Function
+pci:v00008086d000015A9*
+ ID_MODEL_FROM_DATABASE=X552 Virtual Function
+
pci:v00008086d000015AA*
ID_MODEL_FROM_DATABASE=Ethernet Connection X552 10 GbE Backplane
@@ -67484,6 +67985,12 @@ pci:v00008086d000015AD*
pci:v00008086d000015AE*
ID_MODEL_FROM_DATABASE=Ethernet Connection X552 1000BASE-T
+pci:v00008086d000015B0*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X552 Backplane
+
+pci:v00008086d000015B4*
+ ID_MODEL_FROM_DATABASE=X553 Virtual Function
+
pci:v00008086d000015B5*
ID_MODEL_FROM_DATABASE=DSL6340 USB 3.1 Controller [Alpine Ridge]
@@ -67499,12 +68006,27 @@ pci:v00008086d000015B8*
pci:v00008086d000015B9*
ID_MODEL_FROM_DATABASE=Ethernet Connection (3) I219-LM
+pci:v00008086d000015BB*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection (7) I219-LM
+
+pci:v00008086d000015BC*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection (7) I219-V
+
+pci:v00008086d000015BD*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection (6) I219-LM
+
+pci:v00008086d000015BE*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection (6) I219-V
+
pci:v00008086d000015BF*
ID_MODEL_FROM_DATABASE=JHL6240 Thunderbolt 3 NHI (Low Power) [Alpine Ridge LP 2016]
pci:v00008086d000015C0*
ID_MODEL_FROM_DATABASE=JHL6240 Thunderbolt 3 Bridge (Low Power) [Alpine Ridge LP 2016]
+pci:v00008086d000015C5*
+ ID_MODEL_FROM_DATABASE=X553 Virtual Function
+
pci:v00008086d000015D0*
ID_MODEL_FROM_DATABASE=Ethernet SDI Adapter FM10420-100GbE-QDA2
@@ -67950,7 +68472,7 @@ pci:v00008086d00001A38sv000015D9sd00008680*
ID_MODEL_FROM_DATABASE=5000 Series Chipset DMA Engine (X7DVL-E-O motherboard)
pci:v00008086d00001A38sv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=5000 Series Chipset DMA Engine (Intel S5000PSLSATA Server Board)
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset DMA Engine (S5000PSLSATA Server Board)
pci:v00008086d00001A48*
ID_MODEL_FROM_DATABASE=82597EX 10GbE Ethernet Controller
@@ -71384,6 +71906,12 @@ pci:v00008086d000024F4*
pci:v00008086d000024F4sv00008086sd00000030*
ID_MODEL_FROM_DATABASE=Wireless 8260 (Dual Band Wireless-AC 8260)
+pci:v00008086d000024FD*
+ ID_MODEL_FROM_DATABASE=Wireless 8265 / 8275
+
+pci:v00008086d000024FDsv00008086sd00000010*
+ ID_MODEL_FROM_DATABASE=Wireless 8265 / 8275 (Dual Band Wireless-AC 8265)
+
pci:v00008086d00002500*
ID_MODEL_FROM_DATABASE=82820 820 (Camino) Chipset Host Bridge (MCH)
@@ -72678,7 +73206,7 @@ pci:v00008086d00002670sv000015D9sd00009680*
ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset LPC Interface Controller (X7DBN Motherboard)
pci:v00008086d00002670sv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset LPC Interface Controller (Intel S5000PSLSATA Server Board)
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset LPC Interface Controller (S5000PSLSATA Server Board)
pci:v00008086d00002680*
ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset SATA IDE Controller
@@ -72696,7 +73224,7 @@ pci:v00008086d00002681sv000015D9sd00009680*
ID_MODEL_FROM_DATABASE=631xESB/632xESB SATA AHCI Controller (X7DBN Motherboard)
pci:v00008086d00002681sv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=631xESB/632xESB SATA AHCI Controller (Intel S5000PSLSATA Server Board)
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB SATA AHCI Controller (S5000PSLSATA Server Board)
pci:v00008086d00002682*
ID_MODEL_FROM_DATABASE=631xESB/632xESB SATA RAID Controller
@@ -72726,7 +73254,7 @@ pci:v00008086d00002688sv000015D9sd00009680*
ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #1 (X7DBN Motherboard)
pci:v00008086d00002688sv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #1 (Intel S5000PSLSATA Server Board)
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #1 (S5000PSLSATA Server Board)
pci:v00008086d00002689*
ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #2
@@ -72747,7 +73275,7 @@ pci:v00008086d00002689sv000015D9sd00009680*
ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #2 (X7DBN Motherboard)
pci:v00008086d00002689sv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #2 (Intel S5000PSLSATA Server Board)
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #2 (S5000PSLSATA Server Board)
pci:v00008086d0000268A*
ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #3
@@ -72765,7 +73293,7 @@ pci:v00008086d0000268Asv000015D9sd00009680*
ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #3 (X7DBN Motherboard)
pci:v00008086d0000268Asv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #3 (Intel S5000PSLSATA Server Board)
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #3 (S5000PSLSATA Server Board)
pci:v00008086d0000268B*
ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #4
@@ -72777,7 +73305,7 @@ pci:v00008086d0000268Bsv000015D9sd00008680*
ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #4 (X7DVL-E-O motherboard)
pci:v00008086d0000268Bsv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #4 (Intel S5000PSLSATA Server Board)
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #4 (S5000PSLSATA Server Board)
pci:v00008086d0000268C*
ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset EHCI USB2 Controller
@@ -72798,7 +73326,7 @@ pci:v00008086d0000268Csv000015D9sd00009680*
ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset EHCI USB2 Controller (X7DBN Motherboard)
pci:v00008086d0000268Csv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset EHCI USB2 Controller (Intel S5000PSLSATA Server Board)
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset EHCI USB2 Controller (S5000PSLSATA Server Board)
pci:v00008086d00002690*
ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset PCI Express Root Port 1
@@ -72843,7 +73371,7 @@ pci:v00008086d0000269Bsv000015D9sd00009680*
ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset SMBus Controller (X7DBN Motherboard)
pci:v00008086d0000269Bsv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset SMBus Controller (Intel S5000PSLSATA Server Board)
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset SMBus Controller (S5000PSLSATA Server Board)
pci:v00008086d0000269E*
ID_MODEL_FROM_DATABASE=631xESB/632xESB IDE Controller
@@ -72894,7 +73422,7 @@ pci:v00008086d00002772sv00008086sd0000544E*
ID_MODEL_FROM_DATABASE=82945G/GZ Integrated Graphics Controller (DeskTop Board D945GTP)
pci:v00008086d00002772sv00008086sd0000D605*
- ID_MODEL_FROM_DATABASE=82945G/GZ Integrated Graphics Controller (Intel Desktop Board D945GCCR)
+ ID_MODEL_FROM_DATABASE=82945G/GZ Integrated Graphics Controller (Desktop Board D945GCCR)
pci:v00008086d00002774*
ID_MODEL_FROM_DATABASE=82955X Memory Controller Hub
@@ -74043,22 +74571,22 @@ pci:v00008086d00002826*
ID_MODEL_FROM_DATABASE=C600/X79 series chipset SATA RAID Controller
pci:v00008086d00002826sv00001D49sd00000100*
- ID_MODEL_FROM_DATABASE=C600/X79 series chipset SATA RAID Controller (ThinkSystem RAID 331)
+ ID_MODEL_FROM_DATABASE=C600/X79 series chipset SATA RAID Controller (Intel RSTe SATA Software RAID)
pci:v00008086d00002826sv00001D49sd00000101*
- ID_MODEL_FROM_DATABASE=C600/X79 series chipset SATA RAID Controller (ThinkSystem RAID 331)
+ ID_MODEL_FROM_DATABASE=C600/X79 series chipset SATA RAID Controller (Intel RSTe SATA Software RAID)
pci:v00008086d00002826sv00001D49sd00000102*
- ID_MODEL_FROM_DATABASE=C600/X79 series chipset SATA RAID Controller (ThinkSystem RAID 331)
+ ID_MODEL_FROM_DATABASE=C600/X79 series chipset SATA RAID Controller (Intel RSTe SATA Software RAID)
pci:v00008086d00002826sv00001D49sd00000103*
- ID_MODEL_FROM_DATABASE=C600/X79 series chipset SATA RAID Controller (ThinkSystem RAID 331)
+ ID_MODEL_FROM_DATABASE=C600/X79 series chipset SATA RAID Controller (Intel RSTe SATA Software RAID)
pci:v00008086d00002826sv00001D49sd00000104*
- ID_MODEL_FROM_DATABASE=C600/X79 series chipset SATA RAID Controller (ThinkSystem RAID 331)
+ ID_MODEL_FROM_DATABASE=C600/X79 series chipset SATA RAID Controller (Intel RSTe SATA Software RAID)
pci:v00008086d00002826sv00001D49sd00000105*
- ID_MODEL_FROM_DATABASE=C600/X79 series chipset SATA RAID Controller (ThinkSystem RAID 331)
+ ID_MODEL_FROM_DATABASE=C600/X79 series chipset SATA RAID Controller (Intel RSTe SATA Software RAID)
pci:v00008086d00002827*
ID_MODEL_FROM_DATABASE=C610/X99 series chipset sSATA Controller [RAID mode]
@@ -76956,7 +77484,7 @@ pci:v00008086d00003165sv00008086sd00004210*
ID_MODEL_FROM_DATABASE=Wireless 3165 (Dual Band Wireless AC 3165)
pci:v00008086d00003166*
- ID_MODEL_FROM_DATABASE=Intel Dual Band Wireless-AC 3165 Plus Bluetooth
+ ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 3165 Plus Bluetooth
pci:v00008086d00003200*
ID_MODEL_FROM_DATABASE=GD31244 PCI-X SATA HBA
@@ -77783,9 +78311,18 @@ pci:v00008086d000037D0sv000017AAsd00004020*
pci:v00008086d000037D0sv000017AAsd00004021*
ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE SFP+ (Intel Ethernet Connection X722 for 10G SFP+)
+pci:v00008086d000037D0sv000017AAsd00004022*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE SFP+
+
pci:v00008086d000037D1*
ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 1GbE
+pci:v00008086d000037D1sv00001590sd00000216*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 1GbE (Ethernet 1Gb 2-port 368i Adapter)
+
+pci:v00008086d000037D1sv00001590sd00000217*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 1GbE (Ethernet 1Gb 2-port 368FLR-MMT Adapter)
+
pci:v00008086d000037D1sv000017AAsd00004020*
ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 1GbE (Intel Ethernet Connection X722 for 1GbE)
@@ -77798,15 +78335,24 @@ pci:v00008086d000037D1sv000017AAsd00004022*
pci:v00008086d000037D2*
ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T
+pci:v00008086d000037D2sv00001590sd00000218*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T (Ethernet 10Gb 2-port 568FLR-MMT Adapter)
+
pci:v00008086d000037D2sv000017AAsd00004020*
ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T (Intel Ethernet Connection X722 for 10GBASE)
pci:v00008086d000037D2sv000017AAsd00004021*
ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T (Intel Ethernet Connection X722 for 10GBASE)
+pci:v00008086d000037D2sv000017AAsd00004022*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T
+
pci:v00008086d000037D3*
ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE SFP+
+pci:v00008086d000037D3sv00001590sd00000219*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE SFP+ (Ethernet 10Gb 2-port 568FLR-MMSFP+ Adapter)
+
pci:v00008086d000037D4*
ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE QSFP+
@@ -79416,109 +79962,109 @@ pci:v00008086d00005845sv00001AF4sd00001100*
ID_MODEL_FROM_DATABASE=QEMU NVM Express Controller (QEMU Virtual Machine)
pci:v00008086d00005A84*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series Integrated Graphics Controller
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series Integrated Graphics Controller
pci:v00008086d00005A88*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series Imaging Unit
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series Imaging Unit
pci:v00008086d00005A98*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series Audio Cluster
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series Audio Cluster
pci:v00008086d00005A9A*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series Trusted Execution Engine
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series Trusted Execution Engine
pci:v00008086d00005AA2*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series Integrated Sensor Hub
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series Integrated Sensor Hub
pci:v00008086d00005AA8*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series USB xHCI
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series USB xHCI
pci:v00008086d00005AAC*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series I2C Controller #1
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series I2C Controller #1
pci:v00008086d00005AAE*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series I2C Controller #2
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series I2C Controller #2
pci:v00008086d00005AB0*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series I2C Controller #3
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series I2C Controller #3
pci:v00008086d00005AB2*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series I2C Controller #4
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series I2C Controller #4
pci:v00008086d00005AB4*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series I2C Controller #5
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series I2C Controller #5
pci:v00008086d00005AB6*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series I2C Controller #6
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series I2C Controller #6
pci:v00008086d00005AB8*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series I2C Controller #7
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series I2C Controller #7
pci:v00008086d00005ABA*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series I2C Controller #8
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series I2C Controller #8
pci:v00008086d00005ABC*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series HSUART Controller #1
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series HSUART Controller #1
pci:v00008086d00005ABE*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series HSUART Controller #2
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series HSUART Controller #2
pci:v00008086d00005AC0*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series HSUART Controller #3
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series HSUART Controller #3
pci:v00008086d00005AC2*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series SPI Controller #1
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series SPI Controller #1
pci:v00008086d00005AC4*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series SPI Controller #2
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series SPI Controller #2
pci:v00008086d00005AC6*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series SPI Controller #3
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series SPI Controller #3
pci:v00008086d00005AC8*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series PWM Pin Controller
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series PWM Pin Controller
pci:v00008086d00005ACA*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series SDXC/MMC Host Controller
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series SDXC/MMC Host Controller
pci:v00008086d00005ACC*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series eMMC Controller
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series eMMC Controller
pci:v00008086d00005AD0*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series SDIO Controller
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series SDIO Controller
pci:v00008086d00005AD4*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series SMBus Controller
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series SMBus Controller
pci:v00008086d00005AD6*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series PCI Express Port B #1
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series PCI Express Port B #1
pci:v00008086d00005AD7*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series PCI Express Port B #2
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series PCI Express Port B #2
pci:v00008086d00005AD8*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series PCI Express Port A #1
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series PCI Express Port A #1
pci:v00008086d00005AD9*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series PCI Express Port A #2
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series PCI Express Port A #2
pci:v00008086d00005ADA*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series PCI Express Port A #3
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series PCI Express Port A #3
pci:v00008086d00005ADB*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series PCI Express Port A #4
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series PCI Express Port A #4
pci:v00008086d00005AE3*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series SATA AHCI Controller
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series SATA AHCI Controller
pci:v00008086d00005AE8*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series Low Pin Count Interface
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series Low Pin Count Interface
pci:v00008086d00005AEE*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series HSUART Controller #4
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series HSUART Controller #4
pci:v00008086d00005AF0*
- ID_MODEL_FROM_DATABASE=Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series Host Bridge
+ ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series Host Bridge
pci:v00008086d000065C0*
ID_MODEL_FROM_DATABASE=5100 Chipset Memory Controller Hub
@@ -82043,6 +82589,63 @@ pci:v00008086d0000A252*
pci:v00008086d0000A256*
ID_MODEL_FROM_DATABASE=Lewisburg SSATA Controller [RAID mode]
+pci:v00008086d0000A282*
+ ID_MODEL_FROM_DATABASE=200 Series PCH SATA controller [AHCI mode]
+
+pci:v00008086d0000A294*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #1
+
+pci:v00008086d0000A2A1*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PMC
+
+pci:v00008086d0000A2A3*
+ ID_MODEL_FROM_DATABASE=200 Series PCH SMBus Controller
+
+pci:v00008086d0000A2A7*
+ ID_MODEL_FROM_DATABASE=200 Series PCH Serial IO UART Controller #0
+
+pci:v00008086d0000A2A8*
+ ID_MODEL_FROM_DATABASE=200 Series PCH Serial IO UART Controller #1
+
+pci:v00008086d0000A2A9*
+ ID_MODEL_FROM_DATABASE=200 Series PCH Serial IO SPI Controller #0
+
+pci:v00008086d0000A2AA*
+ ID_MODEL_FROM_DATABASE=200 Series PCH Serial IO SPI Controller #1
+
+pci:v00008086d0000A2AF*
+ ID_MODEL_FROM_DATABASE=200 Series PCH USB 3.0 xHCI Controller
+
+pci:v00008086d0000A2B1*
+ ID_MODEL_FROM_DATABASE=200 Series PCH Thermal Subsystem
+
+pci:v00008086d0000A2BA*
+ ID_MODEL_FROM_DATABASE=200 Series PCH CSME HECI #1
+
+pci:v00008086d0000A2BB*
+ ID_MODEL_FROM_DATABASE=200 Series PCH CSME HECI #2
+
+pci:v00008086d0000A2C6*
+ ID_MODEL_FROM_DATABASE=200 Series PCH LPC Controller
+
+pci:v00008086d0000A2E0*
+ ID_MODEL_FROM_DATABASE=200 Series PCH Serial IO I2C Controller #0
+
+pci:v00008086d0000A2E1*
+ ID_MODEL_FROM_DATABASE=200 Series PCH Serial IO I2C Controller #1
+
+pci:v00008086d0000A2E2*
+ ID_MODEL_FROM_DATABASE=200 Series PCH Serial IO I2C Controller #2
+
+pci:v00008086d0000A2E3*
+ ID_MODEL_FROM_DATABASE=200 Series PCH Serial IO I2C Controller #3
+
+pci:v00008086d0000A2E6*
+ ID_MODEL_FROM_DATABASE=200 Series PCH Serial IO UART Controller #2
+
+pci:v00008086d0000A2F0*
+ ID_MODEL_FROM_DATABASE=200 Series PCH HD Audio
+
pci:v00008086d0000A620*
ID_MODEL_FROM_DATABASE=6400/6402 Advanced Memory Buffer (AMB)
@@ -84320,6 +84923,9 @@ pci:v0000F1D0d0000CFEE*
pci:v0000F1D0d0000DAFF*
ID_MODEL_FROM_DATABASE=KONA LHi
+pci:v0000F1D0d0000DB09*
+ ID_MODEL_FROM_DATABASE=Corvid 24
+
pci:v0000F1D0d0000DCAF*
ID_MODEL_FROM_DATABASE=Kona HD
diff --git a/hwdb/20-usb-vendor-model.hwdb b/hwdb/20-usb-vendor-model.hwdb
index ec0c26fc35..6acb51bb1c 100644
--- a/hwdb/20-usb-vendor-model.hwdb
+++ b/hwdb/20-usb-vendor-model.hwdb
@@ -50,6 +50,9 @@ usb:v0127*
usb:v0127p0002*
ID_MODEL_FROM_DATABASE=HDM Interface
+usb:v0127p0127*
+ ID_MODEL_FROM_DATABASE=ibp
+
usb:v0145*
ID_VENDOR_FROM_DATABASE=Unknown
@@ -1841,6 +1844,9 @@ usb:v03F0p9002*
usb:v03F0p9102*
ID_MODEL_FROM_DATABASE=PhotoSmart M537
+usb:v03F0p9207*
+ ID_MODEL_FROM_DATABASE=HD-4110 Webcam
+
usb:v03F0p9302*
ID_MODEL_FROM_DATABASE=PhotoSmart R930 series
@@ -2063,6 +2069,9 @@ usb:v03FD*
usb:v03FDp0008*
ID_MODEL_FROM_DATABASE=Platform Cable USB II
+usb:v03FDp0050*
+ ID_MODEL_FROM_DATABASE=dfu downloader
+
usb:v03FE*
ID_VENDOR_FROM_DATABASE=Farallon Comunications
@@ -2187,7 +2196,7 @@ usb:v0403p6009*
ID_MODEL_FROM_DATABASE=Serial Converter
usb:v0403p6010*
- ID_MODEL_FROM_DATABASE=FT2232C Dual USB-UART/FIFO IC
+ ID_MODEL_FROM_DATABASE=FT2232C/D/H Dual UART/FIFO IC
usb:v0403p6011*
ID_MODEL_FROM_DATABASE=FT4232H Quad HS USB-UART/FIFO IC
@@ -2318,6 +2327,9 @@ usb:v0403pBFDB*
usb:v0403pBFDC*
ID_MODEL_FROM_DATABASE=OpenDCC (GBM)
+usb:v0403pC580*
+ ID_MODEL_FROM_DATABASE=HID UNIKEY dongle [F-Response]
+
usb:v0403pC630*
ID_MODEL_FROM_DATABASE=lcd2usb interface
@@ -5432,6 +5444,12 @@ usb:v044F*
usb:v044Fp0400*
ID_MODEL_FROM_DATABASE=HOTAS Cougar
+usb:v044Fp0402*
+ ID_MODEL_FROM_DATABASE=HOTAS Warthog Joystick
+
+usb:v044Fp0404*
+ ID_MODEL_FROM_DATABASE=HOTAS Warthog Throttle
+
usb:v044Fp044F*
ID_MODEL_FROM_DATABASE=GP XID
@@ -5501,6 +5519,9 @@ usb:v044FpB653*
usb:v044FpB654*
ID_MODEL_FROM_DATABASE=Ferrari GT Force Feedback Wheel
+usb:v044FpB687*
+ ID_MODEL_FROM_DATABASE=TWCS Throttle
+
usb:v044FpB700*
ID_MODEL_FROM_DATABASE=Tacticalboard
@@ -6401,6 +6422,15 @@ usb:v045Ep02D5*
usb:v045Ep02DD*
ID_MODEL_FROM_DATABASE=Xbox One Controller (Covert Forces/Firmware 2015)
+usb:v045Ep02E3*
+ ID_MODEL_FROM_DATABASE=Xbox One Elite Controller
+
+usb:v045Ep02E6*
+ ID_MODEL_FROM_DATABASE=Wireless XBox Controller Dongle
+
+usb:v045Ep02EA*
+ ID_MODEL_FROM_DATABASE=Xbox One S Controller
+
usb:v045Ep0400*
ID_MODEL_FROM_DATABASE=Windows Powered Pocket PC 2002
@@ -6851,6 +6881,9 @@ usb:v045Ep0752*
usb:v045Ep075D*
ID_MODEL_FROM_DATABASE=LifeCam Cinema
+usb:v045Ep0761*
+ ID_MODEL_FROM_DATABASE=LifeCam VX-2000
+
usb:v045Ep0766*
ID_MODEL_FROM_DATABASE=LifeCam VX-800
@@ -6869,6 +6902,9 @@ usb:v045Ep0772*
usb:v045Ep0779*
ID_MODEL_FROM_DATABASE=LifeCam HD-3000
+usb:v045Ep077F*
+ ID_MODEL_FROM_DATABASE=LifeChat LX-6000 Headset
+
usb:v045Ep0780*
ID_MODEL_FROM_DATABASE=Comfort Curve Keyboard 3000
@@ -7148,6 +7184,12 @@ usb:v046Ap002A*
usb:v046Ap002D*
ID_MODEL_FROM_DATABASE=SmartTerminal XX44
+usb:v046Ap003C*
+ ID_MODEL_FROM_DATABASE=Raptor Gaming Keyboard
+
+usb:v046Ap003D*
+ ID_MODEL_FROM_DATABASE=Raptor Gaming Keyboard Integrated Hub
+
usb:v046Ap003E*
ID_MODEL_FROM_DATABASE=SmartTerminal ST-2xxx
@@ -7166,6 +7208,12 @@ usb:v046Ap0106*
usb:v046Ap010D*
ID_MODEL_FROM_DATABASE=MX-Board 3.0 Keyboard
+usb:v046ApB090*
+ ID_MODEL_FROM_DATABASE=Keyboard
+
+usb:v046ApB091*
+ ID_MODEL_FROM_DATABASE=Mouse
+
usb:v046B*
ID_VENDOR_FROM_DATABASE=American Megatrends, Inc.
@@ -7607,9 +7655,15 @@ usb:v046Dp0A38*
usb:v046Dp0A44*
ID_MODEL_FROM_DATABASE=Headset H390
+usb:v046Dp0A45*
+ ID_MODEL_FROM_DATABASE=960 Headset
+
usb:v046Dp0A4D*
ID_MODEL_FROM_DATABASE=G430 Surround Sound Gaming Headset
+usb:v046Dp0A5B*
+ ID_MODEL_FROM_DATABASE=G933 Wireless Headset Dongle
+
usb:v046Dp0B02*
ID_MODEL_FROM_DATABASE=C-UV35 [Bluetooth Mini-Receiver] (HID proxy mode)
@@ -7902,7 +7956,7 @@ usb:v046DpC20E*
ID_MODEL_FROM_DATABASE=WingMan Formula GP
usb:v046DpC211*
- ID_MODEL_FROM_DATABASE=iTouch Cordless Reciever
+ ID_MODEL_FROM_DATABASE=iTouch Cordless Receiver
usb:v046DpC212*
ID_MODEL_FROM_DATABASE=WingMan Extreme Digital 3D
@@ -9149,6 +9203,9 @@ usb:v0480pA208*
usb:v0480pB001*
ID_MODEL_FROM_DATABASE=Stor.E Partner
+usb:v0480pB207*
+ ID_MODEL_FROM_DATABASE=Canvio Ready
+
usb:v0480pD000*
ID_MODEL_FROM_DATABASE=External Disk 2TB Model DT01ABA200
@@ -9362,6 +9419,9 @@ usb:v048D*
usb:v048Dp1165*
ID_MODEL_FROM_DATABASE=IT1165 Flash Controller
+usb:v048Dp1172*
+ ID_MODEL_FROM_DATABASE=Flash Drive
+
usb:v048Dp1336*
ID_MODEL_FROM_DATABASE=SD/MMC Cardreader
@@ -10145,6 +10205,9 @@ usb:v04A7p04A0*
usb:v04A7p04AC*
ID_MODEL_FROM_DATABASE=Xerox Travel Scanner 100
+usb:v04A7p04CD*
+ ID_MODEL_FROM_DATABASE=Xerox Travel Scanner 150
+
usb:v04A8*
ID_VENDOR_FROM_DATABASE=Multivideo Labs, Inc.
@@ -10361,6 +10424,9 @@ usb:v04A9p10A9*
usb:v04A9p10B6*
ID_MODEL_FROM_DATABASE=PIXMA iP4300 Printer
+usb:v04A9p10B7*
+ ID_MODEL_FROM_DATABASE=PIXMA iP5300 Printer
+
usb:v04A9p10C2*
ID_MODEL_FROM_DATABASE=PIXMA iP1800 Printer
@@ -10368,7 +10434,10 @@ usb:v04A9p10C4*
ID_MODEL_FROM_DATABASE=Pixma iP4500 Printer
usb:v04A9p10C9*
- ID_MODEL_FROM_DATABASE=PIXIMA iP4600 Printer
+ ID_MODEL_FROM_DATABASE=PIXMA iP4600 Printer
+
+usb:v04A9p10CA*
+ ID_MODEL_FROM_DATABASE=PIXMA iP3600 Printer
usb:v04A9p10E3*
ID_MODEL_FROM_DATABASE=PIXMA iX6850 Printer
@@ -10394,6 +10463,9 @@ usb:v04A9p1601*
usb:v04A9p1607*
ID_MODEL_FROM_DATABASE=DR-6080 Scanner
+usb:v04A9p1608*
+ ID_MODEL_FROM_DATABASE=DR-2580C Scanner
+
usb:v04A9p1700*
ID_MODEL_FROM_DATABASE=PIXMA MP110 Scanner
@@ -10485,7 +10557,7 @@ usb:v04A9p1727*
ID_MODEL_FROM_DATABASE=MX300 ser
usb:v04A9p1728*
- ID_MODEL_FROM_DATABASE=MX310 ser
+ ID_MODEL_FROM_DATABASE=PIXMA MX310 series
usb:v04A9p1729*
ID_MODEL_FROM_DATABASE=MX700 ser
@@ -11564,9 +11636,15 @@ usb:v04A9p3212*
usb:v04A9p3214*
ID_MODEL_FROM_DATABASE=SELPHY CP800
+usb:v04A9p3215*
+ ID_MODEL_FROM_DATABASE=EOS 60D
+
usb:v04A9p3218*
ID_MODEL_FROM_DATABASE=EOS 600D / Rebel T3i (ptp)
+usb:v04A9p3219*
+ ID_MODEL_FROM_DATABASE=EOS 1D X
+
usb:v04A9p3223*
ID_MODEL_FROM_DATABASE=PowerShot A3300 IS
@@ -11615,9 +11693,15 @@ usb:v04A9p3237*
usb:v04A9p3238*
ID_MODEL_FROM_DATABASE=PowerShot SX40 HS
+usb:v04A9p323A*
+ ID_MODEL_FROM_DATABASE=EOS 5D Mark III
+
usb:v04A9p323B*
ID_MODEL_FROM_DATABASE=EOS Rebel T4i
+usb:v04A9p323D*
+ ID_MODEL_FROM_DATABASE=EOS M
+
usb:v04A9p323E*
ID_MODEL_FROM_DATABASE=PowerShot A1300
@@ -11642,6 +11726,9 @@ usb:v04A9p3244*
usb:v04A9p3245*
ID_MODEL_FROM_DATABASE=PowerShot SX240 HS
+usb:v04A9p3246*
+ ID_MODEL_FROM_DATABASE=PowerShot ELPH 530 HS / IXUS 510 HS
+
usb:v04A9p3247*
ID_MODEL_FROM_DATABASE=PowerShot ELPH 520 HS / IXUS 500 HS
@@ -11654,6 +11741,15 @@ usb:v04A9p3249*
usb:v04A9p324A*
ID_MODEL_FROM_DATABASE=PowerShot A2300
+usb:v04A9p3250*
+ ID_MODEL_FROM_DATABASE=EOS 6D
+
+usb:v04A9p3252*
+ ID_MODEL_FROM_DATABASE=EOS 1D C
+
+usb:v04A9p3253*
+ ID_MODEL_FROM_DATABASE=EOS 70D
+
usb:v04A9p3255*
ID_MODEL_FROM_DATABASE=SELPHY CP900
@@ -11705,9 +11801,24 @@ usb:v04A9p3266*
usb:v04A9p3268*
ID_MODEL_FROM_DATABASE=PowerShot ELPH 330 HS / IXUS 255 HS
+usb:v04A9p326F*
+ ID_MODEL_FROM_DATABASE=EOS 7D Mark II
+
+usb:v04A9p3270*
+ ID_MODEL_FROM_DATABASE=EOS 100D
+
usb:v04A9p3271*
ID_MODEL_FROM_DATABASE=PowerShot A2500
+usb:v04A9p3272*
+ ID_MODEL_FROM_DATABASE=EOS 700D
+
+usb:v04A9p3274*
+ ID_MODEL_FROM_DATABASE=PowerShot G16
+
+usb:v04A9p3275*
+ ID_MODEL_FROM_DATABASE=PowerShot S120
+
usb:v04A9p3276*
ID_MODEL_FROM_DATABASE=PowerShot SX170 IS
@@ -11717,6 +11828,9 @@ usb:v04A9p3277*
usb:v04A9p3278*
ID_MODEL_FROM_DATABASE=PowerShot S200
+usb:v04A9p327A*
+ ID_MODEL_FROM_DATABASE=SELPHY CP910
+
usb:v04A9p327D*
ID_MODEL_FROM_DATABASE=Powershot ELPH 115 IS / IXUS 132
@@ -11771,15 +11885,30 @@ usb:v04A9p32A6*
usb:v04A9p32AA*
ID_MODEL_FROM_DATABASE=Powershot ELPH 160 / IXUS 160
+usb:v04A9p32AB*
+ ID_MODEL_FROM_DATABASE=PowerShot ELPH 350HS / IXUS 275 HS
+
usb:v04A9p32AC*
ID_MODEL_FROM_DATABASE=PowerShot ELPH 170 IS / IXUS 170
usb:v04A9p32AD*
ID_MODEL_FROM_DATABASE=PowerShot SX410 IS
+usb:v04A9p32B1*
+ ID_MODEL_FROM_DATABASE=SELPHY CP1200
+
+usb:v04A9p32B2*
+ ID_MODEL_FROM_DATABASE=PowerShot G9 X
+
+usb:v04A9p32BB*
+ ID_MODEL_FROM_DATABASE=EOS M5
+
usb:v04A9p32C1*
ID_MODEL_FROM_DATABASE=PowerShot ELPH 180 / IXUS 175
+usb:v04A9p32C2*
+ ID_MODEL_FROM_DATABASE=PowerShot SX720 HS
+
usb:v04AA*
ID_VENDOR_FROM_DATABASE=DaeWoo Telecom, Ltd
@@ -12878,6 +13007,9 @@ usb:v04B9p1305*
usb:v04B9p1306*
ID_MODEL_FROM_DATABASE=iKey Token
+usb:v04B9p8000*
+ ID_MODEL_FROM_DATABASE=SafeNet Sentinel Hardware Key
+
usb:v04BA*
ID_VENDOR_FROM_DATABASE=Toucan Systems, Ltd
@@ -13763,6 +13895,9 @@ usb:v04D9p2011*
usb:v04D9p2013*
ID_MODEL_FROM_DATABASE=Keyboard [Das Keyboard]
+usb:v04D9p2206*
+ ID_MODEL_FROM_DATABASE=Fujitsu Siemens Mouse Esprimo Q
+
usb:v04D9p2221*
ID_MODEL_FROM_DATABASE=Keyboard
@@ -13787,6 +13922,9 @@ usb:v04D9pA050*
usb:v04D9pA055*
ID_MODEL_FROM_DATABASE=Keyboard
+usb:v04D9pA11B*
+ ID_MODEL_FROM_DATABASE=Mouse [MX-3200]
+
usb:v04DA*
ID_VENDOR_FROM_DATABASE=Panasonic (Matsushita)
@@ -13817,6 +13955,9 @@ usb:v04DAp0D0D*
usb:v04DAp0D0E*
ID_MODEL_FROM_DATABASE=DVD-ROM & CD-R/RW
+usb:v04DAp0F07*
+ ID_MODEL_FROM_DATABASE=KX-MB2030 Multifunction Laser Printer
+
usb:v04DAp0F40*
ID_MODEL_FROM_DATABASE=Printer
@@ -13871,6 +14012,15 @@ usb:v04DAp2451*
usb:v04DAp245B*
ID_MODEL_FROM_DATABASE=HC-X920K (3MOS Full HD video camcorder)
+usb:v04DAp2477*
+ ID_MODEL_FROM_DATABASE=SDR-H85 Camcorder (PC mode)
+
+usb:v04DAp2478*
+ ID_MODEL_FROM_DATABASE=SDR-H85 Camcorder (recorder mode - SD card)
+
+usb:v04DAp2479*
+ ID_MODEL_FROM_DATABASE=SDR-H85 Camcorder (recorder mode - HDD)
+
usb:v04DAp2497*
ID_MODEL_FROM_DATABASE=HDC-TM700
@@ -14315,6 +14465,9 @@ usb:v04E7p00FF*
usb:v04E8*
ID_VENDOR_FROM_DATABASE=Samsung Electronics Co., Ltd
+usb:v04E8p0001*
+ ID_MODEL_FROM_DATABASE=Printer Bootloader
+
usb:v04E8p0100*
ID_MODEL_FROM_DATABASE=Kingston Flash Drive (128MB)
@@ -14775,7 +14928,7 @@ usb:v04E8p61B6*
ID_MODEL_FROM_DATABASE=M3 Portable Hard Drive 1TB
usb:v04E8p61F3*
- ID_MODEL_FROM_DATABASE=MU-PT500B [T3 500GB USB SSD]
+ ID_MODEL_FROM_DATABASE=Portable SSD T3 (MU-PT250B, MU-PT500B)
usb:v04E8p6601*
ID_MODEL_FROM_DATABASE=Mobile Phone
@@ -14907,10 +15060,10 @@ usb:v04E8p6864*
ID_MODEL_FROM_DATABASE=GT-I9070 (network tethering, USB debugging enabled)
usb:v04E8p6865*
- ID_MODEL_FROM_DATABASE=GT-I9300 Phone [Galaxy S III] (PTP mode)
+ ID_MODEL_FROM_DATABASE=Galaxy (PTP mode)
usb:v04E8p6866*
- ID_MODEL_FROM_DATABASE=GT-I9300 Phone [Galaxy S III] (debugging mode)
+ ID_MODEL_FROM_DATABASE=Galaxy (debugging mode)
usb:v04E8p6868*
ID_MODEL_FROM_DATABASE=Escape Composite driver for Android Phones: Modem+Diagnostic+ADB
@@ -15329,6 +15482,9 @@ usb:v04F3p0230*
usb:v04F3p0232*
ID_MODEL_FROM_DATABASE=Mouse
+usb:v04F3p0234*
+ ID_MODEL_FROM_DATABASE=Optical Mouse
+
usb:v04F3p02F4*
ID_MODEL_FROM_DATABASE=2.4G Cordless Mouse
@@ -16850,9 +17006,18 @@ usb:v04F9p2028*
usb:v04F9p202B*
ID_MODEL_FROM_DATABASE=PT-7600 P-touch Label Printer
+usb:v04F9p2061*
+ ID_MODEL_FROM_DATABASE=PT-P700 P-touch Label Printer
+
+usb:v04F9p2064*
+ ID_MODEL_FROM_DATABASE=PT-P700 P-touch Label Printer RemovableDisk
+
usb:v04F9p2100*
ID_MODEL_FROM_DATABASE=Card Reader Writer
+usb:v04F9p2102*
+ ID_MODEL_FROM_DATABASE=Sewing machine
+
usb:v04F9p60A0*
ID_MODEL_FROM_DATABASE=ADS-2000
@@ -18371,6 +18536,9 @@ usb:v054Cp021C*
usb:v054Cp021D*
ID_MODEL_FROM_DATABASE=Net MD
+usb:v054Cp0226*
+ ID_MODEL_FROM_DATABASE=UP-CR10L
+
usb:v054Cp0227*
ID_MODEL_FROM_DATABASE=Printing Support
@@ -18554,9 +18722,27 @@ usb:v054Cp0689*
usb:v054Cp06BB*
ID_MODEL_FROM_DATABASE=WALKMAN NWZ-F805
+usb:v054Cp06C3*
+ ID_MODEL_FROM_DATABASE=RC-S380
+
+usb:v054Cp07C4*
+ ID_MODEL_FROM_DATABASE=ILCE-6000 (aka Alpha-6000) in Mass Storage mode
+
usb:v054Cp088C*
ID_MODEL_FROM_DATABASE=Portable Headphone Amplifier
+usb:v054Cp08B7*
+ ID_MODEL_FROM_DATABASE=ILCE-6000 (aka Alpha-6000) in MTP mode
+
+usb:v054Cp094E*
+ ID_MODEL_FROM_DATABASE=ILCE-6000 (aka Alpha-6000) in PC Remote mode
+
+usb:v054Cp0994*
+ ID_MODEL_FROM_DATABASE=ILCE-6000 (aka Alpha-6000) in charging mode
+
+usb:v054Cp0BB5*
+ ID_MODEL_FROM_DATABASE=Headset MDR-1000X
+
usb:v054Cp1000*
ID_MODEL_FROM_DATABASE=Wireless Buzz! Receiver
@@ -19418,6 +19604,24 @@ usb:v056Ap0318*
usb:v056Ap032F*
ID_MODEL_FROM_DATABASE=DTU-1031X
+usb:v056Ap0347*
+ ID_MODEL_FROM_DATABASE=Integrated Hub
+
+usb:v056Ap0348*
+ ID_MODEL_FROM_DATABASE=Integrated Hub
+
+usb:v056Ap034A*
+ ID_MODEL_FROM_DATABASE=DTH-W1320 [MobileStudio Pro 13] touchscreen
+
+usb:v056Ap034B*
+ ID_MODEL_FROM_DATABASE=DTH-W1620 [MobileStudio Pro 16] touchscreen
+
+usb:v056Ap034D*
+ ID_MODEL_FROM_DATABASE=DTH-W1320 [MobileStudio Pro 13] tablet
+
+usb:v056Ap034E*
+ ID_MODEL_FROM_DATABASE=DTH-W1620 [MobileStudio Pro 16] tablet
+
usb:v056Ap0400*
ID_MODEL_FROM_DATABASE=PenPartner 4x5
@@ -19565,6 +19769,9 @@ usb:v0572p1301*
usb:v0572p1328*
ID_MODEL_FROM_DATABASE=TrendNet TFM-561 modem
+usb:v0572p1804*
+ ID_MODEL_FROM_DATABASE=HP Dock Audio
+
usb:v0572p2000*
ID_MODEL_FROM_DATABASE=SoftGate 802.11 Adapter
@@ -20888,6 +21095,9 @@ usb:v058Cp001F*
usb:v058CpFFE5*
ID_MODEL_FROM_DATABASE=IN34 Projector
+usb:v058CpFFEB*
+ ID_MODEL_FROM_DATABASE=Projector IN76
+
usb:v058D*
ID_VENDOR_FROM_DATABASE=Micrel Semiconductor
@@ -23189,6 +23399,9 @@ usb:v05DCpB018*
usb:v05DCpB047*
ID_MODEL_FROM_DATABASE=SDHC Reader [RW047-7000]
+usb:v05DCpB051*
+ ID_MODEL_FROM_DATABASE=microSD RDR UHS-I Card Reader [LRWM03U-7000]
+
usb:v05DCpBA02*
ID_MODEL_FROM_DATABASE=Workflow CFR1
@@ -23300,6 +23513,9 @@ usb:v05E3p0142*
usb:v05E3p0143*
ID_MODEL_FROM_DATABASE=Multiple Frames Film Scanner-36series
+usb:v05E3p0145*
+ ID_MODEL_FROM_DATABASE=Reflecta CrystalScan 7200 Photo-Scanner
+
usb:v05E3p0180*
ID_MODEL_FROM_DATABASE=Plustek Scanner
@@ -23447,6 +23663,9 @@ usb:v05E3p0732*
usb:v05E3p0736*
ID_MODEL_FROM_DATABASE=microSD Reader/Writer
+usb:v05E3p0738*
+ ID_MODEL_FROM_DATABASE=Card reader
+
usb:v05E3p0741*
ID_MODEL_FROM_DATABASE=microSD Card Reader
@@ -26171,6 +26390,21 @@ usb:v06D3p03A1*
usb:v06D3p03A5*
ID_MODEL_FROM_DATABASE=CP9550DW-S
+usb:v06D3p03A9*
+ ID_MODEL_FROM_DATABASE=CP-9600DW
+
+usb:v06D3p03AA*
+ ID_MODEL_FROM_DATABASE=CP3020DA
+
+usb:v06D3p03AD*
+ ID_MODEL_FROM_DATABASE=CP-9800DW-S
+
+usb:v06D3p03AE*
+ ID_MODEL_FROM_DATABASE=CP-9800DW-S
+
+usb:v06D3p3B10*
+ ID_MODEL_FROM_DATABASE=P95D
+
usb:v06D3p3B30*
ID_MODEL_FROM_DATABASE=CP-D70DW / CP-D707DW
@@ -26885,6 +27119,9 @@ usb:v0718p0624*
usb:v0718p1120*
ID_MODEL_FROM_DATABASE=RDX External dock (redbud)
+usb:v0718p4006*
+ ID_MODEL_FROM_DATABASE=8x Slim DVD Multi-Format Recorder External
+
usb:v0718pD000*
ID_MODEL_FROM_DATABASE=Disc Stakka CD/DVD Manager
@@ -27890,6 +28127,9 @@ usb:v0781p5575*
usb:v0781p5576*
ID_MODEL_FROM_DATABASE=Cruzer Facet
+usb:v0781p5577*
+ ID_MODEL_FROM_DATABASE=Cruzer Pop (8GB)
+
usb:v0781p557D*
ID_MODEL_FROM_DATABASE=Cruzer Force (64GB)
@@ -27902,6 +28142,9 @@ usb:v0781p5581*
usb:v0781p5583*
ID_MODEL_FROM_DATABASE=Ultra Fit
+usb:v0781p5590*
+ ID_MODEL_FROM_DATABASE=Ultra Dual
+
usb:v0781p5591*
ID_MODEL_FROM_DATABASE=Ultra Flair
@@ -29840,6 +30083,9 @@ usb:v0810p0002*
usb:v0810p0003*
ID_MODEL_FROM_DATABASE=PlayStation Gamepad
+usb:v0810pE501*
+ ID_MODEL_FROM_DATABASE=SNES Gamepad
+
usb:v0813*
ID_VENDOR_FROM_DATABASE=Mattel, Inc.
@@ -30888,13 +31134,31 @@ usb:v08BB*
ID_VENDOR_FROM_DATABASE=Texas Instruments
usb:v08BBp2702*
- ID_MODEL_FROM_DATABASE=Speakers
+ ID_MODEL_FROM_DATABASE=PCM2702 16-bit stereo audio DAC
usb:v08BBp2704*
- ID_MODEL_FROM_DATABASE=Audio Codec
+ ID_MODEL_FROM_DATABASE=PCM2704 16-bit stereo audio DAC
+
+usb:v08BBp2705*
+ ID_MODEL_FROM_DATABASE=PCM2705 stereo audio DAC
usb:v08BBp2706*
- ID_MODEL_FROM_DATABASE=PCM2706 Audio Codec
+ ID_MODEL_FROM_DATABASE=PCM2706 stereo audio DAC
+
+usb:v08BBp2707*
+ ID_MODEL_FROM_DATABASE=PCM2707 stereo audio DAC
+
+usb:v08BBp27C4*
+ ID_MODEL_FROM_DATABASE=PCM2704C stereo audio DAC
+
+usb:v08BBp27C5*
+ ID_MODEL_FROM_DATABASE=PCM2705C stereo audio DAC
+
+usb:v08BBp27C6*
+ ID_MODEL_FROM_DATABASE=PCM2706C stereo audio DAC
+
+usb:v08BBp27C7*
+ ID_MODEL_FROM_DATABASE=PCM2707C stereo audio DAC
usb:v08BBp2900*
ID_MODEL_FROM_DATABASE=PCM2900 Audio Codec
@@ -30911,6 +31175,9 @@ usb:v08BBp2904*
usb:v08BBp2910*
ID_MODEL_FROM_DATABASE=PCM2912 Audio Codec
+usb:v08BBp2912*
+ ID_MODEL_FROM_DATABASE=PCM2912A Audio Codec
+
usb:v08BBp29B0*
ID_MODEL_FROM_DATABASE=PCM2900B Audio CODEC
@@ -32024,6 +32291,9 @@ usb:v091Ep255B*
usb:v091Ep26A1*
ID_MODEL_FROM_DATABASE=Nuvi 55
+usb:v091Ep47FB*
+ ID_MODEL_FROM_DATABASE=nuviCam
+
usb:v0920*
ID_VENDOR_FROM_DATABASE=Echelon Co.
@@ -32078,6 +32348,9 @@ usb:v0924p3CE8*
usb:v0924p3CEA*
ID_MODEL_FROM_DATABASE=Phaser 3125
+usb:v0924p3CEC*
+ ID_MODEL_FROM_DATABASE=Phaser 3250
+
usb:v0924p3D5B*
ID_MODEL_FROM_DATABASE=Phaser 6115MFP TWAIN Scanner
@@ -32444,9 +32717,24 @@ usb:v0934*
usb:v0936*
ID_VENDOR_FROM_DATABASE=NuTesla
+usb:v0936p000A*
+ ID_MODEL_FROM_DATABASE=Moebius
+
+usb:v0936p000B*
+ ID_MODEL_FROM_DATABASE=iMoebius
+
usb:v0936p000C*
ID_MODEL_FROM_DATABASE=Rhythmedics 6 BioData Integrator
+usb:v0936p000D*
+ ID_MODEL_FROM_DATABASE=Hypurius
+
+usb:v0936p000E*
+ ID_MODEL_FROM_DATABASE=Millennius
+
+usb:v0936p000F*
+ ID_MODEL_FROM_DATABASE=Purius
+
usb:v0936p0030*
ID_MODEL_FROM_DATABASE=Composite Device, Mass Storage Device (Flash Drive) amd HID
@@ -32753,6 +33041,9 @@ usb:v0954*
usb:v0955*
ID_VENDOR_FROM_DATABASE=NVidia Corp.
+usb:v0955p7018*
+ ID_MODEL_FROM_DATABASE=APX
+
usb:v0955p7030*
ID_MODEL_FROM_DATABASE=Tegra 3 (recovery mode)
@@ -33263,6 +33554,12 @@ usb:v09D7*
usb:v09D7p0100*
ID_MODEL_FROM_DATABASE=NovAtel FlexPack GPS receiver
+usb:v09D8*
+ ID_VENDOR_FROM_DATABASE=ELATEC
+
+usb:v09D8p0406*
+ ID_MODEL_FROM_DATABASE=TWN4 MIFARE NFC
+
usb:v09D9*
ID_VENDOR_FROM_DATABASE=KRF Tech, Ltd
@@ -35250,7 +35547,7 @@ usb:v0B05p5412*
ID_MODEL_FROM_DATABASE=MeMO Pad HD 7 (PTP mode)
usb:v0B05p550F*
- ID_MODEL_FROM_DATABASE=ASUS fonepad 7
+ ID_MODEL_FROM_DATABASE=Fonepad 7
usb:v0B05p6101*
ID_MODEL_FROM_DATABASE=Cable Modem
@@ -35258,6 +35555,24 @@ usb:v0B05p6101*
usb:v0B05p620A*
ID_MODEL_FROM_DATABASE=Remote NDIS Device
+usb:v0B05p7772*
+ ID_MODEL_FROM_DATABASE=ASUS Zenfone GO (ZB500KL) (MTP mode)
+
+usb:v0B05p7773*
+ ID_MODEL_FROM_DATABASE=ASUS Zenfone GO (ZB500KL) (Debug, MTP mode)
+
+usb:v0B05p7774*
+ ID_MODEL_FROM_DATABASE=ASUS Zenfone GO (ZB500KL) (RNDIS mode)
+
+usb:v0B05p7775*
+ ID_MODEL_FROM_DATABASE=ASUS Zenfone GO (ZB500KL) (Debug, RNDIS mode)
+
+usb:v0B05p7776*
+ ID_MODEL_FROM_DATABASE=ASUS Zenfone GO (ZB500KL) (PTP mode)
+
+usb:v0B05p7777*
+ ID_MODEL_FROM_DATABASE=ASUS Zenfone GO (ZB500KL) (Debug, PTP mode)
+
usb:v0B05pB700*
ID_MODEL_FROM_DATABASE=Broadcom Bluetooth 2.1
@@ -36599,6 +36914,9 @@ usb:v0BC2p2320*
usb:v0BC2p2321*
ID_MODEL_FROM_DATABASE=Expansion Portable
+usb:v0BC2p2322*
+ ID_MODEL_FROM_DATABASE=SRD0NF1 Expansion Portable (STEA)
+
usb:v0BC2p2340*
ID_MODEL_FROM_DATABASE=FreeAgent External Hard Drive
@@ -36653,6 +36971,9 @@ usb:v0BC2p5121*
usb:v0BC2p5161*
ID_MODEL_FROM_DATABASE=FreeAgent GoFlex dock
+usb:v0BC2p61B7*
+ ID_MODEL_FROM_DATABASE=Maxtor M3 Portable
+
usb:v0BC2pA003*
ID_MODEL_FROM_DATABASE=Backup Plus
@@ -36680,6 +37001,9 @@ usb:v0BC2pAB31*
usb:v0BC2pAB34*
ID_MODEL_FROM_DATABASE=Backup Plus
+usb:v0BC2pAB38*
+ ID_MODEL_FROM_DATABASE=Backup Plus Hub
+
usb:v0BC3*
ID_VENDOR_FROM_DATABASE=IPWireless, Inc.
@@ -36887,6 +37211,9 @@ usb:v0BDAp570C*
usb:v0BDAp5730*
ID_MODEL_FROM_DATABASE=HP 2.0MP High Definition Webcam
+usb:v0BDAp5751*
+ ID_MODEL_FROM_DATABASE=Integrated Webcam
+
usb:v0BDAp5775*
ID_MODEL_FROM_DATABASE=HP "Truevision HD" laptop camera
@@ -37109,6 +37436,12 @@ usb:v0BFDp000B*
usb:v0BFDp000E*
ID_MODEL_FROM_DATABASE=Leaf SemiPro HS
+usb:v0C00*
+ ID_VENDOR_FROM_DATABASE=FireFly Mouse Mat
+
+usb:v0C00p1607*
+ ID_MODEL_FROM_DATABASE=Apex M500
+
usb:v0C04*
ID_VENDOR_FROM_DATABASE=MOTO Development Group, Inc.
@@ -37808,6 +38141,9 @@ usb:v0C45p648B*
usb:v0C45p64BD*
ID_MODEL_FROM_DATABASE=Sony Visual Communication Camera
+usb:v0C45p64D0*
+ ID_MODEL_FROM_DATABASE=Integrated Webcam
+
usb:v0C45p64D2*
ID_MODEL_FROM_DATABASE=Integrated Webcam
@@ -38333,8 +38669,14 @@ usb:v0CA7*
usb:v0CAD*
ID_VENDOR_FROM_DATABASE=Motorola CGISS
+usb:v0CADp1007*
+ ID_MODEL_FROM_DATABASE=APX Series Consolette
+
usb:v0CADp1030*
- ID_MODEL_FROM_DATABASE=APX Series Radio
+ ID_MODEL_FROM_DATABASE=APX Series Radio (Portable)
+
+usb:v0CADp1031*
+ ID_MODEL_FROM_DATABASE=APX Series Radio (Mobile)
usb:v0CADp1602*
ID_MODEL_FROM_DATABASE=IMPRES Battery Data Reader
@@ -38585,6 +38927,18 @@ usb:v0CD5p0003*
usb:v0CD5p0009*
ID_MODEL_FROM_DATABASE=UE9
+usb:v0CD6*
+ ID_VENDOR_FROM_DATABASE=Scheidt & Bachmann
+
+usb:v0CD6p000C*
+ ID_MODEL_FROM_DATABASE=S&B TPU
+
+usb:v0CD6p000E*
+ ID_MODEL_FROM_DATABASE=S&B BKV
+
+usb:v0CD6p0011*
+ ID_MODEL_FROM_DATABASE=Money Coin Unit
+
usb:v0CD7*
ID_VENDOR_FROM_DATABASE=NewChip S.r.l.
@@ -38921,6 +39275,9 @@ usb:v0D16p0002*
usb:v0D16p0004*
ID_MODEL_FROM_DATABASE=Photo Printer 63xPL/PS
+usb:v0D16p000E*
+ ID_MODEL_FROM_DATABASE=P910L
+
usb:v0D16p0100*
ID_MODEL_FROM_DATABASE=Photo Printer 63xPL/PS
@@ -39633,7 +39990,7 @@ usb:v0D99*
ID_VENDOR_FROM_DATABASE=Trazer Technologies, Inc.
usb:v0D9A*
- ID_VENDOR_FROM_DATABASE=RTX Telecom AS
+ ID_VENDOR_FROM_DATABASE=RTX AS
usb:v0D9Ap0001*
ID_MODEL_FROM_DATABASE=Bluetooth Device
@@ -40325,6 +40682,9 @@ usb:v0DFC*
usb:v0DFCp0001*
ID_MODEL_FROM_DATABASE=Touchscreen
+usb:v0DFCp0101*
+ ID_MODEL_FROM_DATABASE=5-point Touch Screen
+
usb:v0E03*
ID_VENDOR_FROM_DATABASE=Nippon Systemware Co., Ltd
@@ -41636,6 +41996,9 @@ usb:v0FCAp8011*
usb:v0FCAp8020*
ID_MODEL_FROM_DATABASE=Blackberry Playbook (CD-Rom mode)
+usb:v0FCAp8037*
+ ID_MODEL_FROM_DATABASE=Blackberry PRIV
+
usb:v0FCE*
ID_VENDOR_FROM_DATABASE=Sony Ericsson Mobile Communications AB
@@ -42212,6 +42575,9 @@ usb:v1004p631E*
usb:v1004p631F*
ID_MODEL_FROM_DATABASE=Optimus Android Phone (Charge Mode)
+usb:v1004p633A*
+ ID_MODEL_FROM_DATABASE=Ultimate 2 Android Phone L41C
+
usb:v1004p633E*
ID_MODEL_FROM_DATABASE=G2/G3 Android Phone [MTP/PTP/Download mode]
@@ -42851,6 +43217,9 @@ usb:v1058p1230*
usb:v1058p1235*
ID_MODEL_FROM_DATABASE=My Book (WDBFJK0040HBK)
+usb:v1058p2599*
+ ID_MODEL_FROM_DATABASE=My Passport Ultra (WD40NMZW)
+
usb:v1058p259D*
ID_MODEL_FROM_DATABASE=My Passport Ultra (WDBBKD)
@@ -50873,15 +51242,57 @@ usb:v1B1Cp0A00*
usb:v1B1Cp0A60*
ID_MODEL_FROM_DATABASE=Vengeance K60 Keyboard
+usb:v1B1Cp0C04*
+ ID_MODEL_FROM_DATABASE=Link Cooling Node
+
usb:v1B1Cp1A01*
ID_MODEL_FROM_DATABASE=Flash Voyager GT
+usb:v1B1Cp1A03*
+ ID_MODEL_FROM_DATABASE=Voyager 3.0
+
+usb:v1B1Cp1A09*
+ ID_MODEL_FROM_DATABASE=Voyager GT 3.0
+
usb:v1B1Cp1A0A*
ID_MODEL_FROM_DATABASE=Survivor Stealth Flash Drive
+usb:v1B1Cp1A0B*
+ ID_MODEL_FROM_DATABASE=Flash Voyager LS
+
+usb:v1B1Cp1A15*
+ ID_MODEL_FROM_DATABASE=Voyager Slider Flash Drive
+
usb:v1B1Cp1A90*
ID_MODEL_FROM_DATABASE=Flash Voyager GT
+usb:v1B1Cp1AB1*
+ ID_MODEL_FROM_DATABASE=Voyager
+
+usb:v1B1Cp1B04*
+ ID_MODEL_FROM_DATABASE=Raptor K50 Keyboard
+
+usb:v1B1Cp1B07*
+ ID_MODEL_FROM_DATABASE=Vengeance K65 Gaming Keyboard
+
+usb:v1B1Cp1B08*
+ ID_MODEL_FROM_DATABASE=Vengeance K95 Keyboard
+
+usb:v1B1Cp1B09*
+ ID_MODEL_FROM_DATABASE=Vengeance K70R keyboard
+
+usb:v1B1Cp1B11*
+ ID_MODEL_FROM_DATABASE=K95 RGB Mechanical Gaming Keyboard
+
+usb:v1B1Cp1B13*
+ ID_MODEL_FROM_DATABASE=Vengeance K70RGB keyboard
+
+usb:v1B1Cp1C00*
+ ID_MODEL_FROM_DATABASE=Controller for Corsair Link
+
+usb:v1B1Cp1C0C*
+ ID_MODEL_FROM_DATABASE=RM850i Power Supply
+
usb:v1B1F*
ID_VENDOR_FROM_DATABASE=eQ-3 Entwicklung GmbH
@@ -52544,6 +52955,15 @@ usb:v1D90*
usb:v1D90p201E*
ID_MODEL_FROM_DATABASE=PPU-700
+usb:v1D9D*
+ ID_VENDOR_FROM_DATABASE=Sigma Sport
+
+usb:v1D9Dp1010*
+ ID_MODEL_FROM_DATABASE=Docking Station Topline 2009
+
+usb:v1D9Dp1011*
+ ID_MODEL_FROM_DATABASE=Docking Station Topline 2012
+
usb:v1DE1*
ID_VENDOR_FROM_DATABASE=Actions Microelectronics Co.
@@ -54374,6 +54794,27 @@ usb:v2735p1043*
usb:v2735p1044*
ID_MODEL_FROM_DATABASE=HCT HMD-180A
+usb:v273F*
+ ID_VENDOR_FROM_DATABASE=Hughski Limited
+
+usb:v273Fp1000*
+ ID_MODEL_FROM_DATABASE=ColorHug bootloader
+
+usb:v273Fp1001*
+ ID_MODEL_FROM_DATABASE=ColorHug
+
+usb:v273Fp1002*
+ ID_MODEL_FROM_DATABASE=ColorHug+
+
+usb:v273Fp1003*
+ ID_MODEL_FROM_DATABASE=ColorHug+ Bootloader
+
+usb:v273Fp1004*
+ ID_MODEL_FROM_DATABASE=ColorHug2
+
+usb:v273Fp1005*
+ ID_MODEL_FROM_DATABASE=ColorHug2 bootloader
+
usb:v2770*
ID_VENDOR_FROM_DATABASE=NHJ, Ltd
@@ -54620,6 +55061,12 @@ usb:v2C1A*
usb:v2C1Ap0000*
ID_MODEL_FROM_DATABASE=Wireless Optical Mouse
+usb:v2DCF*
+ ID_VENDOR_FROM_DATABASE=Dialog Semiconductor
+
+usb:v2DCFpC952*
+ ID_MODEL_FROM_DATABASE=Audio Class 2.0 Devices
+
usb:v2FB2*
ID_VENDOR_FROM_DATABASE=Fujitsu, Ltd
diff --git a/hwdb/60-evdev.hwdb b/hwdb/60-evdev.hwdb
index 0b692a1b5d..fd9078393b 100644
--- a/hwdb/60-evdev.hwdb
+++ b/hwdb/60-evdev.hwdb
@@ -15,7 +15,7 @@
# To add local entries, create a new file
# /etc/udev/hwdb.d/61-evdev-local.hwdb
# and add your rules there. To load the new rules execute (as root):
-# udevadm hwdb --update
+# systemd-hwdb update
# udevadm trigger /dev/input/eventXX
# where /dev/input/eventXX is the device in question. If in
# doubt, simply use /dev/input/event* to reload all input rules.
@@ -93,6 +93,14 @@ evdev:input:b0003v05ACp025B*
#########################################
# ASUS
#########################################
+
+# Asus VivoBook E402SA
+evdev:name:Elan Touchpad:dmi:*svnASUSTeKCOMPUTERINC.:pnE402SA*
+ EVDEV_ABS_00=::29
+ EVDEV_ABS_01=::29
+ EVDEV_ABS_35=::29
+ EVDEV_ABS_36=::29
+
# Asus K52JT
evdev:name:ETPS/2 Elantech Touchpad:dmi:bvn*:bvr*:bd*:svnASUSTeKComputerInc.:pnK52JT:*
EVDEV_ABS_00=::18
@@ -100,7 +108,8 @@ evdev:name:ETPS/2 Elantech Touchpad:dmi:bvn*:bvr*:bd*:svnASUSTeKComputerInc.:pnK
EVDEV_ABS_35=::18
EVDEV_ABS_36=::16
-evdev:name:ETPS/2 Elantech Touchpad:dmi:*:svnASUSTeKCOMPUTERINC.:pnX550CC:*
+# Asus X550CC and S550CB
+evdev:name:ETPS/2 Elantech Touchpad:dmi:*:svnASUSTeKCOMPUTERINC.:pn?550C?:*
EVDEV_ABS_00=::31
EVDEV_ABS_01=::30
EVDEV_ABS_35=::31
@@ -136,6 +145,13 @@ evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLati
EVDEV_ABS_35=76:1815:22
EVDEV_ABS_36=131:1330:30
+# Dell Latitude E6320
+evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE6320*
+ EVDEV_ABS_00=79:1841:22
+ EVDEV_ABS_01=140:1325:29
+ EVDEV_ABS_35=79:1841:22
+ EVDEV_ABS_36=140:1325:29
+
# Dell Precision 5510
evdev:name:SynPS/2 Synaptics TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnPrecision5510*
EVDEV_ABS_00=::42
@@ -184,10 +200,31 @@ evdev:name:SynPS/2 Synaptics TouchPad*:dmi:*svnHewlett-Packard:pnHPPaviliondm4*
EVDEV_ABS_35=1360:5563:47
EVDEV_ABS_36=1269:4618:61
+# HP Pavilion dv7
+evdev:name:SynPS/2 Synaptics TouchPad*:dmi:*svnHewlett-Packard:pnHPPaviliondv7*
+ EVDEV_ABS_00=1068:5805:44
+ EVDEV_ABS_01=1197:4890:57
+ EVDEV_ABS_35=1068:5805:44
+ EVDEV_ABS_36=1197:4890:57
+
+# HP Spectre
+evdev:name:SynPS/2 Synaptics TouchPad:dmi:i*svnHP:pnHPSpectreNotebook*
+ EVDEV_ABS_00=1205:5691:47
+ EVDEV_ABS_01=1083:4808:65
+ EVDEV_ABS_35=1205:5691:47
+ EVDEV_ABS_36=1083:4808:65
+
#########################################
# Lenovo
#########################################
+# Lenovo B590
+evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pvrLenovoB590*
+ EVDEV_ABS_00=1243:5759:48
+ EVDEV_ABS_01=1130:4832:65
+ EVDEV_ABS_35=1243:5759:48
+ EVDEV_ABS_36=1130:4832:65
+
# Lenovo E530
evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:pn*ThinkPadEdgeE530*
EVDEV_ABS_00=1241:5703:49
@@ -217,6 +254,20 @@ evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pvrThinkPad??40?:*
EVDEV_ABS_35=::41
EVDEV_ABS_36=::37
+# Lenovo ThinkPad T430
+evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pvrThinkPadT430*
+ EVDEV_ABS_00=1250:5631:58
+ EVDEV_ABS_01=1309:4826:78
+ EVDEV_ABS_35=1250:5631:58
+ EVDEV_ABS_36=1309:4826:78
+
+# Lenovo Thinkpad Carbon X1 4th gen. and X1 Yoga 1st gen.
+evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pvrThinkPadX1Carbon4th*
+ EVDEV_ABS_00=1262:5679:44
+ EVDEV_ABS_01=1101:4824:65
+ EVDEV_ABS_35=1262:5679:44
+ EVDEV_ABS_36=1101:4824:65
+
# Lenovo T460
evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pn*ThinkPad*T460*
EVDEV_ABS_00=1266:5677:44
@@ -236,6 +287,13 @@ evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*pvrLenovoV360*
EVDEV_ABS_00=1243:5927:60
EVDEV_ABS_01=902:5330:108
+# Lenovo W530
+evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*pvrThinkPadW530*
+ EVDEV_ABS_00=1250:5631:59
+ EVDEV_ABS_01=1205:4834:81
+ EVDEV_ABS_35=1250:5631:59
+ EVDEV_ABS_36=1205:4834:81
+
# Lenovo X220 series
evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*pvrThinkPadX220*
EVDEV_ABS_00=1316:5627:58
@@ -279,3 +337,12 @@ evdev:name:ETPS/2 Elantech Touchpad:dmi:*svnSAMSUNGELECTRONICSCO.,LTD.:pn305V4A/
EVDEV_ABS_01=0:1116:24
EVDEV_ABS_35=0:2480:28
EVDEV_ABS_36=0:1116:24
+
+#########################################
+# Toshiba
+#########################################
+
+# Toshiba Tecra M11
+evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:*svnTOSHIBA:pnTECRAM11*
+ EVDEV_ABS_00=90:962:11
+ EVDEV_ABS_01=51:681:14
diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb
index 9c87aecd30..1aa729f047 100644
--- a/hwdb/60-keyboard.hwdb
+++ b/hwdb/60-keyboard.hwdb
@@ -4,7 +4,7 @@
# scan codes to add to the AT keyboard's 'force-release' list.
#
# The lookup keys are composed in:
-# 60-keyboard.rules
+# 60-evdev.rules
#
# Note: The format of the "evdev:" prefix match key is a
# contract between the rules file and the hardware data, it might
@@ -18,17 +18,28 @@
# ZZZZ is the bus-id (see /usr/include/linux/input.h BUS_*), YYYY, XXXX and
# WWW are the 4-digit hex uppercase vendor, product and version ID and VVVV
# is an arbitrary length input-modalias describing the device capabilities.
+# The vendor, product and version ID for a device node "eventX" is listed
+# in /sys/class/input/eventX/device/id.
#
# - AT keyboard DMI data matches:
# evdev:atkbd:dmi:bvn*:bvr*:bd*:svn<vendor>:pn<product>:pvr*
# <vendor> and <product> are the firmware-provided strings
-# exported by the kernel DMI modalias.
+# exported by the kernel DMI modalias, see /sys/class/dmi/id/modalias
#
# - Input driver device name and DMI data match:
# evdev:name:<input device name>:dmi:bvn*:bvr*:bd*:svn<vendor>:pn*
# <input device name> is the name device specified by the
# driver, <vendor> is the firmware-provided string exported
-# by the kernel DMI modalias.
+# by the kernel DMI modalias, see /sys/class/dmi/id/modalias
+#
+# - Extended input driver device name, properties and DMI data match:
+# evdev:name:<input device name>:phys:<phys>:ev:<ev>:dmi:bvn*:bvr*:bd*:svn<vendor>:pn*
+# <input device name> is the name device specified by the
+# driver, <phys> is the physical-device-path, "cat
+# /sys/class/input/input?/phys", <ev> is the event bitmask, "cat
+# /sys/class/input/input?/capabilities/ev" and <vendor> is the
+# firmware-provided string exported by the kernel DMI modalias,
+# see /sys/class/dmi/id/modalias
#
# Scan codes are specified as:
# KEYBOARD_KEY_<hex scan code>=<key code identifier>
@@ -42,11 +53,18 @@
#
# To debug key presses and access scan code mapping data of
# an input device use the commonly available tool: evtest(1).
+
+# A device with a fixed keyboard layout that must not be changed by
+# the desktop environment may specify that layout as:
+# XKB_FIXED_LAYOUT="us"
+# XKB_FIXED_VARIANT=""
+# Examples of such devices: the Yubikey or other key-code generating
+# devices.
#
# To update this file, create a new file
# /etc/udev/hwdb.d/70-keyboard.hwdb
# and add your rules there. To load the new rules execute (as root):
-# udevadm hwdb --update
+# systemd-hwdb update
# udevadm trigger /dev/input/eventXX
# where /dev/input/eventXX is the keyboard in question. If in
# doubt, simply use /dev/input/event* to reload all input rules.
@@ -115,6 +133,9 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*8930:*
KEYBOARD_KEY_89=fastforward
KEYBOARD_KEY_9e=back
+evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*7750G:pvr*
+ KEYBOARD_KEY_e0=!pageup
+
# Travelmate C300
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*C3[01]0*:pvr*
KEYBOARD_KEY_67=f24 # FIXME: rotate screen
@@ -197,6 +218,14 @@ evdev:input:b0003v049Fp0051*
KEYBOARD_KEY_0c0015=messenger
###########################################################
+# Cube
+###########################################################
+
+evdev:name:gpio-keys:phys:gpio-keys/input0:ev:3:dmi:bvn*:bvr*:bd*:svncube:pni1-TF:*
+ KEYBOARD_KEY_0=home
+ KEYBOARD_KEY_1=power
+
+###########################################################
# Dell
###########################################################
@@ -275,7 +304,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnXPS12-9Q33*:pvr*
evdev:name:Dell WMI hotkeys:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*
# Dell Precision microphone mute
evdev:name:Dell WMI hotkeys:dmi:bvn*:bvr*:bd*:svnDell*:pnPrecision*
- KEYBOARD_KEY_150=f20 # Mic mute toggle, should be micmute
+ KEYBOARD_KEY_100150=f20 # Mic mute toggle, should be micmute
###########################################################
# Everex
@@ -415,6 +444,10 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*Pavilion*dv7*Notebook*PC:
KEYBOARD_KEY_c6=break
KEYBOARD_KEY_94=reserved
+# Pavilion x360 13 (Prevents random airplane mode activation)
+evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[pP][aA][vV][iI][lL][iI][oO][nN]*13*x360*:pvr*
+ KEYBOARD_KEY_d7=unknown
+
# Elitebook
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*Compaq*:pvr*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*EliteBook*:pvr*
@@ -858,6 +891,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*:pvr*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*U-100*:pvr*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*U100*:pvr*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*N033:*
+evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*VR420*:pvr*
KEYBOARD_KEY_f7=reserved
KEYBOARD_KEY_f8=reserved
@@ -1239,3 +1273,18 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDIXONSP:pnDIXON*:pvr*
KEYBOARD_KEY_a0=! # mute
KEYBOARD_KEY_ae=! # volume down
KEYBOARD_KEY_b0=! # volume up
+
+###########################################################
+# Fixed layout devices
+###########################################################
+
+# Yubico Yubico Yubikey II"
+evdev:input:b0003v1050p0010*
+# Yubico Yubikey NEO OTP+CCID
+evdev:input:b0003v1050p0111*
+# Yubico Yubikey NEO OTP+U2F+CCID
+evdev:input:b0003v1050p0116*
+# OKE Electron Company USB barcode reader
+evdev:input:b0003v05FEp1010*
+ XKB_FIXED_LAYOUT="us"
+ XKB_FIXED_VARIANT=""
diff --git a/hwdb/60-sensor.hwdb b/hwdb/60-sensor.hwdb
new file mode 100644
index 0000000000..fcbdcabf30
--- /dev/null
+++ b/hwdb/60-sensor.hwdb
@@ -0,0 +1,54 @@
+# This file is part of systemd.
+#
+# The lookup keys are composed in:
+# 60-sensor.rules
+#
+# Note: The format of the "sensor:" prefix match key is a
+# contract between the rules file and the hardware data, it might
+# change in later revisions to support more or better matches, it
+# is not necessarily expected to be a stable ABI.
+#
+# Match string formats:
+# sensor:modalias:<parent device modalias>:dmi:<dmi string>
+#
+# To add local entries, create a new file
+# /etc/udev/hwdb.d/61-sensor-local.hwdb
+# and add your rules there. To load the new rules execute (as root):
+# systemd-hwdb update
+# udevadm trigger -y `dirname $(udevadm info -n "/dev/iio:deviceXXX" -q path)`
+# where /dev/iio:deviceXXX is the device in question.
+#
+# If your changes are generally applicable, preferably send them as a pull
+# request to
+# https://github.com/systemd/systemd
+# or create a bug report on https://github.com/systemd/systemd/issues and
+# include your new rules, a description of the device, and the output of
+# udevadm info --export-db
+#
+# For hwdb format and systemd behavior:
+# https://www.freedesktop.org/software/systemd/man/hwdb.html
+#
+# Allowed properties are:
+# ACCEL_MOUNT_MATRIX=<matrix>
+#
+# where <matrix> is a mount-matrix in the format specified in the IIO
+# subsystem[1]. The default, when unset, is equivalent to:
+# ACCEL_MOUNT_MATRIX=1, 0, 0; 0, 1, 0; 0, 0, 1
+# eg. the identity matrix.
+#
+# [1]: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=dfc57732ad38f93ae6232a3b4e64fd077383a0f1
+#
+#
+# Sort by brand, model
+
+#########################################
+# AsusTek
+#########################################
+sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP500LB*
+ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 0
+
+#########################################
+# Winbook
+#########################################
+sensor:modalias:acpi:BMA250*:dmi:*svn*WinBook*:*pn*TW100*
+ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 0
diff --git a/hwdb/70-mouse.hwdb b/hwdb/70-mouse.hwdb
index bf3d134c46..772534f495 100644
--- a/hwdb/70-mouse.hwdb
+++ b/hwdb/70-mouse.hwdb
@@ -31,7 +31,7 @@
# To add local entries, create a new file
# /etc/udev/hwdb.d/71-mouse-local.hwdb
# and add your rules there. To load the new rules execute (as root):
-# udevadm hwdb --update
+# systemd-hwdb update
# udevadm trigger /dev/input/eventXX
# where /dev/input/eventXX is the mouse in question. If in
# doubt, simply use /dev/input/event* to reload all input rules.
@@ -50,6 +50,8 @@
# MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL
# MOUSE_WHEEL_CLICK_COUNT
# MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL
+# MOUSE_WHEEL_TILT_HORIZONTAL
+# MOUSE_WHEEL_TILT_VERTICAL
#
#########################################
# ID_INPUT_TRACKBALL #
@@ -134,6 +136,26 @@
# MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL works the same way but also follows the
# rules of MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL.
+#########################################
+# MOUSE_WHEEL_TILT_HORIZONTAL #
+# MOUSE_WHEEL_TILT_VERTICAL #
+#########################################
+#
+# Indicates that the respective axis is not a mouse wheel rotation but a
+# tilt along that axis. Wheel tilt is most commonly used for horizontal
+# scroll wheel emulation on mice with only a single vertical wheel.
+#
+# The vertical and horizontal Axes are independently marked as tilt axes,
+# for example it is permitted to have a MOUSE_WHEEL_CLICK_COUNT or
+# MOUSE_WHEEL_CLICK_ANGLE for the vertical axis and mark the horizontal axis
+# marked as as MOUSE_WHEEL_TILT_HORIZONTAL.
+#
+# It is a bug to have either CLICK_COUNT or CLICK_ANGLE set on the same axis
+# as WHEEL_TILT. Applications should give priority to WHEEL_TILT and ignore
+# other settings.
+#
+# This is a flag only, permitted values: 0 or 1
+
#
# Sort by brand, type (usb, bluetooth), DPI, frequency.
# For mice with switchable resolution, sort by the starred entry.
@@ -346,6 +368,10 @@ mouse:usb:v046dpc24c:name:Logitech G400s Optical Gaming Mouse:
mouse:usb:v046dpc07e:name:Logitech Gaming Mouse G402:
MOUSE_DPI=400@1000 *800@1000 1600@1000 3200@1000
+# Logitech G502 Proteus Spectrum
+mouse:usb:v046dpc332:name:Logitech Gaming Mouse G502:
+ MOUSE_DPI=1200@1000 *2400@1000 3200@1000 6400@1000
+
# Logitech B605 Wireless Mouse (also M505)
mouse:usb:v046dp101d:name:Logitech B605:
mouse:usb:v046dp101d:name:Logitech M505:
@@ -416,6 +442,10 @@ mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:4026:
mouse:usb:v046dpc068:name:Logitech G500:
MOUSE_DPI=*1600@500 2600@500 3600@500
+# Logitech TrackMan Wheel (USB)
+mouse:usb:v046dpc404:name:Logitech Trackball:
+ MOUSE_DPI=300@125
+
# Logitech MX1000 Laser Cordless Mouse
mouse:bluetooth:v046dpb003:name:Logitech MX1000 mouse:
MOUSE_DPI=800@80
@@ -464,6 +494,10 @@ mouse:bluetooth:v045ep0702:name:Microsoft Wireless Laser Mouse 8000:
mouse:bluetooth:v045ep07f3:name:Arc Touch Mouse SE:
MOUSE_DPI=1000@2000
+# Microsoft Surface Mouse
+mouse:bluetooth:v0000p0000:name:Surface Mouse:
+ MOUSE_DPI=2000@2000
+
##########################################
# Mionix
##########################################
@@ -497,6 +531,10 @@ mouse:bluetooth:v056ep0061:name:Laser BTmouse:
mouse:usb:v1532p0042:name:Razer Razer Abyssus:
MOUSE_DPI=3500@1000
+# Razer DeathAdder Black Edition
+mouse:usb:v1532p0029:name:Razer Razer DeathAdder:
+ MOUSE_DPI=3500@1000
+
##########################################
# Roccat
##########################################
diff --git a/hwdb/70-pointingstick.hwdb b/hwdb/70-pointingstick.hwdb
index e18ef28290..65c87aeac7 100644
--- a/hwdb/70-pointingstick.hwdb
+++ b/hwdb/70-pointingstick.hwdb
@@ -18,16 +18,19 @@
# ZZZZ is the bus-id (see /usr/include/linux/input.h BUS_*), YYYY, XXXX and
# WWW are the 4-digit hex uppercase vendor, product and version ID and VVVV
# is an arbitrary length input-modalias describing the device capabilities.
+# The vendor, product and version ID for a device node "eventX" is listed
+# in /sys/class/input/eventX/device/id.
#
# - Input driver device name and DMI data match:
# evdev:name:<input device name>:dmi:bvn*:bvr*:bd*:svn<vendor>:pn*
# <input device name> is the name device specified by the driver,
-# <vendor> is the firmware-provided string from the kernel DMI modalias.
+# <vendor> is the firmware-provided string from the kernel DMI modalias,
+# see /sys/class/dmi/id/modalias
#
# To add local entries, create a new file
# /etc/udev/hwdb.d/71-pointingstick-local.hwdb
# and add your rules there. To load the new rules execute (as root):
-# udevadm hwdb --update
+# systemd-hwdb update
# udevadm trigger /dev/input/eventXX
# where /dev/input/eventXX is the pointingstick in question. If in
# doubt, simply use /dev/input/event* to reload all input rules.
@@ -79,6 +82,10 @@
evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeD620*:pvr*
POINTINGSTICK_CONST_ACCEL=0.5
+# Latitude E5570
+evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE5570*:pvr*
+ POINTINGSTICK_CONST_ACCEL=0.1
+
# Latitude E6320
evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE6320*:pvr*
POINTINGSTICK_CONST_ACCEL=2.0
@@ -95,6 +102,8 @@ evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE7470*:pvr*
# Lenovo
#########################################
+# Lenovo Thinkpad X220
+evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX220:*
# Lenovo Thinkpad X230
evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX230:*
# Lenovo Thinkpad X230 tablet
diff --git a/hwdb/70-touchpad.hwdb b/hwdb/70-touchpad.hwdb
index 11f3f96f04..82a4b7a575 100644
--- a/hwdb/70-touchpad.hwdb
+++ b/hwdb/70-touchpad.hwdb
@@ -18,7 +18,7 @@
# To add local entries, create a new file
# /etc/udev/hwdb.d/71-touchpad-local.hwdb
# and add your rules there. To load the new rules execute (as root):
-# udevadm hwdb --update
+# systemd-hwdb update
# udevadm trigger /dev/input/eventXX
# where /dev/input/eventXX is the touchpad in question. If in
# doubt, simply use /dev/input/event* to reload all input rules.
@@ -47,3 +47,9 @@ touchpad:usb:*
###########################################################
touchpad:usb:v05ac*
ID_INPUT_TOUCHPAD_INTEGRATION=internal
+
+###########################################################
+# Wacom
+###########################################################
+touchpad:usb:v056a*
+ ID_INPUT_TOUCHPAD_INTEGRATION=external
diff --git a/hwdb/acpi-update.py b/hwdb/acpi-update.py
index 2dc8c7c064..50da531dc6 100755
--- a/hwdb/acpi-update.py
+++ b/hwdb/acpi-update.py
@@ -31,7 +31,7 @@ class PNPTableParser(HTMLParser):
elif self.state == State.AFTER_PNPID:
self.state = State.DATE
else:
- raise Error("Unexpected field")
+ raise ValueError
self.data = ""
@@ -48,7 +48,7 @@ class PNPTableParser(HTMLParser):
elif self.state == State.DATE:
self.state = State.NOWHERE
else:
- raise Error("Unexpected field")
+ raise ValueError
def handle_data(self, data):
self.data += data
diff --git a/hwdb/parse_hwdb.py b/hwdb/parse_hwdb.py
index 5d4c5ea64d..b57e6f75aa 100755
--- a/hwdb/parse_hwdb.py
+++ b/hwdb/parse_hwdb.py
@@ -26,7 +26,6 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
-import functools
import glob
import string
import sys
@@ -35,9 +34,9 @@ import os
try:
from pyparsing import (Word, White, Literal, ParserElement, Regex,
LineStart, LineEnd,
- ZeroOrMore, OneOrMore, Combine, Or, Optional, Suppress, Group,
+ OneOrMore, Combine, Or, Optional, Suppress, Group,
nums, alphanums, printables,
- stringEnd, pythonStyleComment,
+ stringEnd, pythonStyleComment, QuotedString,
ParseBaseException)
except ImportError:
print('pyparsing is not available')
@@ -56,17 +55,20 @@ except ImportError:
lru_cache = lambda: (lambda f: f)
EOL = LineEnd().suppress()
-EMPTYLINE = LineStart() + LineEnd()
+EMPTYLINE = LineEnd()
COMMENTLINE = pythonStyleComment + EOL
INTEGER = Word(nums)
+STRING = QuotedString('"')
REAL = Combine((INTEGER + Optional('.' + Optional(INTEGER))) ^ ('.' + INTEGER))
+SIGNED_REAL = Combine(Optional(Word('-+')) + REAL)
UDEV_TAG = Word(string.ascii_uppercase, alphanums + '_')
TYPES = {'mouse': ('usb', 'bluetooth', 'ps2', '*'),
'evdev': ('name', 'atkbd', 'input'),
'touchpad': ('i8042', 'rmi', 'bluetooth', 'usb'),
'keyboard': ('name', ),
- }
+ 'sensor': ('modalias', ),
+ }
@lru_cache()
def hwdb_grammar():
@@ -76,13 +78,13 @@ def hwdb_grammar():
for category, conn in TYPES.items())
matchline = Combine(prefix + Word(printables + ' ' + '®')) + EOL
propertyline = (White(' ', exact=1).suppress() +
- Combine(UDEV_TAG - '=' - Word(alphanums + '_=:@*.! ') - Optional(pythonStyleComment)) +
+ Combine(UDEV_TAG - '=' - Word(alphanums + '_=:@*.!-;, "') - Optional(pythonStyleComment)) +
EOL)
propertycomment = White(' ', exact=1) + pythonStyleComment + EOL
group = (OneOrMore(matchline('MATCHES*') ^ COMMENTLINE.suppress()) -
OneOrMore(propertyline('PROPERTIES*') ^ propertycomment.suppress()) -
- (EMPTYLINE ^ stringEnd()).suppress() )
+ (EMPTYLINE ^ stringEnd()).suppress())
commentgroup = OneOrMore(COMMENTLINE).suppress() - EMPTYLINE.suppress()
grammar = OneOrMore(group('GROUPS*') ^ commentgroup) + stringEnd()
@@ -93,29 +95,37 @@ def hwdb_grammar():
def property_grammar():
ParserElement.setDefaultWhitespaceChars(' ')
- setting = Optional('*')('DEFAULT') + INTEGER('DPI') + Suppress('@') + INTEGER('HZ')
- props = (('MOUSE_DPI', Group(OneOrMore(setting('SETTINGS*')))),
+ dpi_setting = (Optional('*')('DEFAULT') + INTEGER('DPI') + Suppress('@') + INTEGER('HZ'))('SETTINGS*')
+ mount_matrix_row = SIGNED_REAL + ',' + SIGNED_REAL + ',' + SIGNED_REAL
+ mount_matrix = (mount_matrix_row + ';' + mount_matrix_row + ';' + mount_matrix_row)('MOUNT_MATRIX')
+
+ props = (('MOUSE_DPI', Group(OneOrMore(dpi_setting))),
('MOUSE_WHEEL_CLICK_ANGLE', INTEGER),
('MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL', INTEGER),
('MOUSE_WHEEL_CLICK_COUNT', INTEGER),
('MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL', INTEGER),
('ID_INPUT_TRACKBALL', Literal('1')),
+ ('MOUSE_WHEEL_TILT_HORIZONTAL', Literal('1')),
+ ('MOUSE_WHEEL_TILT_VERTICAL', Literal('1')),
('POINTINGSTICK_SENSITIVITY', INTEGER),
('POINTINGSTICK_CONST_ACCEL', REAL),
('ID_INPUT_TOUCHPAD_INTEGRATION', Or(('internal', 'external'))),
- )
+ ('XKB_FIXED_LAYOUT', STRING),
+ ('XKB_FIXED_VARIANT', STRING),
+ ('ACCEL_MOUNT_MATRIX', mount_matrix),
+ )
fixed_props = [Literal(name)('NAME') - Suppress('=') - val('VALUE')
for name, val in props]
kbd_props = [Regex(r'KEYBOARD_KEY_[0-9a-f]+')('NAME')
- Suppress('=') -
('!' ^ (Optional('!') - Word(alphanums + '_')))('VALUE')
- ]
+ ]
abs_props = [Regex(r'EVDEV_ABS_[0-9a-f]{2}')('NAME')
- Suppress('=') -
Word(nums + ':')('VALUE')
- ]
+ ]
- grammar = Or(fixed_props + kbd_props + abs_props)
+ grammar = Or(fixed_props + kbd_props + abs_props) + EOL
return grammar
@@ -133,7 +143,8 @@ def convert_properties(group):
def parse(fname):
grammar = hwdb_grammar()
try:
- parsed = grammar.parseFile(fname)
+ with open(fname, 'r', encoding='UTF-8') as f:
+ parsed = grammar.parseFile(f)
except ParseBaseException as e:
error('Cannot parse {}: {}', fname, e)
return []
@@ -185,8 +196,7 @@ def print_summary(fname, groups):
.format(fname,
len(groups),
sum(len(matches) for matches, props in groups),
- sum(len(props) for matches, props in groups),
- ))
+ sum(len(props) for matches, props in groups)))
if __name__ == '__main__':
args = sys.argv[1:] or glob.glob(os.path.dirname(sys.argv[0]) + '/[67]0-*.hwdb')
diff --git a/man/50-xdg-data-dirs.sh b/man/50-xdg-data-dirs.sh
new file mode 100755
index 0000000000..073174cb40
--- /dev/null
+++ b/man/50-xdg-data-dirs.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+# set the default value
+XDG_DATA_DIRS="${XDG_DATA_DIRS:-/usr/local/share/:/usr/share}"
+
+# add a directory if it exists
+if [[ -d /opt/foo/share ]]; then
+ XDG_DATA_DIRS=/opt/foo/share:${XDG_DATA_DIRS}
+fi
+
+# write our output
+echo XDG_DATA_DIRS=$XDG_DATA_DIRS
diff --git a/man/90-rearrange-path.py b/man/90-rearrange-path.py
new file mode 100755
index 0000000000..c6ff32210f
--- /dev/null
+++ b/man/90-rearrange-path.py
@@ -0,0 +1,40 @@
+#!/usr/bin/python3
+
+"""
+
+Proof-of-concept systemd environment generator that makes sure that bin dirs
+are always after matching sbin dirs in the path.
+(Changes /sbin:/bin:/foo/bar to /bin:/sbin:/foo/bar.)
+
+This generator shows how to override the configuration possibly created by
+earlier generators. It would be easier to write in bash, but let's have it
+in Python just to prove that we can, and to serve as a template for more
+interesting generators.
+
+"""
+
+import os
+import pathlib
+
+def rearrange_bin_sbin(path):
+ """Make sure any pair of …/bin, …/sbin directories is in this order
+
+ >>> rearrange_bin_sbin('/bin:/sbin:/usr/sbin:/usr/bin')
+ '/bin:/sbin:/usr/bin:/usr/sbin'
+ """
+ items = [pathlib.Path(p) for p in path.split(':')]
+ for i in range(len(items)):
+ if 'sbin' in items[i].parts:
+ ind = items[i].parts.index('sbin')
+ bin = pathlib.Path(*items[i].parts[:ind], 'bin', *items[i].parts[ind+1:])
+ if bin in items[i+1:]:
+ j = i + 1 + items[i+1:].index(bin)
+ items[i], items[j] = items[j], items[i]
+ return ':'.join(p.as_posix() for p in items)
+
+if __name__ == '__main__':
+ path = os.environ['PATH'] # This should be always set.
+ # If it's not, we'll just crash, we is OK too.
+ new = rearrange_bin_sbin(path)
+ if new != path:
+ print('PATH={}'.format(new))
diff --git a/man/bootctl.xml b/man/bootctl.xml
index e2575a4751..675e0174e9 100644
--- a/man/bootctl.xml
+++ b/man/bootctl.xml
@@ -118,8 +118,8 @@
<refsect1>
<title>See Also</title>
<para>
- <ulink url="http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec">Boot loader specification</ulink>
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/BootLoaderInterface">Systemd boot loader interface</ulink>
+ <ulink url="https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec">Boot loader specification</ulink>
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/BootLoaderInterface">Systemd boot loader interface</ulink>
</para>
</refsect1>
</refentry>
diff --git a/man/bootup.xml b/man/bootup.xml
index 986996398c..b92c60f43a 100644
--- a/man/bootup.xml
+++ b/man/bootup.xml
@@ -179,6 +179,13 @@
identical to the system manager bootup (see above) until it
reaches <filename>basic.target</filename>. From there, systemd
approaches the special target <filename>initrd.target</filename>.
+
+ Before any file systems are mounted, it must be determined whether
+ the system will resume from hibernation or proceed with normal boot.
+ This is accomplished by <filename>systemd-hibernate-resume@.service</filename>
+ which must be finished before <filename>local-fs-pre.target</filename>,
+ so no filesystems can be mounted before the check is complete.
+
When the root device becomes available,
<filename>initd-root-device.target</filename> is reached.
If the root device can be mounted at
diff --git a/man/busctl.xml b/man/busctl.xml
index 052a33097f..28b36f09d0 100644
--- a/man/busctl.xml
+++ b/man/busctl.xml
@@ -291,11 +291,11 @@
<listitem><para>Similar to <command>monitor</command> but
writes the output in pcap format (for details, see the <ulink
- url="http://wiki.wireshark.org/Development/LibpcapFileFormat">Libpcap
- File Format</ulink> description. Make sure to redirect the
- output to STDOUT to a file. Tools like
+ url="https://wiki.wireshark.org/Development/LibpcapFileFormat">Libpcap
+ File Format</ulink> description). Make sure to redirect
+ standard output to a file. Tools like
<citerefentry project='die-net'><refentrytitle>wireshark</refentrytitle><manvolnum>1</manvolnum></citerefentry>
- may be used to dissect and view the generated
+ may be used to dissect and view the resulting
files.</para></listitem>
</varlistentry>
@@ -472,7 +472,7 @@ o "/org/freedesktop/systemd1/job/42684"</programlisting>
<para>
<citerefentry project='dbus'><refentrytitle>dbus-daemon</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
- <ulink url="http://freedesktop.org/wiki/Software/dbus">D-Bus</ulink>,
+ <ulink url="https://www.freedesktop.org/wiki/Software/dbus">D-Bus</ulink>,
<citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
diff --git a/man/coredump.conf.xml b/man/coredump.conf.xml
index 77b4dac51c..5f61e05f40 100644
--- a/man/coredump.conf.xml
+++ b/man/coredump.conf.xml
@@ -85,7 +85,7 @@
<listitem><para>Controls where to store cores. One of <literal>none</literal>,
<literal>external</literal>, and <literal>journal</literal>. When
- <literal>none</literal>, the core dumps will be logged (included the traceback if
+ <literal>none</literal>, the core dumps will be logged (including the backtrace if
possible), but not stored permanently. When <literal>external</literal> (the
default), cores will be stored in <filename>/var/lib/systemd/coredump/</filename>.
When <literal>journal</literal>, cores will be stored in the journal and rotated
diff --git a/man/coredumpctl.xml b/man/coredumpctl.xml
index abc245be5e..ca8156f77c 100644
--- a/man/coredumpctl.xml
+++ b/man/coredumpctl.xml
@@ -92,6 +92,28 @@
</varlistentry>
<varlistentry>
+ <term><option>-S</option></term>
+ <term><option>--since</option></term>
+
+ <listitem><para>Only print entries which are since the specified date.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U</option></term>
+ <term><option>--until</option></term>
+
+ <listitem><para>Only print entries which are until the specified date.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-r</option></term>
+ <term><option>--reverse</option></term>
+
+ <listitem><para>Reverse output so that the newest entries are displayed first.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>-F</option> <replaceable>FIELD</replaceable></term>
<term><option>--field=</option><replaceable>FIELD</replaceable></term>
@@ -116,6 +138,14 @@
</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>-q</option></term>
+ <term><option>--quiet</option></term>
+
+ <listitem><para>Suppresses info messages about lack
+ of access to journal files and possible in-flight coredumps.
+ </para></listitem>
+ </varlistentry>
</variablelist>
</refsect1>
@@ -132,6 +162,57 @@
matching specified characteristics. If no command is
specified, this is the implied default.</para>
+ <para>The output is designed to be human readable and contains list contains
+ a table with the following columns:</para>
+ <variablelist>
+ <varlistentry>
+ <term>TIME</term>
+ <listitem><para>The timestamp of the crash, as reported by the kernel.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PID</term>
+ <listitem><para>The identifier of the process that crashed.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>UID</term>
+ <term>GID</term>
+ <listitem><para>The user and group identifiers of the process that crashed.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>SIGNAL</term>
+ <listitem><para>The signal that caused the process to crash, when applicable.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>COREFILE</term>
+ <listitem><para>Information whether the coredump was stored, and whether
+ it is still accessible: <literal>none</literal> means the the core was
+ not stored, <literal>-</literal> means that it was not available (for
+ example because the process was not terminated by a signal),
+ <literal>present</literal> means that the core file is accessible by the
+ current user, <literal>journal</literal> means that the core was stored
+ in the <literal>journal</literal>, <literal>truncated</literal> is the
+ same as one of the previous two, but the core was too large and was not
+ stored in its entirety, <literal>error</literal> means that the core file
+ cannot be accessed, most likely because of insufficient permissions, and
+ <literal>missing</literal> means that the core was stored in a file, but
+ this file has since been removed.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>EXE</term>
+ <listitem><para>The full path to the executable. For backtraces of scripts
+ this is the name of the interpreter.</para></listitem>
+ </varlistentry>
+ </variablelist>
+
<para>It's worth noting that different restrictions apply to
data saved in the journal and core dump files saved in
<filename>/var/lib/systemd/coredump</filename>, see overview in
@@ -201,9 +282,9 @@
<varlistentry>
<term><replaceable>MATCH</replaceable></term>
- <listitem><para>General journalctl predicates (see
+ <listitem><para>General journalctl predicate (see
<citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>).
- Must contain an equal sign. </para></listitem>
+ Must contain an equals sign (<literal>=</literal>).</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
diff --git a/man/environment.d.xml b/man/environment.d.xml
new file mode 100644
index 0000000000..be7758a2f9
--- /dev/null
+++ b/man/environment.d.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+ This file is part of systemd.
+
+ Copyright 2016 Red Hat, Inc.
+ Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="environment.d" xmlns:xi="http://www.w3.org/2001/XInclude">
+
+ <refentryinfo>
+ <title>environment.d</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <contrib>Developer</contrib>
+ <firstname>Ray</firstname>
+ <surname>Strode</surname>
+ <email>rstrode@redhat.com</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>environment.d</refentrytitle>
+ <manvolnum>5</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>environment.d</refname>
+ <refpurpose>Definition of user session environment</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <para><filename>~/.config/environment.d/*.conf</filename></para>
+ <para><filename>/etc/environment.d/*.conf</filename></para>
+ <para><filename>/run/environment.d/*.conf</filename></para>
+ <para><filename>/usr/lib/environment.d/*.conf</filename></para>
+ <para><filename>/etc/environment</filename></para>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The <filename>environment.d</filename> directories contain a list of "global" environment
+ variable assignments for the user environment.
+ <citerefentry><refentrytitle>systemd-environment-d-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ parses them and updates the environment exported by the systemd user instance to the services it
+ starts.</para>
+
+ <para>It is recommended to use numerical prefixes for file names to simplify ordering.</para>
+
+ <para>For backwards compatibility, a symlink to <filename>/etc/environment</filename> is
+ installed, so this file is also parsed.</para>
+ </refsect1>
+
+ <xi:include href="standard-conf.xml" xpointer="confd" />
+
+ <refsect1>
+ <title>Configuration Format</title>
+
+ <para>The configuration files contain a list of
+ <literal><replaceable>KEY</replaceable>=<replaceable>VALUE</replaceable></literal> environment
+ variable assignments, separated by newlines. The right hand side of these assignments may
+ reference previously defined environment variables, using the <literal>${OTHER_KEY}</literal>
+ and <literal>$OTHER_KEY</literal> format. It is also possible to use
+
+ <literal>${<replaceable>FOO</replaceable>:-<replaceable>DEFAULT_VALUE</replaceable>}</literal>
+ to expand in the same way as <literal>${<replaceable>FOO</replaceable>}</literal> unless the
+ expansion would be empty, in which case it expands to <replaceable>DEFAULT_VALUE</replaceable>,
+ and use
+ <literal>${<replaceable>FOO</replaceable>:+<replaceable>ALTERNATE_VALUE</replaceable>}</literal>
+ to expand to <replaceable>ALTERNATE_VALUE</replaceable> as long as
+ <literal>${<replaceable>FOO</replaceable>}</literal> would have expanded to a non-empty value.
+ No other elements of shell syntax are supported.</para>
+
+ <para>Each<replaceable>KEY</replaceable> must be a valid variable name. Empty lines
+ and lines beginning with the comment character <literal>#</literal> are ignored.</para>
+
+ <refsect2>
+ <title>Example</title>
+ <example>
+ <title>Setup environment to allow access to a program installed in
+ <filename noindex='true'>/opt/foo</filename></title>
+
+ <para><filename>/etc/environment.d/60-foo.conf</filename>:
+ </para>
+ <programlisting>
+ FOO_DEBUG=force-software-gl,log-verbose
+ PATH=/opt/foo/bin:$PATH
+ LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}/opt/foo/lib
+ XDG_DATA_DIRS=/opt/foo/share:${XDG_DATA_DIRS:-/usr/local/share/:/usr/share/}
+ </programlisting>
+ </example>
+ </refsect2>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+ <para>
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-environment-d-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd.environment-generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/file-hierarchy.xml b/man/file-hierarchy.xml
index 538a592f8d..ab52ccfe0c 100644
--- a/man/file-hierarchy.xml
+++ b/man/file-hierarchy.xml
@@ -502,7 +502,7 @@
url="http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html">XDG
Base Directory Specification</ulink>. Additional locations for
high-level user resources are defined by <ulink
- url="http://www.freedesktop.org/wiki/Software/xdg-user-dirs/">xdg-user-dirs</ulink>.</para>
+ url="https://www.freedesktop.org/wiki/Software/xdg-user-dirs/">xdg-user-dirs</ulink>.</para>
<variablelist>
<varlistentry>
diff --git a/man/hostnamectl.xml b/man/hostnamectl.xml
index 9e1b593e6d..81bce2da6a 100644
--- a/man/hostnamectl.xml
+++ b/man/hostnamectl.xml
@@ -173,6 +173,7 @@
defined:
<literal>desktop</literal>,
<literal>laptop</literal>,
+ <literal>convertible</literal>,
<literal>server</literal>,
<literal>tablet</literal>,
<literal>handset</literal>,
diff --git a/man/hwdb.xml b/man/hwdb.xml
index 2b1e60fb22..ae5ddb1a4d 100644
--- a/man/hwdb.xml
+++ b/man/hwdb.xml
@@ -50,28 +50,88 @@
system-supplied hwdb file with a local file if needed;
a symlink in <filename>/etc</filename> with the same name as a hwdb file in
<filename>/usr/lib</filename>, pointing to <filename>/dev/null</filename>,
- disables the hwdb file entirely. hwdb files must have the extension
+ disables that hwdb file entirely. hwdb files must have the extension
<filename>.hwdb</filename>; other extensions are ignored.</para>
- <para>The hwdb file contains data records consisting of matches and
- associated key-value pairs. Every record in the hwdb starts with one or
- more match strings, specifying a shell glob to compare the database
- lookup string against. Multiple match lines are specified in additional
- consecutive lines. Every match line is compared individually, and they are
- combined by OR. Every match line must start at the first character of
- the line.</para>
+ <para>Each hwdb file contains data records consisting of matches and associated
+ key-value pairs. Every record in the hwdb starts with one or more match strings,
+ specifying a shell glob to compare the lookup string against. Multiple match lines
+ are specified in consecutive lines. Every match line is compared individually, and
+ they are combined by OR. Every match line must start at the first character of the
+ line.</para>
- <para>The match lines are followed by one or more key-value pair lines, which
- are recognized by a leading space character. The key name and value are separated
- by <literal>=</literal>. An empty line signifies the end
- of a record. Lines beginning with <literal>#</literal> are ignored.</para>
+ <para>The match lines are followed by one or more key-value pair lines, which are
+ recognized by a leading space character. The key name and value are separated by
+ <literal>=</literal>. An empty line signifies the end of a record. Lines beginning
+ with <literal>#</literal> are ignored.</para>
+
+ <para>In case multiple records match a given lookup string, the key-value pairs
+ from all records are combined. If a key is specified multiple times, the value
+ from the record with the highest priority is used (each key can have only a single
+ value). The priority is higher when the record is in a file that sorts later
+ lexicographically, and in case of records in the same file, later records have
+ higher priority.</para>
<para>The content of all hwdb files is read by
<citerefentry><refentrytitle>systemd-hwdb</refentrytitle><manvolnum>8</manvolnum></citerefentry>
and compiled to a binary database located at <filename>/etc/udev/hwdb.bin</filename>,
- or alternatively <filename>/usr/lib/udev/hwdb.bin</filename> if you want ship the compiled
- database in an immutable image.
- During runtime, only the binary database is used.</para>
+ or alternatively <filename>/usr/lib/udev/hwdb.bin</filename> if you want ship the
+ compiled database in an immutable image. During runtime, only the binary database
+ is used.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <example>
+ <title>General syntax of hwdb files</title>
+
+ <programlisting># /usr/lib/udev/hwdb.d/example.hwdb
+# Comments can be placed before any records. This is a good spot
+# to describe what that file is used for, what kind of properties
+# it defines, and the ordering convention.
+
+# A record with three matches and one property
+mouse:*:name:*Trackball*:
+mouse:*:name:*trackball*:
+mouse:*:name:*TrackBall*:
+ ID_INPUT_TRACKBALL=1
+
+# A record with a single match and five properties
+mouse:usb:v046dp4041:name:Logitech MX Master:
+ MOUSE_DPI=1000@166
+ MOUSE_WHEEL_CLICK_ANGLE=15
+ MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL=26
+ MOUSE_WHEEL_CLICK_COUNT=24
+ MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL=14
+</programlisting>
+ </example>
+
+ <example>
+ <title>Overriding of properties</title>
+
+ <programlisting># /usr/lib/udev/hwdb.d/60-keyboard.hwdb
+evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pn*
+ KEYBOARD_KEY_a1=help
+ KEYBOARD_KEY_a2=setup
+ KEYBOARD_KEY_a3=battery
+
+evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pn123*
+ KEYBOARD_KEY_a2=wlan
+
+# /etc/udev/hwdb.d/70-keyboard.hwdb
+# disable wlan key on all at keyboards
+evdev:atkbd:*
+ KEYBOARD_KEY_a2=reserved</programlisting>
+
+ <para>If the hwdb consists of those two files, a keyboard with the lookup string
+ <literal>evdev:atkbd:dmi:bvnAcer:bdXXXXX:bd08/05/2010:svnAcer:pn123</literal>
+ will match all three records, and end up with the following properties:</para>
+
+ <programlisting>KEYBOARD_KEY_a1=help
+KEYBOARD_KEY_a2=reserved
+KEYBOARD_KEY_a3=battery</programlisting>
+ </example>
</refsect1>
<refsect1>
diff --git a/man/journalctl.xml b/man/journalctl.xml
index 63b4a267b8..cae5312db2 100644
--- a/man/journalctl.xml
+++ b/man/journalctl.xml
@@ -318,8 +318,10 @@
<para>serializes the journal into a binary (but mostly
text-based) stream suitable for backups and network
transfer (see
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/export">Journal Export Format</ulink>
- for more information).</para>
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/export">Journal Export Format</ulink>
+ for more information). To import the binary stream back
+ into native journald format use
+ <citerefentry><refentrytitle>systemd-journal-remote</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
</listitem>
</varlistentry>
@@ -330,7 +332,7 @@
<listitem>
<para>formats entries as JSON data structures, one per
line (see
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/json">Journal JSON Format</ulink>
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/json">Journal JSON Format</ulink>
for more information).</para>
</listitem>
</varlistentry>
@@ -399,7 +401,7 @@
manuals. Note that help texts are not available for all
messages, but only for selected ones. For more information on
the message catalog, please refer to the
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/catalog">Message Catalog Developer Documentation</ulink>.</para>
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/catalog">Message Catalog Developer Documentation</ulink>.</para>
<para>Note: when attaching <command>journalctl</command>
output to bug reports, please do <emphasis>not</emphasis> use
@@ -412,7 +414,7 @@
<term><option>--quiet</option></term>
<listitem><para>Suppresses all info messages
- (i.e. "-- Logs begin at ...", "-- Reboot --"),
+ (i.e. "-- Logs begin at …", "-- Reboot --"),
any warning messages regarding
inaccessible system journals when run as a normal
user.</para></listitem>
@@ -573,7 +575,7 @@
<listitem><para>The cursor is shown after the last entry after
two dashes:</para>
- <programlisting>-- cursor: s=0639...</programlisting>
+ <programlisting>-- cursor: s=0639…</programlisting>
<para>The format of the cursor is private
and subject to change.</para></listitem>
</varlistentry>
@@ -675,7 +677,7 @@
a new 128-bit ID suitable for identifying messages. This is
intended for usage by developers who need a new identifier for
a new message they introduce and want to make
- recognizable. This will print the new ID in three different
+ recognizable. This will print the new ID in four different
formats which can be copied into source code or similar.
</para></listitem>
</varlistentry>
@@ -731,7 +733,7 @@
<varlistentry>
<term><option>--list-catalog
- <optional><replaceable>128-bit-ID...</replaceable></optional>
+ <optional><replaceable>128-bit-ID…</replaceable></optional>
</option></term>
<listitem><para>List the contents of the message catalog as a
@@ -745,7 +747,7 @@
<varlistentry>
<term><option>--dump-catalog
- <optional><replaceable>128-bit-ID...</replaceable></optional>
+ <optional><replaceable>128-bit-ID…</replaceable></optional>
</option></term>
<listitem><para>Show the contents of the message catalog, with
@@ -923,7 +925,9 @@
<citerefentry><refentrytitle>coredumpctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-journal-remote</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-journal-upload</refentrytitle><manvolnum>8</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>
diff --git a/man/journald.conf.xml b/man/journald.conf.xml
index 9daa964803..209d857234 100644
--- a/man/journald.conf.xml
+++ b/man/journald.conf.xml
@@ -227,7 +227,7 @@
rotated journal files are kept as history.</para>
<para>Specify values in bytes or use K, M, G, T, P, E as
- units for the specified sizes (equal to 1024, 1024², ... bytes).
+ units for the specified sizes (equal to 1024, 1024², … bytes).
Note that size limits are enforced synchronously when journal
files are extended, and no explicit rotation step triggered by
time is needed.</para>
diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml
index 1fa31a14b7..f02ca3e7bc 100644
--- a/man/kernel-command-line.xml
+++ b/man/kernel-command-line.xml
@@ -78,20 +78,22 @@
<varlistentry>
<term><varname>systemd.unit=</varname></term>
<term><varname>rd.systemd.unit=</varname></term>
- <term><varname>systemd.dump_core=</varname></term>
- <term><varname>systemd.crash_chvt=</varname></term>
- <term><varname>systemd.crash_shell=</varname></term>
- <term><varname>systemd.crash_reboot=</varname></term>
- <term><varname>systemd.confirm_spawn=</varname></term>
- <term><varname>systemd.show_status=</varname></term>
+ <term><varname>systemd.dump_core</varname></term>
+ <term><varname>systemd.crash_chvt</varname></term>
+ <term><varname>systemd.crash_shell</varname></term>
+ <term><varname>systemd.crash_reboot</varname></term>
+ <term><varname>systemd.confirm_spawn</varname></term>
+ <term><varname>systemd.show_status</varname></term>
<term><varname>systemd.log_target=</varname></term>
<term><varname>systemd.log_level=</varname></term>
- <term><varname>systemd.log_color=</varname></term>
<term><varname>systemd.log_location=</varname></term>
+ <term><varname>systemd.log_color</varname></term>
<term><varname>systemd.default_standard_output=</varname></term>
<term><varname>systemd.default_standard_error=</varname></term>
<term><varname>systemd.setenv=</varname></term>
<term><varname>systemd.machine_id=</varname></term>
+ <term><varname>systemd.unified_cgroup_hierarchy</varname></term>
+ <term><varname>systemd.legacy_systemd_cgroup_controller</varname></term>
<listitem>
<para>Parameters understood by the system and service
manager to control system behavior. For details, see
@@ -102,7 +104,7 @@
<varlistentry>
<term><varname>systemd.mask=</varname></term>
<term><varname>systemd.wants=</varname></term>
- <term><varname>systemd.debug-shell</varname></term>
+ <term><varname>systemd.debug_shell</varname></term>
<listitem>
<para>Additional parameters understood by
<citerefentry><refentrytitle>systemd-debug-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
@@ -125,6 +127,28 @@
</varlistentry>
<varlistentry>
+ <term><varname>systemd.volatile=</varname></term>
+ <listitem>
+ <para>This parameter controls whether the system shall boot up in volatile mode. Takes a boolean argument, or
+ the special value <literal>state</literal>. If false (the default), normal boot mode is selected, the root
+ directory and <filename>/var</filename> are mounted as specified on the kernel command line or
+ <filename>/etc/fstab</filename>, or otherwise configured. If true, full state-less boot mode is selected. In
+ this case the root directory is mounted as volatile memory file system (<literal>tmpfs</literal>), and only
+ <filename>/usr</filename> is mounted from the file system configured as root device, in read-only mode. This
+ enables fully state-less boots were the vendor-supplied OS is used as shipped, with only default
+ configuration and no stored state in effect, as <filename>/etc</filename> and <filename>/var</filename> (as
+ well as all other resources shipped in the root file system) are reset at boot and lost on shutdown. If this
+ setting is set to <literal>state</literal> the root file system is mounted as usual, however
+ <filename>/var</filename> is mounted as a volatile memory file system (<literal>tmpfs</literal>), so that the
+ system boots up with the normal configuration applied, but all state reset at boot and lost at shutdown. For details,
+ see
+ <citerefentry><refentrytitle>systemd-volatile-root.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ and
+ <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>quiet</varname></term>
<listitem>
<para>Parameter understood by both the kernel and the system
@@ -236,14 +260,14 @@
</varlistentry>
<varlistentry>
- <term><varname>udev.log-priority=</varname></term>
- <term><varname>rd.udev.log-priority=</varname></term>
- <term><varname>udev.children-max=</varname></term>
- <term><varname>rd.udev.children-max=</varname></term>
- <term><varname>udev.exec-delay=</varname></term>
- <term><varname>rd.udev.exec-delay=</varname></term>
- <term><varname>udev.event-timeout=</varname></term>
- <term><varname>rd.udev.event-timeout=</varname></term>
+ <term><varname>udev.log_priority=</varname></term>
+ <term><varname>rd.udev.log_priority=</varname></term>
+ <term><varname>udev.children_max=</varname></term>
+ <term><varname>rd.udev.children_max=</varname></term>
+ <term><varname>udev.exec_delay=</varname></term>
+ <term><varname>rd.udev.exec_delay=</varname></term>
+ <term><varname>udev.event_timeout=</varname></term>
+ <term><varname>rd.udev.event_timeout=</varname></term>
<term><varname>net.ifnames=</varname></term>
<listitem>
@@ -312,6 +336,19 @@
</varlistentry>
<varlistentry>
+ <term><varname>roothash=</varname></term>
+ <term><varname>systemd.verity=</varname></term>
+ <term><varname>rd.systemd.verity=</varname></term>
+ <term><varname>systemd.verity_root_data=</varname></term>
+ <term><varname>systemd.verity_root_hash=</varname></term>
+ <listitem>
+ <para>Configures the integrity protection root hash for the root file system, and other related
+ parameters. For details, see
+ <citerefentry><refentrytitle>systemd-veritysetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>systemd.gpt_auto=</varname></term>
<term><varname>rd.systemd.gpt_auto=</varname></term>
@@ -332,8 +369,8 @@
</varlistentry>
<varlistentry>
- <term><varname>modules-load=</varname></term>
- <term><varname>rd.modules-load=</varname></term>
+ <term><varname>modules_load=</varname></term>
+ <term><varname>rd.modules_load=</varname></term>
<listitem>
<para>Load a specific kernel module early at boot. For
@@ -353,6 +390,15 @@
<citerefentry><refentrytitle>systemd-hibernate-resume-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><varname>systemd.firstboot=</varname></term>
+
+ <listitem><para>Takes a boolean argument, defaults to on. If off,
+ <citerefentry><refentrytitle>systemd-firstboot.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ will not query the user for basic system settings, even if the system boots up for the first time and the
+ relevant settings are not initialized yet.</para></listitem>
+ </varlistentry>
</variablelist>
</refsect1>
@@ -371,12 +417,15 @@
<citerefentry><refentrytitle>systemd-udevd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='die-net'><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-cryptsetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-veritysetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-gpt-auto-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-volatile-root.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-modules-load.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-backlight@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-rfkill.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd-hibernate-resume-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>systemd-hibernate-resume-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-firstboot.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
</para>
</refsect1>
diff --git a/man/kernel-install.xml b/man/kernel-install.xml
index 32e6169f63..2f42d49d9f 100644
--- a/man/kernel-install.xml
+++ b/man/kernel-install.xml
@@ -89,11 +89,12 @@
<listitem>
<para><command>kernel-install</command> creates the directory
<filename>/boot/<replaceable>MACHINE-ID</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/</filename>
- and calls every executable
+ and calls executables from
<filename>/usr/lib/kernel/install.d/*.install</filename> and
<filename>/etc/kernel/install.d/*.install</filename> with
the arguments
- <programlisting>add <replaceable>KERNEL-VERSION</replaceable> <filename>/boot/<replaceable>MACHINE-ID</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/</filename></programlisting>
+ <programlisting>add <replaceable>KERNEL-VERSION</replaceable> \
+ <filename>/boot/<replaceable>MACHINE-ID</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/</filename> <replaceable>KERNEL-IMAGE</replaceable></programlisting>
</para>
<para>The kernel-install plugin <filename>50-depmod.install</filename> runs depmod for the <replaceable>KERNEL-VERSION</replaceable>.</para>
@@ -119,7 +120,7 @@
<varlistentry>
<term><command>remove <replaceable>KERNEL-VERSION</replaceable></command></term>
<listitem>
- <para>Calls every executable <filename>/usr/lib/kernel/install.d/*.install</filename>
+ <para>Calls executables from <filename>/usr/lib/kernel/install.d/*.install</filename>
and <filename>/etc/kernel/install.d/*.install</filename> with the arguments
<programlisting>remove <replaceable>KERNEL-VERSION</replaceable> <filename>/boot/<replaceable>MACHINE-ID</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/</filename></programlisting>
</para>
@@ -138,7 +139,7 @@
<refsect1>
<title>Exit status</title>
- <para>If every executable returns with 0, 0 is returned, a non-zero failure code otherwise.</para>
+ <para>If every executable returns 0 or 77, 0 is returned, and a non-zero failure code otherwise.</para>
</refsect1>
<refsect1>
@@ -188,7 +189,7 @@
<para>
<citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- <ulink url="http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec">Boot loader specification</ulink>
+ <ulink url="https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec">Boot loader specification</ulink>
</para>
</refsect1>
diff --git a/man/localectl.xml b/man/localectl.xml
index 31238272f3..7da12c29de 100644
--- a/man/localectl.xml
+++ b/man/localectl.xml
@@ -127,7 +127,7 @@
</varlistentry>
<varlistentry>
- <term><command>set-locale LOCALE...</command></term>
+ <term><command>set-locale LOCALE…</command></term>
<listitem><para>Set the system locale. This takes one or more
assignments such as "LANG=de_DE.utf8",
diff --git a/man/loginctl.xml b/man/loginctl.xml
index fb51740503..534a0d961e 100644
--- a/man/loginctl.xml
+++ b/man/loginctl.xml
@@ -191,7 +191,7 @@
</varlistentry>
<varlistentry>
- <term><command>session-status</command> <optional><replaceable>ID</replaceable>...</optional></term>
+ <term><command>session-status</command> <optional><replaceable>ID</replaceable>…</optional></term>
<listitem><para>Show terse runtime status information about
one or more sessions, followed by the most recent log data
@@ -204,7 +204,7 @@
</varlistentry>
<varlistentry>
- <term><command>show-session</command> <optional><replaceable>ID</replaceable>...</optional></term>
+ <term><command>show-session</command> <optional><replaceable>ID</replaceable>…</optional></term>
<listitem><para>Show properties of one or more sessions or the
manager itself. If no argument is specified, properties of the
@@ -229,8 +229,8 @@
</varlistentry>
<varlistentry>
- <term><command>lock-session</command> <optional><replaceable>ID</replaceable>...</optional></term>
- <term><command>unlock-session</command> <optional><replaceable>ID</replaceable>...</optional></term>
+ <term><command>lock-session</command> <optional><replaceable>ID</replaceable>…</optional></term>
+ <term><command>unlock-session</command> <optional><replaceable>ID</replaceable>…</optional></term>
<listitem><para>Activates/deactivates the screen lock on one
or more sessions, if the session supports it. Takes one or
@@ -248,7 +248,7 @@
</varlistentry>
<varlistentry>
- <term><command>terminate-session</command> <replaceable>ID</replaceable>...</term>
+ <term><command>terminate-session</command> <replaceable>ID</replaceable>…</term>
<listitem><para>Terminates a session. This kills all processes
of the session and deallocates all resources attached to the
@@ -256,7 +256,7 @@
</varlistentry>
<varlistentry>
- <term><command>kill-session</command> <replaceable>ID</replaceable>...</term>
+ <term><command>kill-session</command> <replaceable>ID</replaceable>…</term>
<listitem><para>Send a signal to one or more processes of the
session. Use <option>--kill-who=</option> to select which
@@ -274,7 +274,7 @@
</varlistentry>
<varlistentry>
- <term><command>user-status</command> <optional><replaceable>USER</replaceable>...</optional></term>
+ <term><command>user-status</command> <optional><replaceable>USER</replaceable>…</optional></term>
<listitem><para>Show terse runtime status information about
one or more logged in users, followed by the most recent log
@@ -288,7 +288,7 @@
</varlistentry>
<varlistentry>
- <term><command>show-user</command> <optional><replaceable>USER</replaceable>...</optional></term>
+ <term><command>show-user</command> <optional><replaceable>USER</replaceable>…</optional></term>
<listitem><para>Show properties of one or more users or the
manager itself. If no argument is specified, properties of the
@@ -303,8 +303,8 @@
</varlistentry>
<varlistentry>
- <term><command>enable-linger</command> <optional><replaceable>USER</replaceable>...</optional></term>
- <term><command>disable-linger</command> <optional><replaceable>USER</replaceable>...</optional></term>
+ <term><command>enable-linger</command> <optional><replaceable>USER</replaceable>…</optional></term>
+ <term><command>disable-linger</command> <optional><replaceable>USER</replaceable>…</optional></term>
<listitem><para>Enable/disable user lingering for one or more
users. If enabled for a specific user, a user manager is
@@ -320,7 +320,7 @@
</varlistentry>
<varlistentry>
- <term><command>terminate-user</command> <replaceable>USER</replaceable>...</term>
+ <term><command>terminate-user</command> <replaceable>USER</replaceable>…</term>
<listitem><para>Terminates all sessions of a user. This kills
all processes of all sessions of the user and deallocates all
@@ -328,7 +328,7 @@
</varlistentry>
<varlistentry>
- <term><command>kill-user</command> <replaceable>USER</replaceable>...</term>
+ <term><command>kill-user</command> <replaceable>USER</replaceable>…</term>
<listitem><para>Send a signal to all processes of a user. Use
<option>--signal=</option> to select the signal to send.
@@ -345,7 +345,7 @@
</varlistentry>
<varlistentry>
- <term><command>seat-status</command> <optional><replaceable>NAME</replaceable>...</optional></term>
+ <term><command>seat-status</command> <optional><replaceable>NAME</replaceable>…</optional></term>
<listitem><para>Show terse runtime status information about
one or more seats. Takes one or more seat names as parameters.
@@ -357,7 +357,7 @@
</varlistentry>
<varlistentry>
- <term><command>show-seat</command> <optional><replaceable>NAME</replaceable>...</optional></term>
+ <term><command>show-seat</command> <optional><replaceable>NAME</replaceable>…</optional></term>
<listitem><para>Show properties of one or more seats or the
manager itself. If no argument is specified, properties of the
@@ -372,7 +372,7 @@
</varlistentry>
<varlistentry>
- <term><command>attach</command> <replaceable>NAME</replaceable> <replaceable>DEVICE</replaceable>...</term>
+ <term><command>attach</command> <replaceable>NAME</replaceable> <replaceable>DEVICE</replaceable>…</term>
<listitem><para>Persistently attach one or more devices to a
seat. The devices should be specified via device paths in the
@@ -396,7 +396,7 @@
</varlistentry>
<varlistentry>
- <term><command>terminate-seat</command> <replaceable>NAME</replaceable>...</term>
+ <term><command>terminate-seat</command> <replaceable>NAME</replaceable>…</term>
<listitem><para>Terminates all sessions on a seat. This kills
all processes of all sessions on the seat and deallocates all
@@ -426,9 +426,9 @@ fatima (1005)
Sessions: 5 *3
Unit: user-1005.slice
├─user@1005.service
- ...
+ …
├─session-3.scope
- ...
+ …
└─session-5.scope
├─3473 login -- fatima
└─3515 -zsh
diff --git a/man/machine-id.xml b/man/machine-id.xml
index d318ec54ec..3c261bffcc 100644
--- a/man/machine-id.xml
+++ b/man/machine-id.xml
@@ -53,30 +53,32 @@
<refsect1>
<title>Description</title>
- <para>The <filename>/etc/machine-id</filename> file contains the
- unique machine ID of the local system that is set during
- installation. The machine ID is a single newline-terminated,
- hexadecimal, 32-character, lowercase machine ID string. When
- decoded from hexadecimal, this corresponds with a 16-byte/128-bit
- string.</para>
+ <para>The <filename>/etc/machine-id</filename> file contains the unique machine ID of the local
+ system that is set during installation. The machine ID is a single newline-terminated,
+ hexadecimal, 32-character, lowercase ID. When decoded from hexadecimal, this corresponds to a
+ 16-byte/128-bit value.</para>
<para>The machine ID is usually generated from a random source
during system installation and stays constant for all subsequent
boots. Optionally, for stateless systems, it is generated during
runtime at early boot if it is found to be empty.</para>
- <para>The machine ID does not change based on user configuration
- or when hardware is replaced.</para>
+ <para>The machine ID does not change based on local or network configuration or when hardware is
+ replaced. Due to this and its greater length, it is a more useful replacement for the
+ <citerefentry project='man-pages'><refentrytitle>gethostid</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ call that POSIX specifies.</para>
<para>This machine ID adheres to the same format and logic as the
D-Bus machine ID.</para>
- <para>Programs may use this ID to identify the host with a
- globally unique ID in the network, which does not change even if
- the local network configuration changes. Due to this and its
- greater length, it is a more useful replacement for the
- <citerefentry project='man-pages'><refentrytitle>gethostid</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- call that POSIX specifies.</para>
+ <para>This ID uniquely identifies the host. It should be considered "confidential", and must not be exposed in
+ untrusted environments, in particular on the network. If a stable unique identifier that is tied to the machine is
+ needed for some application, the machine ID or any part of it must not be used directly. Instead the machine ID
+ should be hashed with a cryptographic, keyed hash function, using a fixed, application-specific key. That way the
+ ID will be properly unique, and derived in a constant way from the machine ID but there will be no way to retrieve
+ the original machine ID from the application-specific one. The
+ <citerefentry><refentrytitle>sd_id128_get_machine_app_specific</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ API provides an implementation of such an algorithm.</para>
<para>The
<citerefentry><refentrytitle>systemd-machine-id-setup</refentrytitle><manvolnum>1</manvolnum></citerefentry>
diff --git a/man/machine-info.xml b/man/machine-info.xml
index 351133670b..cd5997d4e2 100644
--- a/man/machine-info.xml
+++ b/man/machine-info.xml
@@ -120,6 +120,7 @@
chassis types are defined:
<literal>desktop</literal>,
<literal>laptop</literal>,
+ <literal>convertible</literal>,
<literal>server</literal>,
<literal>tablet</literal>,
<literal>handset</literal>,
diff --git a/man/machinectl.xml b/man/machinectl.xml
index 5a6ec294d2..7a159aecdc 100644
--- a/man/machinectl.xml
+++ b/man/machinectl.xml
@@ -292,7 +292,7 @@
Defaults to 1. All addresses can be requested with <literal>all</literal>
as argument to <option>--max-addresses</option> . If the argument to
<option>--max-addresses</option> is less than the actual number
- of addresses,<literal>...</literal>follows the last address.
+ of addresses, <literal>...</literal>follows the last address.
If multiple addresses are to be written for a given machine, every
address except the first one is on a new line and is followed by
<literal>,</literal> if another address will be output afterwards. </para></listitem>
@@ -327,7 +327,7 @@
</varlistentry>
<varlistentry>
- <term><command>status</command> <replaceable>NAME</replaceable>...</term>
+ <term><command>status</command> <replaceable>NAME</replaceable>…</term>
<listitem><para>Show runtime status information about
one or more virtual machines and containers, followed by the
@@ -341,7 +341,7 @@
</varlistentry>
<varlistentry>
- <term><command>show</command> [<replaceable>NAME</replaceable>...]</term>
+ <term><command>show</command> [<replaceable>NAME</replaceable>…]</term>
<listitem><para>Show properties of one or more registered virtual machines or containers or the manager
itself. If no argument is specified, properties of the manager will be shown. If a NAME is specified,
@@ -353,7 +353,7 @@
</varlistentry>
<varlistentry>
- <term><command>start</command> <replaceable>NAME</replaceable>...</term>
+ <term><command>start</command> <replaceable>NAME</replaceable>…</term>
<listitem><para>Start a container as a system service, using
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
@@ -410,7 +410,7 @@
</varlistentry>
<varlistentry>
- <term><command>shell</command> [[<replaceable>NAME</replaceable>@]<replaceable>NAME</replaceable> [<replaceable>PATH</replaceable> [<replaceable>ARGUMENTS</replaceable>...]]] </term>
+ <term><command>shell</command> [[<replaceable>NAME</replaceable>@]<replaceable>NAME</replaceable> [<replaceable>PATH</replaceable> [<replaceable>ARGUMENTS</replaceable>…]]] </term>
<listitem><para>Open an interactive shell session in a
container or on the local host. The first argument refers to
@@ -428,6 +428,9 @@
user may be selected. Use <option>--setenv=</option> to set
environment variables for the executed process.</para>
+ <para>Note that <command>machinectl shell</command> does not propagate the exit code/status of the invoked
+ shell process. Use <command>systemd-run</command> instead if that information is required (see below).</para>
+
<para>When using the <command>shell</command> command without
arguments, (thus invoking the executed shell or command on the
local host), it is in many ways similar to a <citerefentry
@@ -440,17 +443,20 @@
environment variables or resource limits, among other
properties.</para>
- <para>Note that
- <citerefentry><refentrytitle>systemd-run</refentrytitle><manvolnum>1</manvolnum></citerefentry>
- may be used in place of the <command>shell</command> command,
- and allows more detailed, low-level configuration of the
- invoked unit. However, it is frequently more privileged than
- the <command>shell</command> command.</para></listitem>
+ <para>Note that <citerefentry><refentrytitle>systemd-run</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ with its <option>--machine=</option> switch may be used in place of the <command>machinectl shell</command>
+ command, and allows non-interactive operation, more detailed and low-level configuration of the invoked unit,
+ as well as access to runtime and exit code/status information of the invoked shell process. In particular, use
+ <command>systemd-run</command>'s <option>--wait</option> switch to propagate exit status information of the
+ invoked process. Use <command>systemd-run</command>'s <option>--pty</option> switch for acquiring an
+ interactive shell, similar to <command>machinectl shell</command>. In general, <command>systemd-run</command>
+ is preferable for scripting purposes. However, note that <command>systemd-run</command> might require higher
+ privileges than <command>machinectl shell</command>.</para></listitem>
</varlistentry>
<varlistentry>
- <term><command>enable</command> <replaceable>NAME</replaceable>...</term>
- <term><command>disable</command> <replaceable>NAME</replaceable>...</term>
+ <term><command>enable</command> <replaceable>NAME</replaceable>…</term>
+ <term><command>disable</command> <replaceable>NAME</replaceable>…</term>
<listitem><para>Enable or disable a container as a system
service to start at system boot, using
@@ -463,7 +469,7 @@
</varlistentry>
<varlistentry>
- <term><command>poweroff</command> <replaceable>NAME</replaceable>...</term>
+ <term><command>poweroff</command> <replaceable>NAME</replaceable>…</term>
<listitem><para>Power off one or more containers. This will
trigger a reboot by sending SIGRTMIN+4 to the container's init
@@ -478,7 +484,7 @@
</varlistentry>
<varlistentry>
- <term><command>reboot</command> <replaceable>NAME</replaceable>...</term>
+ <term><command>reboot</command> <replaceable>NAME</replaceable>…</term>
<listitem><para>Reboot one or more containers. This will
trigger a reboot by sending SIGINT to the container's init
@@ -488,7 +494,7 @@
</varlistentry>
<varlistentry>
- <term><command>terminate</command> <replaceable>NAME</replaceable>...</term>
+ <term><command>terminate</command> <replaceable>NAME</replaceable>…</term>
<listitem><para>Immediately terminates a virtual machine or
container, without cleanly shutting it down. This kills all
@@ -499,7 +505,7 @@
</varlistentry>
<varlistentry>
- <term><command>kill</command> <replaceable>NAME</replaceable>...</term>
+ <term><command>kill</command> <replaceable>NAME</replaceable>…</term>
<listitem><para>Send a signal to one or more processes of the
virtual machine or container. This means processes as seen by
@@ -512,19 +518,14 @@
<varlistentry>
<term><command>bind</command> <replaceable>NAME</replaceable> <replaceable>PATH</replaceable> [<replaceable>PATH</replaceable>]</term>
- <listitem><para>Bind mounts a directory from the host into the
- specified container. The first directory argument is the
- source directory on the host, the second directory argument
- is the destination directory in the container. When the
- latter is omitted, the destination path in the container is
- the same as the source path on the host. When combined with
- the <option>--read-only</option> switch, a ready-only bind
- mount is created. When combined with the
- <option>--mkdir</option> switch, the destination path is first
- created before the mount is applied. Note that this option is
- currently only supported for
- <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>
- containers.</para></listitem>
+ <listitem><para>Bind mounts a directory from the host into the specified container. The first directory
+ argument is the source directory on the host, the second directory argument is the destination directory in the
+ container. When the latter is omitted, the destination path in the container is the same as the source path on
+ the host. When combined with the <option>--read-only</option> switch, a ready-only bind mount is created. When
+ combined with the <option>--mkdir</option> switch, the destination path is first created before the mount is
+ applied. Note that this option is currently only supported for
+ <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry> containers,
+ and only if user namespacing (<option>--private-users</option>) is not used.</para></listitem>
</varlistentry>
<varlistentry>
@@ -534,9 +535,12 @@
system into a running container. Takes a container name,
followed by the source path on the host and the destination
path in the container. If the destination path is omitted, the
- same as the source path is used.</para></listitem>
- </varlistentry>
+ same as the source path is used.</para>
+ <para>If host and container share the same user and group namespace, file ownership by numeric user ID and
+ group ID is preserved for the copy, otherwise all files and directories in the copy will be owned by the root
+ user and group (UID/GID 0).</para></listitem>
+ </varlistentry>
<varlistentry>
<term><command>copy-from</command> <replaceable>NAME</replaceable> <replaceable>PATH</replaceable> [<replaceable>PATH</replaceable>]</term>
@@ -545,7 +549,11 @@
into the host system. Takes a container name, followed by the
source path in the container the destination path on the host.
If the destination path is omitted, the same as the source path
- is used.</para></listitem>
+ is used.</para>
+
+ <para>If host and container share the same user and group namespace, file ownership by numeric user ID and
+ group ID is preserved for the copy, otherwise all files and directories in the copy will be owned by the root
+ user and group (UID/GID 0).</para></listitem>
</varlistentry>
</variablelist></refsect2>
@@ -568,7 +576,7 @@
</varlistentry>
<varlistentry>
- <term><command>image-status</command> [<replaceable>NAME</replaceable>...]</term>
+ <term><command>image-status</command> [<replaceable>NAME</replaceable>…]</term>
<listitem><para>Show terse status information about one or
more container or VM images. This function is intended to
@@ -578,7 +586,7 @@
</varlistentry>
<varlistentry>
- <term><command>show-image</command> [<replaceable>NAME</replaceable>...]</term>
+ <term><command>show-image</command> [<replaceable>NAME</replaceable>…]</term>
<listitem><para>Show properties of one or more registered
virtual machine or container images, or the manager itself. If
@@ -599,8 +607,8 @@
<listitem><para>Clones a container or VM image. The arguments specify the name of the image to clone and the
name of the newly cloned image. Note that plain directory container images are cloned into btrfs subvolume
images with this command, if the underlying file system supports this. Note that cloning a container or VM
- image is optimized for btrfs file systems, and might not be efficient on others, due to file system
- limitations.</para>
+ image is optimized for file systems that support copy-on-write, and might not be efficient on others, due to
+ file system limitations.</para>
<para>Note that this command leaves host name, machine ID and
all other settings that could identify the instance
@@ -630,7 +638,7 @@
</varlistentry>
<varlistentry>
- <term><command>remove</command> <replaceable>NAME</replaceable>...</term>
+ <term><command>remove</command> <replaceable>NAME</replaceable>…</term>
<listitem><para>Removes one or more container or VM images.
The special image <literal>.host</literal>, which refers to
@@ -849,7 +857,7 @@
</varlistentry>
<varlistentry>
- <term><command>cancel-transfers</command> <replaceable>ID</replaceable>...</term>
+ <term><command>cancel-transfers</command> <replaceable>ID</replaceable>…</term>
<listitem><para>Aborts a download, import or export of the
container or VM image with the specified ID. To list ongoing
@@ -910,7 +918,7 @@
<filename>/var/lib/machines/</filename> to make them available for
control with <command>machinectl</command>.</para>
- <para>Note that many image operations are only supported,
+ <para>Note that some image operations are only supported,
efficient or atomic on btrfs file systems. Due to this, if the
<command>pull-tar</command>, <command>pull-raw</command>,
<command>import-tar</command>, <command>import-raw</command> and
diff --git a/man/networkctl.xml b/man/networkctl.xml
index 24e1de6986..809eb7ec6a 100644
--- a/man/networkctl.xml
+++ b/man/networkctl.xml
@@ -102,7 +102,7 @@
<varlistentry>
<term>
<command>list</command>
- <optional><replaceable>LINK...</replaceable></optional>
+ <optional><replaceable>LINK…</replaceable></optional>
</term>
<listitem>
@@ -122,7 +122,7 @@
<varlistentry>
<term>
<command>status</command>
- <optional><replaceable>LINK...</replaceable></optional>
+ <optional><replaceable>LINK…</replaceable></optional>
</term>
<listitem>
@@ -150,7 +150,7 @@
<varlistentry>
<term>
<command>lldp</command>
- <optional><replaceable>LINK...</replaceable></optional>
+ <optional><replaceable>LINK…</replaceable></optional>
</term>
<listitem>
diff --git a/man/nss-resolve.xml b/man/nss-resolve.xml
index 9f24f65019..4e102cec26 100644
--- a/man/nss-resolve.xml
+++ b/man/nss-resolve.xml
@@ -63,16 +63,13 @@
hostnames via DNS.</para>
<para>To activate the NSS module, add <literal>resolve</literal> to the line starting with
- <literal>hosts:</literal> in <filename>/etc/nsswitch.conf</filename>.</para>
-
- <para>It is recommended to place <literal>resolve</literal> early in <filename>/etc/nsswitch.conf</filename>'
- <literal>hosts:</literal> line (but after the <literal>files</literal> or <literal>mymachines</literal> entries),
- replacing the <literal>dns</literal> entry if it exists, to ensure DNS queries are always routed via
- <citerefentry><refentrytitle>systemd-resolved</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
-
- <para>Note that <command>nss-resolve</command> will chain-load <command>nss-dns</command> if
- <filename>systemd-resolved.service</filename> is not running, ensuring that basic DNS resolution continues to work
- if the service is down.</para>
+ <literal>hosts:</literal> in <filename>/etc/nsswitch.conf</filename>. Specifcally, it is recommended to place
+ <literal>resolve</literal> early in <filename>/etc/nsswitch.conf</filename>' <literal>hosts:</literal> line (but
+ after the <literal>files</literal> or <literal>mymachines</literal> entries), right before the
+ <literal>dns</literal> entry if it exists, followed by <literal>[!UNAVAIL=return]</literal>, to ensure DNS queries
+ are always routed via
+ <citerefentry><refentrytitle>systemd-resolved</refentrytitle><manvolnum>8</manvolnum></citerefentry> if it is
+ running, but are routed to <command>nss-dns</command> if this service is not available.</para>
</refsect1>
<refsect1>
@@ -94,9 +91,6 @@ ethers: db files
rpc: db files
netgroup: nis</programlisting>
-
- <para>This keeps the <command>dns</command> module as a fallback for cases where the <command>nss-resolve</command>
- module is not installed.</para>
</refsect1>
<refsect1>
diff --git a/man/pam_systemd.xml b/man/pam_systemd.xml
index ddda81bc90..cef5445c1c 100644
--- a/man/pam_systemd.xml
+++ b/man/pam_systemd.xml
@@ -59,29 +59,23 @@
<citerefentry><refentrytitle>systemd-logind.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
and hence the systemd control group hierarchy.</para>
- <para>On login, this module ensures the following:</para>
+ <para>On login, this module — in conjunction with <filename>systemd-logind.service</filename> — ensures the
+ following:</para>
<orderedlist>
- <listitem><para>If it does not exist yet, the user runtime
- directory <filename>/run/user/$USER</filename> is created and
- its ownership changed to the user that is logging
- in.</para></listitem>
-
- <listitem><para>The <varname>$XDG_SESSION_ID</varname>
- environment variable is initialized. If auditing is available
- and <command>pam_loginuid.so</command> was run before this
- module (which is highly recommended), the variable is
- initialized from the auditing session id
- (<filename>/proc/self/sessionid</filename>). Otherwise, an
+ <listitem><para>If it does not exist yet, the user runtime directory <filename>/run/user/$UID</filename> is
+ either created or mounted as new <literal>tmpfs</literal> file system with quota applied, and its ownership
+ changed to the user that is logging in.</para></listitem>
+
+ <listitem><para>The <varname>$XDG_SESSION_ID</varname> environment variable is initialized. If auditing is
+ available and <command>pam_loginuid.so</command> was run before this module (which is highly recommended), the
+ variable is initialized from the auditing session id (<filename>/proc/self/sessionid</filename>). Otherwise, an
independent session counter is used.</para></listitem>
- <listitem><para>A new systemd scope unit is created for the
- session. If this is the first concurrent session of the user, an
- implicit slice below <filename>user.slice</filename> is
- automatically created and the scope placed into it. An instance
- of the system service <filename>user@.service</filename>, which
- runs the systemd user manager instance, is started.
- </para></listitem>
+ <listitem><para>A new systemd scope unit is created for the session. If this is the first concurrent session of
+ the user, an implicit per-user slice unit below <filename>user.slice</filename> is automatically created and the
+ scope placed into it. An instance of the system service <filename>user@.service</filename>, which runs the
+ systemd user manager instance, is started. </para></listitem>
</orderedlist>
<para>On logout, this module ensures the following:</para>
@@ -89,13 +83,12 @@
<orderedlist>
<listitem><para>If enabled in
<citerefentry><refentrytitle>logind.conf</refentrytitle>
- <manvolnum>5</manvolnum></citerefentry>, all processes of the
- session are terminated. If the last concurrent session of a user
- ends, the user's systemd instance will be terminated too, and so
- will the user's slice unit.</para></listitem>
+ <manvolnum>5</manvolnum></citerefentry> (<varname>KillUserProcesses=</varname>), all processes of the session are
+ terminated. If the last concurrent session of a user ends, the user's systemd instance will be terminated too,
+ and so will the user's slice unit.</para></listitem>
<listitem><para>If the last concurrent session of a user ends,
- the <varname>$XDG_RUNTIME_DIR</varname> directory and all its
+ the user runtime directory <filename>/run/user/$UID</filename> and all its
contents are removed, too.</para></listitem>
</orderedlist>
@@ -199,7 +192,8 @@
offers the greatest possible file system feature set the
operating system provides. For further details, see the <ulink
url="http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html">XDG
- Base Directory Specification</ulink>.</para></listitem>
+ Base Directory Specification</ulink>. <varname>$XDG_RUNTIME_DIR</varname>
+ is not set if the current user is not the original user of the session.</para></listitem>
</varlistentry>
</variablelist>
diff --git a/man/resolved.conf.xml b/man/resolved.conf.xml
index 4fc1ef1b33..7babc5c5c4 100644
--- a/man/resolved.conf.xml
+++ b/man/resolved.conf.xml
@@ -127,6 +127,21 @@
</varlistentry>
<varlistentry>
+ <term><varname>MulticastDNS=</varname></term>
+ <listitem><para>Takes a boolean argument or
+ <literal>resolve</literal>. Controls Multicast DNS support (<ulink
+ url="https://tools.ietf.org/html/rfc6762">RFC 6762</ulink>) on
+ the local host. If true, enables full Multicast DNS responder and
+ resolver support. If false, disables both. If set to
+ <literal>resolve</literal>, only resolution support is enabled,
+ but responding is disabled. Note that
+ <citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ also maintains per-link Multicast DNS settings. Multicast DNS will be
+ enabled on a link only if the per-link and the
+ global setting is on.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>DNSSEC=</varname></term>
<listitem><para>Takes a boolean argument or
<literal>allow-downgrade</literal>. If true all DNS lookups are
diff --git a/man/sd-bus.xml b/man/sd-bus.xml
index 66b1c96c15..6439395549 100644
--- a/man/sd-bus.xml
+++ b/man/sd-bus.xml
@@ -62,7 +62,7 @@
<title>Description</title>
<para><filename>sd-bus.h</filename> provides an implementation of a D-Bus IPC client. See
- <ulink url="http://www.freedesktop.org/software/dbus/" />
+ <ulink url="https://www.freedesktop.org/software/dbus/" />
for more information about D-Bus IPC.
</para>
diff --git a/man/sd-id128.xml b/man/sd-id128.xml
index 5f24feff8e..bc74e3f481 100644
--- a/man/sd-id128.xml
+++ b/man/sd-id128.xml
@@ -47,6 +47,7 @@
<refname>sd-id128</refname>
<refname>sd_id128_t</refname>
<refname>SD_ID128_MAKE</refname>
+ <refname>SD_ID128_MAKE_STR</refname>
<refname>SD_ID128_NULL</refname>
<refname>SD_ID128_CONST_STR</refname>
<refname>SD_ID128_FORMAT_STR</refname>
@@ -113,12 +114,24 @@
<para><function>SD_ID128_NULL</function> may be used to refer to the 128bit ID consisting of only NUL
bytes.</para>
+ <para><function>SD_ID128_MAKE_STR()</function> is similar to <function>SD_ID128_MAKE()</function>, but creates a
+ <type>const char*</type> expression that can be conveniently used in message formats and such:</para>
+
+ <programlisting>#include &lt;stdio.h&gt;
+#define SD_MESSAGE_COREDUMP_STR SD_ID128_MAKE_STR(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1)
+
+int main(int argc, char **argv) {
+ puts("Match for coredumps: MESSAGE_ID=" SD_MESSAGE_COREDUMP_STR);
+}
+ </programlisting>
+
+
<para><function>SD_ID128_CONST_STR()</function> may be used to
convert constant 128-bit IDs into constant strings for output. The
following example code will output the string
"fc2e22bc6ee647b6b90729ab34a250b1":</para>
<programlisting>int main(int argc, char *argv[]) {
- puts(SD_ID128_CONST_STR(SD_MESSAGE_COREDUMP));
+ puts("Match for coredumps: %s", SD_ID128_CONST_STR(SD_MESSAGE_COREDUMP));
}</programlisting>
<para><function>SD_ID128_FORMAT_STR()</function> and
@@ -154,7 +167,7 @@
<para>Note that new, randomized IDs may be generated with
<citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
- <option>--new-id</option> option.</para>
+ <option>--new-id128</option> option.</para>
</refsect1>
<xi:include href="libsystemd-pkgconfig.xml" />
diff --git a/man/sd-login.xml b/man/sd-login.xml
index 328f71164d..6861fbe257 100644
--- a/man/sd-login.xml
+++ b/man/sd-login.xml
@@ -67,7 +67,7 @@
local system. </para>
<para>See <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/multiseat">Multi-Seat
+ url="https://www.freedesktop.org/wiki/Software/systemd/multiseat">Multi-Seat
on Linux</ulink> for an introduction into multi-seat support on
Linux, the background for this set of APIs.</para>
diff --git a/man/sd_bus_error.xml b/man/sd_bus_error.xml
index c2d7ee389b..3091e1f019 100644
--- a/man/sd_bus_error.xml
+++ b/man/sd_bus_error.xml
@@ -68,7 +68,7 @@
<funcsynopsisinfo>typedef struct {
const char *name;
const char *message;
- ...
+ …
} sd_bus_error;</funcsynopsisinfo>
<para>
@@ -95,7 +95,7 @@
<paramdef>sd_bus_error *<parameter>e</parameter></paramdef>
<paramdef>const char *<parameter>name</parameter></paramdef>
<paramdef>const char *<parameter>format</parameter></paramdef>
- <paramdef>...</paramdef>
+ <paramdef>…</paramdef>
</funcprototype>
<funcprototype>
@@ -116,7 +116,7 @@
<paramdef>sd_bus_error *<parameter>e</parameter></paramdef>
<paramdef>int <parameter>error</parameter></paramdef>
<paramdef>const char *<parameter>format</parameter></paramdef>
- <paramdef>...</paramdef>
+ <paramdef>…</paramdef>
</funcprototype>
<funcprototype>
diff --git a/man/sd_bus_error_add_map.xml b/man/sd_bus_error_add_map.xml
index 7dc1ef6c90..55402dfc2a 100644
--- a/man/sd_bus_error_add_map.xml
+++ b/man/sd_bus_error_add_map.xml
@@ -58,7 +58,7 @@
<funcsynopsisinfo>typedef struct {
const char *name;
int code;
- ...
+ …
} sd_bus_error_map;</funcsynopsisinfo>
</funcsynopsis>
diff --git a/man/sd_bus_message_append.xml b/man/sd_bus_message_append.xml
index c222d0fd0e..132ce66434 100644
--- a/man/sd_bus_message_append.xml
+++ b/man/sd_bus_message_append.xml
@@ -58,7 +58,7 @@
<funcdef>int sd_bus_message_append</funcdef>
<paramdef>sd_bus_message *<parameter>m</parameter></paramdef>
<paramdef>const char *<parameter>types</parameter></paramdef>
- <paramdef>...</paramdef>
+ <paramdef>…</paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
@@ -198,7 +198,7 @@ dictionary ::= "a" "{" basic_type complete_type "}"
</para>
<programlisting>sd_bus_message *m;
-...
+…
sd_bus_message_append(m, "s", "a string");</programlisting>
<para>Append all types of integers:</para>
diff --git a/man/sd_bus_path_encode.xml b/man/sd_bus_path_encode.xml
index 3088243e45..986eccc6a8 100644
--- a/man/sd_bus_path_encode.xml
+++ b/man/sd_bus_path_encode.xml
@@ -66,7 +66,7 @@
<funcdef>int <function>sd_bus_path_encode_many</function></funcdef>
<paramdef>char **<parameter>out</parameter></paramdef>
<paramdef>const char *<parameter>path_template</parameter></paramdef>
- <paramdef>...</paramdef>
+ <paramdef>…</paramdef>
</funcprototype>
<funcprototype>
@@ -80,7 +80,7 @@
<funcdef>int <function>sd_bus_path_decode_many</function></funcdef>
<paramdef>const char *<parameter>path</parameter></paramdef>
<paramdef>const char *<parameter>path_template</parameter></paramdef>
- <paramdef>...</paramdef>
+ <paramdef>…</paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
diff --git a/man/sd_event_add_defer.xml b/man/sd_event_add_defer.xml
index d9ebd3b179..ab28b330fe 100644
--- a/man/sd_event_add_defer.xml
+++ b/man/sd_event_add_defer.xml
@@ -153,7 +153,7 @@
<refsect1>
<title>Return Value</title>
- <para>On success, this functions return 0 or a positive
+ <para>On success, these functions return 0 or a positive
integer. On failure, they return a negative errno-style error
code.</para>
</refsect1>
diff --git a/man/sd_event_source_set_prepare.xml b/man/sd_event_source_set_prepare.xml
index 24861d01d9..ee61d23983 100644
--- a/man/sd_event_source_set_prepare.xml
+++ b/man/sd_event_source_set_prepare.xml
@@ -76,10 +76,11 @@
specified as <parameter>callback</parameter> will be invoked
immediately before the event loop goes to sleep to wait for
incoming events. It is invoked with the user data pointer passed
- when the event source was created. The callback function may be
- used to reconfigure the precise events to wait for. If the
- <parameter>callback</parameter> parameter is passed as NULL the
- callback function is reset. </para>
+ when the event source was created. The event source will be disabled
+ if the callback function returns a negative error code. The callback
+ function may be used to reconfigure the precise events to wait for.
+ If the <parameter>callback</parameter> parameter is passed as NULL
+ the callback function is reset. </para>
<para>Event source objects have no preparation callback associated
when they are first created with calls such as
diff --git a/man/sd_id128_get_machine.xml b/man/sd_id128_get_machine.xml
index 9a86c24aed..3938c6d836 100644
--- a/man/sd_id128_get_machine.xml
+++ b/man/sd_id128_get_machine.xml
@@ -44,6 +44,7 @@
<refnamediv>
<refname>sd_id128_get_machine</refname>
+ <refname>sd_id128_get_machine_app_specific</refname>
<refname>sd_id128_get_boot</refname>
<refname>sd_id128_get_invocation</refname>
<refpurpose>Retrieve 128-bit IDs</refpurpose>
@@ -59,6 +60,12 @@
</funcprototype>
<funcprototype>
+ <funcdef>int <function>sd_id128_get_machine_app_specific</function></funcdef>
+ <paramdef>sd_id128_t <parameter>app_id</parameter></paramdef>
+ <paramdef>sd_id128_t *<parameter>ret</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
<funcdef>int <function>sd_id128_get_boot</function></funcdef>
<paramdef>sd_id128_t *<parameter>ret</parameter></paramdef>
</funcprototype>
@@ -74,11 +81,22 @@
<refsect1>
<title>Description</title>
- <para><function>sd_id128_get_machine()</function> returns the
- machine ID of the executing host. This reads and parses the
- <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- file. This function caches the machine ID internally to make
- retrieving the machine ID a cheap operation.</para>
+ <para><function>sd_id128_get_machine()</function> returns the machine ID of the executing host. This reads and
+ parses the <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ file. This function caches the machine ID internally to make retrieving the machine ID a cheap operation. This ID
+ may be used wherever a unique identifier for the local system is needed. However, it is recommended to use this ID
+ as-is only in trusted environments. In untrusted environments it is recommended to derive an application specific
+ ID from this machine ID, in an irreversable (cryptographically secure) way. To make this easy
+ <function>sd_id128_get_machine_app_specific()</function> is provided, see below.</para>
+
+ <para><function>sd_id128_get_machine_app_specific()</function> is similar to
+ <function>sd_id128_get_machine()</function>, but retrieves a machine ID that is specific to the application that is
+ identified by the indicated application ID. It is recommended to use this function instead of
+ <function>sd_id128_get_machine()</function> when passing an ID to untrusted environments, in order to make sure
+ that the original machine ID may not be determined externally. The application-specific ID should be generated via
+ a tool like <command>journalctl --new-id128</command>, and may be compiled into the application. This function will
+ return the same application-specific ID for each combination of machine ID and application ID. Internally, this
+ function calculates HMAC-SHA256 of the application ID, keyed by the machine ID.</para>
<para><function>sd_id128_get_boot()</function> returns the boot ID
of the executing kernel. This reads and parses the
@@ -95,10 +113,10 @@
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details. The
ID is cached internally. In future a different mechanism to determine the invocation ID may be added.</para>
- <para>Note that <function>sd_id128_get_boot()</function> and <function>sd_id128_get_invocation()</function> always
- return UUID v4 compatible IDs. <function>sd_id128_get_machine()</function> will also return a UUID v4-compatible
- ID on new installations but might not on older. It is possible to convert the machine ID into a UUID v4-compatible
- one. For more information, see
+ <para>Note that <function>sd_id128_get_machine_app_specific()</function>, <function>sd_id128_get_boot()</function>
+ and <function>sd_id128_get_invocation()</function> always return UUID v4 compatible IDs.
+ <function>sd_id128_get_machine()</function> will also return a UUID v4-compatible ID on new installations but might
+ not on older. It is possible to convert the machine ID into a UUID v4-compatible one. For more information, see
<citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
<para>For more information about the <literal>sd_id128_t</literal>
@@ -117,13 +135,36 @@
<refsect1>
<title>Notes</title>
- <para>The <function>sd_id128_get_machine()</function>, <function>sd_id128_get_boot()</function> and
- <function>sd_id128_get_invocation()</function> interfaces are available as a shared library, which can be compiled
- and linked to with the <literal>libsystemd</literal> <citerefentry
+ <para>The <function>sd_id128_get_machine()</function>, <function>sd_id128_get_machine_app_specific()</function>
+ <function>sd_id128_get_boot()</function> and <function>sd_id128_get_invocation()</function> interfaces are
+ available as a shared library, which can be compiled and linked to with the
+ <literal>libsystemd</literal> <citerefentry
project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry> file.</para>
</refsect1>
<refsect1>
+ <title>Examples</title>
+
+ <example>
+ <title>Application-specific machine ID</title>
+
+ <para>Here's a simple example for an application specific machine ID:</para>
+
+ <programlisting>#include &lt;systemd/sd-id128.h&gt;
+#include &lt;stdio.h&gt;
+
+#define OUR_APPLICATION_ID SD_ID128_MAKE(c2,73,27,73,23,db,45,4e,a6,3b,b9,6e,79,b5,3e,97)
+
+int main(int argc, char *argv[]) {
+ sd_id128_t id;
+ sd_id128_get_machine_app_specific(OUR_APPLICATION_ID, &amp;id);
+ printf("Our application ID: " SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(id));
+ return 0;
+}</programlisting>
+ </example>
+ </refsect1>
+
+ <refsect1>
<title>See Also</title>
<para>
diff --git a/man/sd_is_fifo.xml b/man/sd_is_fifo.xml
index 7ff02cbfec..1192ca1681 100644
--- a/man/sd_is_fifo.xml
+++ b/man/sd_is_fifo.xml
@@ -48,6 +48,7 @@
<refname>sd_is_socket</refname>
<refname>sd_is_socket_inet</refname>
<refname>sd_is_socket_unix</refname>
+ <refname>sd_is_socket_sockaddr</refname>
<refname>sd_is_mq</refname>
<refname>sd_is_special</refname>
<refpurpose>Check the type of a file descriptor</refpurpose>
@@ -81,6 +82,15 @@
</funcprototype>
<funcprototype>
+ <funcdef>int <function>sd_is_socket_sockaddr</function></funcdef>
+ <paramdef>int <parameter>fd</parameter></paramdef>
+ <paramdef>int <parameter>type</parameter></paramdef>
+ <paramdef>const struct sockaddr *<parameter>addr</parameter></paramdef>
+ <paramdef>unsigned <parameter>addr_len</parameter></paramdef>
+ <paramdef>int <parameter>listening</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
<funcdef>int <function>sd_is_socket_unix</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
<paramdef>int <parameter>type</parameter></paramdef>
@@ -118,10 +128,10 @@
<parameter>family</parameter> parameter is not
<constant>AF_UNSPEC</constant>, it is checked whether the socket
is of the specified family (<constant>AF_UNIX</constant>,
- <constant>AF_INET</constant>, ...). If the <parameter>type</parameter>
+ <constant>AF_INET</constant>, …). If the <parameter>type</parameter>
parameter is not 0, it is checked whether the socket is of the
specified type (<constant>SOCK_STREAM</constant>,
- <constant>SOCK_DGRAM</constant>, ...). If the
+ <constant>SOCK_DGRAM</constant>, …). If the
<parameter>listening</parameter> parameter is positive, it is
checked whether the socket is in accepting mode, i.e.
<function>listen()</function> has been called for it. If
@@ -139,6 +149,18 @@
<constant>AF_UNSPEC</constant>, <constant>AF_INET</constant>, or
<constant>AF_INET6</constant>.</para>
+ <para><function>sd_is_socket_sockaddr()</function> is similar to
+ <function>sd_is_socket_inet()</function>, but checks if the socket is bound to the
+ address specified by <parameter>addr</parameter>. The
+ <structfield>family</structfield> specified by <parameter>addr</parameter> must be
+ either <constant>AF_INET</constant> or <constant>AF_INET6</constant> and
+ <parameter>addr_len</parameter> must be large enough for that family. If
+ <parameter>addr</parameter> specifies a non-zero port, it is also checked if the
+ socket is bound to this port. In addition, for IPv6, if <parameter>addr</parameter>
+ specifies non-zero <structfield>sin6_flowinfo</structfield> or
+ <structfield>sin6_scope_id</structfield>, it is checked if the socket has the same
+ values.</para>
+
<para><function>sd_is_socket_unix()</function> is similar to
<function>sd_is_socket()</function> but optionally checks the
<constant>AF_UNIX</constant> path the socket is bound to, unless
@@ -193,7 +215,13 @@
<citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ <citerefentry project='man-pages'><refentrytitle>ip</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ <citerefentry project='man-pages'><refentrytitle>ipv6</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ <citerefentry project='man-pages'><refentrytitle>unix</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ <citerefentry project='man-pages'><refentrytitle>fifo</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ <citerefentry project='man-pages'><refentrytitle>mq_overview</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ <citerefentry project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
</para>
</refsect1>
diff --git a/man/sd_journal_add_match.xml b/man/sd_journal_add_match.xml
index 7c64329aed..2294b43643 100644
--- a/man/sd_journal_add_match.xml
+++ b/man/sd_journal_add_match.xml
@@ -190,7 +190,7 @@
message ID 03bb1dab98ab4ecfbf6fff2738bdd964 coming from any
service (this example lacks the necessary error checking):</para>
- <programlisting>...
+ <programlisting>…
int add_matches(sd_journal *j) {
sd_journal_add_match(j, "_SYSTEMD_UNIT=avahi-daemon.service", 0);
sd_journal_add_match(j, "PRIORITY=0", 0);
diff --git a/man/sd_journal_get_catalog.xml b/man/sd_journal_get_catalog.xml
index 35ec46f63e..604deb4e8c 100644
--- a/man/sd_journal_get_catalog.xml
+++ b/man/sd_journal_get_catalog.xml
@@ -90,7 +90,7 @@
<para>For more information about the journal message catalog
please refer to the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/catalog">Journal
+ url="https://www.freedesktop.org/wiki/Software/systemd/catalog">Journal
Message Catalogs</ulink> documentation page.</para>
</refsect1>
diff --git a/man/sd_journal_get_data.xml b/man/sd_journal_get_data.xml
index 1321114de0..01e436e70d 100644
--- a/man/sd_journal_get_data.xml
+++ b/man/sd_journal_get_data.xml
@@ -207,14 +207,14 @@
iterate through all fields of the current journal
entry:</para>
- <programlisting>...
+ <programlisting>…
int print_fields(sd_journal *j) {
const void *data;
size_t length;
SD_JOURNAL_FOREACH_DATA(j, data, length)
printf("%.*s\n", (int) length, data);
}
-...</programlisting>
+…</programlisting>
</refsect1>
diff --git a/man/sd_journal_get_fd.xml b/man/sd_journal_get_fd.xml
index 61293f7f99..2e686caccb 100644
--- a/man/sd_journal_get_fd.xml
+++ b/man/sd_journal_get_fd.xml
@@ -146,7 +146,7 @@ if (t == (uint64_t) -1)
else {
struct timespec ts;
uint64_t n;
- clock_getttime(CLOCK_MONOTONIC, &amp;ts);
+ clock_gettime(CLOCK_MONOTONIC, &amp;ts);
n = (uint64_t) ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
msec = t > n ? (int) ((t - n + 999) / 1000) : 0;
}</programlisting>
@@ -304,7 +304,7 @@ int wait_for_changes(sd_journal *j) {
else {
struct timespec ts;
uint64_t n;
- clock_getttime(CLOCK_MONOTONIC, &amp;ts);
+ clock_gettime(CLOCK_MONOTONIC, &amp;ts);
n = (uint64_t) ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
msec = t > n ? (int) ((t - n + 999) / 1000) : 0;
}
diff --git a/man/sd_journal_print.xml b/man/sd_journal_print.xml
index 2d8dd635aa..a741abe32d 100644
--- a/man/sd_journal_print.xml
+++ b/man/sd_journal_print.xml
@@ -60,7 +60,7 @@
<funcdef>int <function>sd_journal_print</function></funcdef>
<paramdef>int <parameter>priority</parameter></paramdef>
<paramdef>const char *<parameter>format</parameter></paramdef>
- <paramdef>...</paramdef>
+ <paramdef>…</paramdef>
</funcprototype>
<funcprototype>
@@ -73,7 +73,7 @@
<funcprototype>
<funcdef>int <function>sd_journal_send</function></funcdef>
<paramdef>const char *<parameter>format</parameter></paramdef>
- <paramdef>...</paramdef>
+ <paramdef>…</paramdef>
</funcprototype>
<funcprototype>
@@ -133,7 +133,7 @@
project='man-pages'><refentrytitle>readv</refentrytitle><manvolnum>3</manvolnum></citerefentry> for details)
instead of the format string. Each structure should reference one field of the entry to submit. The second argument
specifies the number of structures in the array. <function>sd_journal_sendv()</function> is particularly useful to
- submit binary objects to the journal where that is necessary. Note that this function wil not strip trailing
+ submit binary objects to the journal where that is necessary. Note that this function will not strip trailing
whitespace of the passed fields, but passes the specified data along unmodified. This is different from both
<function>sd_journal_print()</function> and <function>sd_journal_send()</function> described above, which are based
on format strings, and do strip trailing whitespace.</para>
@@ -189,10 +189,9 @@ sd_journal_send("MESSAGE=Hello World, this is PID %lu!", (unsigned long) getpid(
<refsect1>
<title>Return Value</title>
- <para>The four calls return 0 on success or a negative errno-style
- error code. The
- <citerefentry project='man-pages'><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- variable itself is not altered.</para>
+ <para>The five calls return 0 on success or a negative errno-style error code. The <citerefentry
+ project='man-pages'><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry> variable itself is
+ not altered.</para>
<para>If
<citerefentry><refentrytitle>systemd-journald</refentrytitle><manvolnum>8</manvolnum></citerefentry>
@@ -218,13 +217,11 @@ sd_journal_send("MESSAGE=Hello World, this is PID %lu!", (unsigned long) getpid(
<refsect1>
<title>Notes</title>
- <para>The <function>sd_journal_print()</function>,
- <function>sd_journal_printv()</function>,
- <function>sd_journal_send()</function> and
- <function>sd_journal_sendv()</function> interfaces are available
- as a shared library, which can be compiled and linked to with the
- <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
- file.</para>
+ <para>The <function>sd_journal_print()</function>, <function>sd_journal_printv()</function>,
+ <function>sd_journal_send()</function>, <function>sd_journal_sendv()</function> and
+ <function>sd_journal_perror()</function> interfaces are available as a shared library, which can be compiled and
+ linked to with the <constant>libsystemd</constant> <citerefentry
+ project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry> file.</para>
</refsect1>
<refsect1>
diff --git a/man/sd_listen_fds.xml b/man/sd_listen_fds.xml
index 93bf8d853f..c1c2423884 100644
--- a/man/sd_listen_fds.xml
+++ b/man/sd_listen_fds.xml
@@ -79,7 +79,7 @@
received, zero is returned. The first file descriptor may be found
at file descriptor number 3
(i.e. <constant>SD_LISTEN_FDS_START</constant>), the remaining
- descriptors follow at 4, 5, 6, ..., if any.</para>
+ descriptors follow at 4, 5, 6, …, if any.</para>
<para>If a daemon receives more than one file descriptor, they
will be passed in the same order as configured in the systemd
diff --git a/man/sd_login_monitor_new.xml b/man/sd_login_monitor_new.xml
index 5625ab9207..129c99f97d 100644
--- a/man/sd_login_monitor_new.xml
+++ b/man/sd_login_monitor_new.xml
@@ -203,7 +203,7 @@ if (t == (uint64_t) -1)
else {
struct timespec ts;
uint64_t n;
- clock_getttime(CLOCK_MONOTONIC, &amp;ts);
+ clock_gettime(CLOCK_MONOTONIC, &amp;ts);
n = (uint64_t) ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
msec = t > n ? (int) ((t - n + 999) / 1000) : 0;
}</programlisting>
diff --git a/man/sd_notify.xml b/man/sd_notify.xml
index 94542b80b8..4dcefc4baf 100644
--- a/man/sd_notify.xml
+++ b/man/sd_notify.xml
@@ -66,7 +66,7 @@
<funcdef>int <function>sd_notifyf</function></funcdef>
<paramdef>int <parameter>unset_environment</parameter></paramdef>
<paramdef>const char *<parameter>format</parameter></paramdef>
- <paramdef>...</paramdef>
+ <paramdef>…</paramdef>
</funcprototype>
<funcprototype>
@@ -81,7 +81,7 @@
<paramdef>pid_t <parameter>pid</parameter></paramdef>
<paramdef>int <parameter>unset_environment</parameter></paramdef>
<paramdef>const char *<parameter>format</parameter></paramdef>
- <paramdef>...</paramdef>
+ <paramdef>…</paramdef>
</funcprototype>
<funcprototype>
@@ -152,7 +152,7 @@
</varlistentry>
<varlistentry>
- <term>STATUS=...</term>
+ <term>STATUS=…</term>
<listitem><para>Passes a single-line UTF-8 status string back
to the service manager that describes the service state. This
@@ -160,11 +160,11 @@
state feedback, fsck-like programs could pass completion
percentages and failing programs could pass a human-readable
error message. Example: <literal>STATUS=Completed 66% of file
- system check...</literal></para></listitem>
+ system check…</literal></para></listitem>
</varlistentry>
<varlistentry>
- <term>ERRNO=...</term>
+ <term>ERRNO=…</term>
<listitem><para>If a service fails, the errno-style error
code, formatted as string. Example: <literal>ERRNO=2</literal>
@@ -172,7 +172,7 @@
</varlistentry>
<varlistentry>
- <term>BUSERROR=...</term>
+ <term>BUSERROR=…</term>
<listitem><para>If a service fails, the D-Bus error-style
error code. Example:
@@ -180,7 +180,7 @@
</varlistentry>
<varlistentry>
- <term>MAINPID=...</term>
+ <term>MAINPID=…</term>
<listitem><para>The main process ID (PID) of the service, in
case the service manager did not fork off the process itself.
@@ -227,7 +227,7 @@
</varlistentry>
<varlistentry>
- <term>FDNAME=...</term>
+ <term>FDNAME=…</term>
<listitem><para>When used in combination with
<varname>FDSTORE=1</varname>, specifies a name for the
@@ -248,7 +248,7 @@
</varlistentry>
<varlistentry>
- <term>WATCHDOG_USEC=...</term>
+ <term>WATCHDOG_USEC=…</term>
<listitem><para>Reset <varname>watchdog_usec</varname> value during runtime.
Notice that this is not available when using <function>sd_event_set_watchdog()</function>
@@ -268,6 +268,15 @@
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details.</para>
+ <para>Note that <function>sd_notify()</function> notifications may be attributed to units correctly only if either
+ the sending process is still around at the time PID 1 processes the message, or if the sending process is
+ explicitly runtime-tracked by the service manager. The latter is the case if the service manager originally forked
+ off the process, i.e. on all processes that match <varname>NotifyAccess=</varname><option>main</option> or
+ <varname>NotifyAccess=</varname><option>exec</option>. Conversely, if an auxiliary process of the unit sends an
+ <function>sd_notify()</function> message and immediately exits, the service manager might not be able to properly
+ attribute the message to the unit, and thus will ignore it, even if
+ <varname>NotifyAccess=</varname><option>all</option> is set for it.</para>
+
<para><function>sd_notifyf()</function> is similar to
<function>sd_notify()</function> but takes a
<function>printf()</function>-like format string plus
@@ -362,7 +371,7 @@
initialization:</para>
<programlisting>sd_notifyf(0, "READY=1\n"
- "STATUS=Processing requests...\n"
+ "STATUS=Processing requests…\n"
"MAINPID=%lu",
(unsigned long) getpid());</programlisting>
</example>
diff --git a/man/sd_watchdog_enabled.xml b/man/sd_watchdog_enabled.xml
index 3de9899453..759d9303c6 100644
--- a/man/sd_watchdog_enabled.xml
+++ b/man/sd_watchdog_enabled.xml
@@ -121,7 +121,7 @@
<xi:include href="libsystemd-pkgconfig.xml" xpointer="pkgconfig-text"/>
- <para>Internally, this functions parses the
+ <para>Internally, this function parses the
<varname>$WATCHDOG_PID</varname> and
<varname>$WATCHDOG_USEC</varname> environment variable. The call
will ignore these variables if <varname>$WATCHDOG_PID</varname>
@@ -148,7 +148,7 @@
<listitem><para>Set by the system manager for supervised
process for which watchdog support is enabled, and contains
- the watchdog timeout in µs See above for
+ the watchdog timeout in µs. See above for
details.</para></listitem>
</varlistentry>
</variablelist>
diff --git a/man/systemctl.xml b/man/systemctl.xml
index dfa00e0c03..7e1864c4f1 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -209,6 +209,10 @@
<varname>RequiresMountsFor=</varname>). Both explicitly
and implicitly introduced dependencies are shown with
<command>list-dependencies</command>.</para>
+
+ <para>When passed to the <command>list-jobs</command> command, for each printed job show which other jobs are
+ waiting for it. May be combined with <option>--before</option> to show both the jobs waiting for each job as
+ well as all jobs each job is waiting for.</para>
</listitem>
</varlistentry>
@@ -220,6 +224,10 @@
units that are ordered after the specified unit. In other
words, recursively list units following the
<varname>Before=</varname> dependency.</para>
+
+ <para>When passed to the <command>list-jobs</command> command, for each printed job show which other jobs it
+ is waiting for. May be combined with <option>--after</option> to show both the jobs waiting for each job as
+ well as all jobs each job is waiting for.</para>
</listitem>
</varlistentry>
@@ -385,10 +393,14 @@
<xi:include href="user-system-options.xml" xpointer="user" />
<xi:include href="user-system-options.xml" xpointer="system" />
- <!-- we do not document -failed here, as it has been made
- redundant by -state=failed, which it predates. To keep
- things simple, we only document the new switch, while
- keeping the old one around for compatibility only. -->
+ <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>
@@ -656,7 +668,7 @@
<variablelist>
<varlistentry>
- <term><command>list-units <optional><replaceable>PATTERN</replaceable>...</optional></command></term>
+ <term><command>list-units <optional><replaceable>PATTERN</replaceable>…</optional></command></term>
<listitem>
<para>List units that <command>systemd</command> currently has in memory. This includes units that are
@@ -672,7 +684,7 @@
</varlistentry>
<varlistentry>
- <term><command>list-sockets <optional><replaceable>PATTERN</replaceable>...</optional></command></term>
+ <term><command>list-sockets <optional><replaceable>PATTERN</replaceable>…</optional></command></term>
<listitem>
<para>List socket units currently in memory, ordered by listening address. If one or more
@@ -681,7 +693,7 @@
<programlisting>
LISTEN UNIT ACTIVATES
/dev/initctl systemd-initctl.socket systemd-initctl.service
-...
+…
[::]:22 sshd.socket sshd.service
kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
@@ -695,19 +707,34 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</varlistentry>
<varlistentry>
- <term><command>list-timers <optional><replaceable>PATTERN</replaceable>...</optional></command></term>
+ <term><command>list-timers <optional><replaceable>PATTERN</replaceable>…</optional></command></term>
<listitem>
<para>List timer units currently in memory, ordered by the time they elapse next. If one or more
<replaceable>PATTERN</replaceable>s are specified, only units matching one of them are shown.
+ Produces output similar to
+ <programlisting>
+NEXT LEFT LAST PASSED UNIT ACTIVATES
+n/a n/a Thu 2017-02-23 13:40:29 EST 3 days ago ureadahead-stop.timer ureadahead-stop.service
+Sun 2017-02-26 18:55:42 EST 1min 14s left Thu 2017-02-23 13:54:44 EST 3 days ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
+Sun 2017-02-26 20:37:16 EST 1h 42min left Sun 2017-02-26 11:56:36 EST 6h ago apt-daily.timer apt-daily.service
+Sun 2017-02-26 20:57:49 EST 2h 3min left Sun 2017-02-26 11:56:36 EST 6h ago snapd.refresh.timer snapd.refresh.service
+ </programlisting>
</para>
+ <para><emphasis>NEXT</emphasis> shows the next time the timer will run.</para>
+ <para><emphasis>LEFT</emphasis> shows how long till the next time the timer runs.</para>
+ <para><emphasis>LAST</emphasis> shows the last time the timer ran.</para>
+ <para><emphasis>PASSED</emphasis> shows has long as passed since the timer laset ran.</para>
+ <para><emphasis>UNIT</emphasis> shows the name of the timer</para>
+ <para><emphasis>ACTIVATES</emphasis> shows the the name the service the timer activates when it runs.</para>
+
<para>Also see <option>--all</option> and <option>--state=</option>.</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><command>start <replaceable>PATTERN</replaceable>...</command></term>
+ <term><command>start <replaceable>PATTERN</replaceable>…</command></term>
<listitem>
<para>Start (activate) one or more units specified on the
@@ -721,7 +748,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</listitem>
</varlistentry>
<varlistentry>
- <term><command>stop <replaceable>PATTERN</replaceable>...</command></term>
+ <term><command>stop <replaceable>PATTERN</replaceable>…</command></term>
<listitem>
<para>Stop (deactivate) one or more units specified on the
@@ -729,7 +756,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</listitem>
</varlistentry>
<varlistentry>
- <term><command>reload <replaceable>PATTERN</replaceable>...</command></term>
+ <term><command>reload <replaceable>PATTERN</replaceable>…</command></term>
<listitem>
<para>Asks all units listed on the command line to reload
@@ -749,27 +776,27 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</varlistentry>
<varlistentry>
- <term><command>restart <replaceable>PATTERN</replaceable>...</command></term>
+ <term><command>restart <replaceable>PATTERN</replaceable>…</command></term>
<listitem>
- <para>Restart one or more units specified on the command
- line. If the units are not running yet, they will be
- started.</para>
+ <para>Stop and then start one or more units specified on the
+ command line. If the units are not running yet, they will
+ be started.</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><command>try-restart <replaceable>PATTERN</replaceable>...</command></term>
+ <term><command>try-restart <replaceable>PATTERN</replaceable>…</command></term>
<listitem>
- <para>Restart one or more units specified on the command
- line if the units are running. This does nothing if units are not
- running.</para>
+ <para>Stop and then start one or more units specified on the
+ command line if the units are running. This does nothing
+ if units are not running.</para>
<!-- Note that we don't document condrestart here, as that is just compatibility support, and we generally
don't document that. -->
</listitem>
</varlistentry>
<varlistentry>
- <term><command>reload-or-restart <replaceable>PATTERN</replaceable>...</command></term>
+ <term><command>reload-or-restart <replaceable>PATTERN</replaceable>…</command></term>
<listitem>
<para>Reload one or more units if they support it. If not,
@@ -778,7 +805,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</listitem>
</varlistentry>
<varlistentry>
- <term><command>try-reload-or-restart <replaceable>PATTERN</replaceable>...</command></term>
+ <term><command>try-reload-or-restart <replaceable>PATTERN</replaceable>…</command></term>
<listitem>
<para>Reload one or more units if they support it. If not,
@@ -810,7 +837,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</listitem>
</varlistentry>
<varlistentry>
- <term><command>kill <replaceable>PATTERN</replaceable>...</command></term>
+ <term><command>kill <replaceable>PATTERN</replaceable>…</command></term>
<listitem>
<para>Send a signal to one or more processes of the
@@ -820,7 +847,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</listitem>
</varlistentry>
<varlistentry>
- <term><command>is-active <replaceable>PATTERN</replaceable>...</command></term>
+ <term><command>is-active <replaceable>PATTERN</replaceable>…</command></term>
<listitem>
<para>Check whether any of the specified units are active
@@ -832,7 +859,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</listitem>
</varlistentry>
<varlistentry>
- <term><command>is-failed <replaceable>PATTERN</replaceable>...</command></term>
+ <term><command>is-failed <replaceable>PATTERN</replaceable>…</command></term>
<listitem>
<para>Check whether any of the specified units are in a
@@ -844,7 +871,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</listitem>
</varlistentry>
<varlistentry>
- <term><command>status</command> <optional><replaceable>PATTERN</replaceable>...|<replaceable>PID</replaceable>...]</optional></term>
+ <term><command>status</command> <optional><replaceable>PATTERN</replaceable>…|<replaceable>PID</replaceable>…]</optional></term>
<listitem>
<para>Show terse runtime status information about one or
@@ -868,27 +895,81 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
a similar filter for messages and might be more
convenient.
</para>
+
+ <para>Systemd implicitly loads units as necessary, so just running the <command>status</command> will
+ attempt to load a file. The command is thus not useful for determining if something was already loaded or
+ not. The units may possibly also be quickly unloaded after the operation is completed if there's no reason
+ to keep it in memory thereafter.
+ </para>
+
+ <example>
+ <title>Example output from systemctl status </title>
+
+ <programlisting>$ systemctl status bluetooth
+â— bluetooth.service - Bluetooth service
+ Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
+ Active: active (running) since Wed 2017-01-04 13:54:04 EST; 1 weeks 0 days ago
+ Docs: man:bluetoothd(8)
+ Main PID: 930 (bluetoothd)
+ Status: "Running"
+ Tasks: 1
+ Memory: 648.0K
+ CPU: 435ms
+ CGroup: /system.slice/bluetooth.service
+ └─930 /usr/lib/bluetooth/bluetoothd
+
+Jan 12 10:46:45 example.com bluetoothd[8900]: Not enough free handles to register service
+Jan 12 10:46:45 example.com bluetoothd[8900]: Current Time Service could not be registered
+Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output error (5)
+</programlisting>
+
+ <para>The dot ("â—") uses color on supported terminals to summarize the unit state at a glance. White
+ indicates an <literal>inactive</literal> or <literal>deactivating</literal> state. Red indicates a
+ <literal>failed</literal> or <literal>error</literal> state and green indicates an
+ <literal>active</literal>, <literal>reloading</literal> or <literal>activating</literal> state.
+ </para>
+
+ <para>The "Loaded:" line in the output will show <literal>loaded</literal> if the unit has been loaded into
+ memory. Other possible values for "Loaded:" include: <literal>error</literal> if there was a problem
+ loading it, <literal>not-found</literal>, and <literal>masked</literal>. Along with showing the path to
+ the unit file, this line will also show the enablement state. Enabled commands start at boot. See the
+ full table of possible enablement states — including the definition of <literal>masked</literal> — in the
+ documentation for the <command>is-enabled</command> command.
+ </para>
+
+ <para>The "Active:" line shows active state. The value is usually <literal>active</literal> or
+ <literal>inactive</literal>. Active could mean started, bound, plugged in, etc depending on the unit type.
+ The unit could also be in process of changing states, reporting a state of <literal>activating</literal> or
+ <literal>deactivating</literal>. A special <literal>failed</literal> state is entered when the service
+ failed in some way, such as a crash, exiting with an error code or timing out. If the failed state is
+ entered the cause will be logged for later reference.</para>
+ </example>
+
</listitem>
</varlistentry>
<varlistentry>
- <term><command>show</command> <optional><replaceable>PATTERN</replaceable>...|<replaceable>JOB</replaceable>...</optional></term>
+ <term><command>show</command> <optional><replaceable>PATTERN</replaceable>…|<replaceable>JOB</replaceable>…</optional></term>
<listitem>
- <para>Show properties of one or more units, jobs, or the
- manager itself. If no argument is specified, properties of
- the manager will be shown. If a unit name is specified,
- properties of the unit are shown, and if a job ID is
- specified, properties of the job are shown. By default, empty
- properties are suppressed. Use <option>--all</option> to
- show those too. To select specific properties to show, use
- <option>--property=</option>. This command is intended to be
- used whenever computer-parsable output is required. Use
- <command>status</command> if you are looking for formatted
- human-readable output.</para>
+ <para>Show properties of one or more units, jobs, or the manager itself. If no argument is specified,
+ properties of the manager will be shown. If a unit name is specified, properties of the unit are shown, and
+ if a job ID is specified, properties of the job are shown. By default, empty properties are suppressed. Use
+ <option>--all</option> to show those too. To select specific properties to show, use
+ <option>--property=</option>. This command is intended to be used whenever computer-parsable output is
+ required. Use <command>status</command> if you are looking for formatted human-readable output.</para>
+
+ <para>Many properties shown by <command>systemctl show</command> map directly to configuration settings of
+ the system and service manager and its unit files. Note that the properties shown by the command are
+ generally more low-level, normalized versions of the original configuration settings and expose runtime
+ state in addition to configuration. For example, properties shown for service units include the service's
+ current main process identifier as <literal>MainPID</literal> (which is runtime state), and time settings
+ are always exposed as properties ending in the <literal>…USec</literal> suffix even if a matching
+ configuration options end in <literal>…Sec</literal>, because microseconds is the normalized time unit used
+ by the system and service manager.</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><command>cat <replaceable>PATTERN</replaceable>...</command></term>
+ <term><command>cat <replaceable>PATTERN</replaceable>…</command></term>
<listitem>
<para>Show backing files of one or more units. Prints the
@@ -902,7 +983,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</listitem>
</varlistentry>
<varlistentry>
- <term><command>set-property <replaceable>NAME</replaceable> <replaceable>ASSIGNMENT</replaceable>...</command></term>
+ <term><command>set-property <replaceable>NAME</replaceable> <replaceable>ASSIGNMENT</replaceable>…</command></term>
<listitem>
<para>Set the specified unit properties at runtime where
@@ -933,7 +1014,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</varlistentry>
<varlistentry>
- <term><command>help <replaceable>PATTERN</replaceable>...|<replaceable>PID</replaceable>...</command></term>
+ <term><command>help <replaceable>PATTERN</replaceable>…|<replaceable>PID</replaceable>…</command></term>
<listitem>
<para>Show manual pages for one or more units, if
@@ -943,7 +1024,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</varlistentry>
<varlistentry>
- <term><command>reset-failed [<replaceable>PATTERN</replaceable>...]</command></term>
+ <term><command>reset-failed [<replaceable>PATTERN</replaceable>…]</command></term>
<listitem>
<para>Reset the <literal>failed</literal> state of the
@@ -991,7 +1072,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
<variablelist>
<varlistentry>
- <term><command>list-unit-files <optional><replaceable>PATTERN...</replaceable></optional></command></term>
+ <term><command>list-unit-files <optional><replaceable>PATTERN…</replaceable></optional></command></term>
<listitem>
<para>List unit files installed on the system, in combination with their enablement state (as reported by
@@ -1002,8 +1083,8 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</varlistentry>
<varlistentry>
- <term><command>enable <replaceable>NAME</replaceable>...</command></term>
- <term><command>enable <replaceable>PATH</replaceable>...</command></term>
+ <term><command>enable <replaceable>NAME</replaceable>…</command></term>
+ <term><command>enable <replaceable>PATH</replaceable>…</command></term>
<listitem>
<para>Enable one or more units or unit instances. This will create a set of symlinks, as encoded in the
@@ -1053,7 +1134,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</varlistentry>
<varlistentry>
- <term><command>disable <replaceable>NAME</replaceable>...</command></term>
+ <term><command>disable <replaceable>NAME</replaceable>…</command></term>
<listitem>
<para>Disables one or more units. This removes all symlinks to the unit files backing the specified units
@@ -1085,7 +1166,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</varlistentry>
<varlistentry>
- <term><command>reenable <replaceable>NAME</replaceable>...</command></term>
+ <term><command>reenable <replaceable>NAME</replaceable>…</command></term>
<listitem>
<para>Reenable one or more units, as specified on the command line. This is a combination of
@@ -1096,7 +1177,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</varlistentry>
<varlistentry>
- <term><command>preset <replaceable>NAME</replaceable>...</command></term>
+ <term><command>preset <replaceable>NAME</replaceable>…</command></term>
<listitem>
<para>Reset the enable/disable status one or more unit files, as specified on
@@ -1115,7 +1196,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
<para>For more information on the preset policy format, see
<citerefentry><refentrytitle>systemd.preset</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
For more information on the concept of presets, please consult the
- <ulink url="http://freedesktop.org/wiki/Software/systemd/Preset">Preset</ulink>
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/Preset">Preset</ulink>
document.</para>
</listitem>
</varlistentry>
@@ -1134,7 +1215,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</varlistentry>
<varlistentry>
- <term><command>is-enabled <replaceable>NAME</replaceable>...</command></term>
+ <term><command>is-enabled <replaceable>NAME</replaceable>…</command></term>
<listitem>
<para>Checks whether any of the specified unit files are
@@ -1221,7 +1302,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</varlistentry>
<varlistentry>
- <term><command>mask <replaceable>NAME</replaceable>...</command></term>
+ <term><command>mask <replaceable>NAME</replaceable>…</command></term>
<listitem>
<para>Mask one or more units, as specified on the command line. This will link these unit files to
@@ -1235,7 +1316,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</varlistentry>
<varlistentry>
- <term><command>unmask <replaceable>NAME</replaceable>...</command></term>
+ <term><command>unmask <replaceable>NAME</replaceable>…</command></term>
<listitem>
<para>Unmask one or more unit files, as specified on the command line. This will undo the effect of
@@ -1245,7 +1326,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</varlistentry>
<varlistentry>
- <term><command>link <replaceable>PATH</replaceable>...</command></term>
+ <term><command>link <replaceable>PATH</replaceable>…</command></term>
<listitem>
<para>Link a unit file that is not in the unit file search paths into the unit file search path. This
@@ -1256,7 +1337,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</varlistentry>
<varlistentry>
- <term><command>revert <replaceable>NAME</replaceable>...</command></term>
+ <term><command>revert <replaceable>NAME</replaceable>…</command></term>
<listitem>
<para>Revert one or more unit files to their vendor versions. This command removes drop-in configuration
@@ -1279,9 +1360,9 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
<varlistentry>
<term><command>add-wants <replaceable>TARGET</replaceable>
- <replaceable>NAME</replaceable>...</command></term>
+ <replaceable>NAME</replaceable>…</command></term>
<term><command>add-requires <replaceable>TARGET</replaceable>
- <replaceable>NAME</replaceable>...</command></term>
+ <replaceable>NAME</replaceable>…</command></term>
<listitem>
<para>Adds <literal>Wants=</literal> or <literal>Requires=</literal>
@@ -1297,7 +1378,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</varlistentry>
<varlistentry>
- <term><command>edit <replaceable>NAME</replaceable>...</command></term>
+ <term><command>edit <replaceable>NAME</replaceable>…</command></term>
<listitem>
<para>Edit a drop-in snippet or a whole replacement file if
@@ -1364,7 +1445,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
<variablelist>
<varlistentry>
- <term><command>list-machines <optional><replaceable>PATTERN</replaceable>...</optional></command></term>
+ <term><command>list-machines <optional><replaceable>PATTERN</replaceable>…</optional></command></term>
<listitem>
<para>List the host and all running local containers with
@@ -1382,16 +1463,20 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
<variablelist>
<varlistentry>
- <term><command>list-jobs <optional><replaceable>PATTERN...</replaceable></optional></command></term>
+ <term><command>list-jobs <optional><replaceable>PATTERN…</replaceable></optional></command></term>
<listitem>
<para>List jobs that are in progress. If one or more
<replaceable>PATTERN</replaceable>s are specified, only
jobs for units matching one of them are shown.</para>
+
+ <para>When combined with <option>--after</option> or <option>--before</option> the list is augmented with
+ information on which other job each job is waiting for, and which other jobs are waiting for it, see
+ above.</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><command>cancel <replaceable>JOB</replaceable>...</command></term>
+ <term><command>cancel <replaceable>JOB</replaceable>…</command></term>
<listitem>
<para>Cancel one or more jobs specified on the command line
@@ -1418,7 +1503,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</listitem>
</varlistentry>
<varlistentry>
- <term><command>set-environment <replaceable>VARIABLE=VALUE</replaceable>...</command></term>
+ <term><command>set-environment <replaceable>VARIABLE=VALUE</replaceable>…</command></term>
<listitem>
<para>Set one or more systemd manager environment variables,
@@ -1426,7 +1511,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
</listitem>
</varlistentry>
<varlistentry>
- <term><command>unset-environment <replaceable>VARIABLE</replaceable>...</command></term>
+ <term><command>unset-environment <replaceable>VARIABLE</replaceable>…</command></term>
<listitem>
<para>Unset one or more systemd manager environment
@@ -1439,7 +1524,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
<varlistentry>
<term>
<command>import-environment</command>
- <optional><replaceable>VARIABLE...</replaceable></optional>
+ <optional><replaceable>VARIABLE…</replaceable></optional>
</term>
<listitem>
@@ -1747,7 +1832,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
<title>Parameter Syntax</title>
<para>Unit commands listed above take either a single unit name (designated as <replaceable>NAME</replaceable>),
- or multiple unit specifications (designated as <replaceable>PATTERN</replaceable>...). In the first case, the
+ or multiple unit specifications (designated as <replaceable>PATTERN</replaceable>…). In the first case, the
unit name with or without a suffix must be given. If the suffix is not specified (unit name is "abbreviated"),
systemctl will append a suitable suffix, <literal>.service</literal> by default, and a type-specific suffix in
case of commands which operate only on specific unit types. For example,
diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml
index 8fa7cd3329..095d4e7e78 100644
--- a/man/systemd-analyze.xml
+++ b/man/systemd-analyze.xml
@@ -104,6 +104,12 @@
<cmdsynopsis>
<command>systemd-analyze</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
+ <arg choice="plain">syscall-filter</arg>
+ <arg choice="opt"><replaceable>SET</replaceable>…</arg>
+ </cmdsynopsis>
+ <cmdsynopsis>
+ <command>systemd-analyze</command>
+ <arg choice="opt" rep="repeat">OPTIONS</arg>
<arg choice="plain">verify</arg>
<arg choice="opt" rep="repeat"><replaceable>FILES</replaceable></arg>
</cmdsynopsis>
@@ -134,7 +140,7 @@
initialization of another service to complete.</para>
<para><command>systemd-analyze critical-chain
- [<replaceable>UNIT...</replaceable>]</command> prints a tree of
+ [<replaceable>UNIT…</replaceable>]</command> prints a tree of
the time-critical chain of units (for each of the specified
<replaceable>UNIT</replaceable>s or for the default target
otherwise). The time after the unit is active or started is
@@ -181,6 +187,11 @@
<option>--log-target=</option>, described in
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>).</para>
+ <para><command>systemd-analyze syscall-filter <optional><replaceable>SET</replaceable>…</optional></command>
+ will list system calls contained in the specified system call set <replaceable>SET</replaceable>,
+ or all known sets if no sets are specified. Argument <replaceable>SET</replaceable> must include
+ the <literal>@</literal> prefix.</para>
+
<para><command>systemd-analyze verify</command> will load unit files and print
warnings if any errors are detected. Files specified on the command line will be
loaded, but also any other units referenced by them. The full unit search path is
@@ -322,7 +333,7 @@ $ eog targets.svg</programlisting>
</para></listitem>
<listitem><para>missing dependencies which are required to start
- the given unit, </para></listitem>
+ the given unit,</para></listitem>
<listitem><para>man pages listed in
<varname>Documentation=</varname> which are not found in the
@@ -343,7 +354,7 @@ Documentation=man:nosuchfile(1)
Requires=different.service
[Service]
-Desription=x
+Description=x
$ systemd-analyze verify ./user.slice
[./user.slice:9] Unknown lvalue 'WhatIsThis' in section 'Unit'
diff --git a/man/systemd-ask-password-console.service.xml b/man/systemd-ask-password-console.service.xml
index 479e5f2e5b..3c1537d942 100644
--- a/man/systemd-ask-password-console.service.xml
+++ b/man/systemd-ask-password-console.service.xml
@@ -71,7 +71,7 @@
properly notified.</para>
<para>See the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">
+ url="https://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">
developer documentation</ulink> for more information about the
system password logic.</para>
diff --git a/man/systemd-ask-password.xml b/man/systemd-ask-password.xml
index 2b6fb5a82f..51d8ef5d82 100644
--- a/man/systemd-ask-password.xml
+++ b/man/systemd-ask-password.xml
@@ -61,10 +61,9 @@
a system password or passphrase from the user, using a question
message specified on the command line. When run from a TTY it will
query a password on the TTY and print it to standard output. When
- run with no TTY or with <option>--no-tty</option> it will query
- the password system-wide and allow active users to respond via
- several agents. The latter is only available to privileged
- processes.</para>
+ run with no TTY or with <option>--no-tty</option> it will use the
+ system-wide query mechanism, which allows active users to respond via
+ several agents, listed below.</para>
<para>The purpose of this tool is to query system-wide passwords
— that is passwords not attached to a specific user account.
@@ -76,28 +75,41 @@
<itemizedlist>
<listitem><para>A boot-time password agent asking the user for
- passwords using Plymouth</para></listitem>
+ passwords using
+ <citerefentry project='die-net'><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ </para></listitem>
<listitem><para>A boot-time password agent querying the user
- directly on the console</para></listitem>
+ directly on the console —
+ <citerefentry><refentrytitle>systemd-ask-password-console.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ </para></listitem>
<listitem><para>An agent requesting password input via a
- <citerefentry
- project='man-pages'><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
- message</para></listitem>
-
- <listitem><para>A command line agent which can be started
- temporarily to process queued password
- requests</para></listitem>
+ <citerefentry project='man-pages'><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ message —
+ <citerefentry><refentrytitle>systemd-ask-password-wall.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ </para></listitem>
<listitem><para>A TTY agent that is temporarily spawned during
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
- invocations</para></listitem>
+ invocations,</para></listitem>
+
+ <listitem><para>A command line agent which can be started
+ temporarily to process queued password
+ requests — <command>systemd-tty-ask-password-agent --query</command>.
+ </para></listitem>
</itemizedlist></para>
+ <para>Answering system-wide password queries is a privileged operation, hence
+ all the agents listed above (except for the last one), run as privileged
+ system services. The last one also needs elevated privileges, so
+ should be run through
+ <citerefentry project='die-net'><refentrytitle>sudo</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ or similar.</para>
+
<para>Additional password agents may be implemented according to
the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">systemd
+ url="https://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">systemd
Password Agent Specification</ulink>.</para>
<para>If a password is queried on a TTY, the user may press TAB to
@@ -217,7 +229,8 @@
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-ask-password-console.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-tty-ask-password</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry project='die-net'><refentrytitle>keyctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry project='die-net'><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
diff --git a/man/systemd-cgls.xml b/man/systemd-cgls.xml
index e8f0368f48..219514b183 100644
--- a/man/systemd-cgls.xml
+++ b/man/systemd-cgls.xml
@@ -54,6 +54,12 @@
<arg choice="opt" rep="repeat">OPTIONS</arg>
<arg choice="opt" rep="repeat">CGROUP</arg>
</cmdsynopsis>
+ <cmdsynopsis>
+ <command>systemd-cgls</command>
+ <arg choice="opt" rep="repeat">OPTIONS</arg>
+ <arg choice="plain"><option>--unit</option>|<option>--user-unit</option></arg>
+ <arg choice="opt" rep="repeat">UNIT</arg>
+ </cmdsynopsis>
</refsynopsisdiv>
<refsect1>
@@ -96,6 +102,21 @@
</varlistentry>
<varlistentry>
+ <term><option>-u</option></term>
+ <term><option>--unit</option></term>
+
+ <listitem><para>Show cgroup subtrees for the specified units.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--user-unit</option></term>
+
+ <listitem><para>Show cgroup subtrees for the specified user units.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>-k</option></term>
<listitem><para>Include kernel threads in output.
diff --git a/man/systemd-coredump.xml b/man/systemd-coredump.xml
index 4a1bc8b296..2c285bcb22 100644
--- a/man/systemd-coredump.xml
+++ b/man/systemd-coredump.xml
@@ -52,14 +52,26 @@
<refsynopsisdiv>
<para><filename>/usr/lib/systemd/systemd-coredump</filename></para>
+ <para><filename>/usr/lib/systemd/systemd-coredump</filename> <option>--backtrace</option></para>
<para><filename>systemd-coredump@.service</filename></para>
<para><filename>systemd-coredump.socket</filename></para>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
- <para><command>systemd-coredump</command> is a system service that can acquire core dumps
- from the kernel and handle them in various ways.</para>
+ <para><filename>systemd-coredump@.service</filename> is a system service that can acquire core
+ dumps from the kernel and handle them in various ways. The <command>systemd-coredump</command>
+ executable does the actual work. It is invoked twice: once as the handler by the kernel, and the
+ second time in the <filename>systemd-coredump@.service</filename> to actually write the data to
+ the journal.</para>
+
+ <para>When the kernel invokes <command>systemd-coredump</command> to handle a core dump, it runs
+ in privileged mode, and will connect to the socket created by the
+ <filename>systemd-coredump.socket</filename> unit, which in turn will spawn an unprivileged
+ <filename>systemd-coredump@.service</filename> instance to process the core dump. Hence
+ <filename>systemd-coredump.socket</filename> and <filename>systemd-coredump@.service</filename>
+ are helper units which do the actual processing of core dumps and are subject to normal service
+ management.</para>
<para>Core dumps can be written to the journal or saved as a file. Once saved they can be retrieved
for further processing, for example in
@@ -70,18 +82,20 @@
if possible to the journal and store the core dump itself in an external file in
<filename>/var/lib/systemd/coredump</filename>.</para>
- <para>When the kernel invokes <command>systemd-coredump</command> to handle a core dump,
- it will connect to the socket created by the <filename>systemd-coredump.socket</filename>
- unit, which in turn will spawn a <filename>systemd-coredump@.service</filename> instance
- to process the core dump. Hence <filename>systemd-coredump.socket</filename>
- and <filename>systemd-coredump@.service</filename> are helper units which do the actual
- processing of core dumps and are subject to normal service management.</para>
-
<para>The behavior of a specific program upon reception of a signal is governed by a few
factors which are described in detail in
<citerefentry project='man-pages'><refentrytitle>core</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
In particular, the core dump will only be processed when the related resource limits are sufficient.
</para>
+
+ <para>It is also possible to invoke <command>systemd-coredump</command> with
+ <option>--backtrace</option> option. In this case, <command>systemd-coredump</command> expects
+ a journal entry in the journal
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/export">Journal Export Format</ulink>
+ on standard input. The entry should contain a <varname>MESSAGE=</varname> field and any additional
+ metadata fields the caller deems reasonable. <command>systemd-coredump</command> will append
+ additional metadata fields in the same way it does for core dumps received from the kernel. In
+ this mode, no core dump is stored in the journal.</para>
</refsect1>
<refsect1>
@@ -91,7 +105,8 @@
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
</para>
- <para>In order to be used <command>systemd-coredump</command> must be configured in
+ <para>In order to be used by the kernel to handle core dumps,
+ <command>systemd-coredump</command> must be configured in
<citerefentry project='man-pages'><refentrytitle>sysctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>
parameter <varname>kernel.core_pattern</varname>. The syntax of this parameter is explained in
<citerefentry project='man-pages'><refentrytitle>core</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
@@ -99,14 +114,20 @@
<varname>kernel.core_pattern</varname> accordingly. This file may be masked or overridden to use a different
setting following normal
<citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- rules.
- If the sysctl configuration is modified, it must be updated in the kernel before
- it takes effect, see
+ rules. If the sysctl configuration is modified, it must be updated in the kernel before it
+ takes effect, see
<citerefentry project='man-pages'><refentrytitle>sysctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>systemd-sysctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
</para>
+ <para>In order to by used in the <option>--backtrace</option> mode, an appropriate backtrace
+ handler must be installed on the sender side. For example, in case of
+ <citerefentry><refentrytitle>python</refentrytitle><manvolnum>1</manvolnum></citerefentry>, this
+ means a <varname>sys.excepthook</varname> must installed, see
+ <ulink url="https://github.com/keszybz/systemd-coredump-python">systemd-coredump-python</ulink>.
+ </para>
+
<para>The behavior of <command>systemd-coredump</command> itself is configured through the configuration file
<filename>/etc/systemd/coredump.conf</filename> and corresponding snippets
<filename>/etc/systemd/coredump.conf.d/*.conf</filename>, see
diff --git a/man/systemd-cryptsetup@.service.xml b/man/systemd-cryptsetup@.service.xml
index ea524851eb..73bd5b78ab 100644
--- a/man/systemd-cryptsetup@.service.xml
+++ b/man/systemd-cryptsetup@.service.xml
@@ -61,14 +61,13 @@
<para><filename>systemd-cryptsetup@.service</filename> will ask
for hard disk passwords via the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">
+ url="https://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">
password agent logic</ulink>, in order to query the user for the
password using the right mechanism at boot and during
runtime.</para>
- <para>At early boot and when the system manager configuration is
- reloaded this <filename>/etc/crypttab</filename> is translated
- into <filename>systemd-cryptsetup@.service</filename> units by
+ <para>At early boot and when the system manager configuration is reloaded, <filename>/etc/crypttab</filename> is
+ translated into <filename>systemd-cryptsetup@.service</filename> units by
<citerefentry><refentrytitle>systemd-cryptsetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
</refsect1>
diff --git a/man/systemd-debug-generator.xml b/man/systemd-debug-generator.xml
index 5c5e9fc4a1..0a66b9bbf9 100644
--- a/man/systemd-debug-generator.xml
+++ b/man/systemd-debug-generator.xml
@@ -70,7 +70,7 @@
the initial transaction. This is useful to start one or more
additional units at boot. May be specified more than once.</para>
- <para>If the <option>systemd.debug-shell</option> option is
+ <para>If the <option>systemd.debug_shell</option> option is
specified, the debug shell service
<literal>debug-shell.service</literal> is pulled into the boot
transaction. It will spawn a debug shell on tty9 during early
diff --git a/man/systemd-delta.xml b/man/systemd-delta.xml
index 99709604aa..6628213209 100644
--- a/man/systemd-delta.xml
+++ b/man/systemd-delta.xml
@@ -63,7 +63,7 @@
compare configuration files that override other configuration
files. Files in <filename>/etc</filename> have highest priority,
files in <filename>/run</filename> have the second highest
- priority, ..., files in <filename>/lib</filename> have lowest
+ priority, …, files in <filename>/lib</filename> have lowest
priority. Files in a directory with higher priority override files
with the same name in directories of lower priority. In addition,
certain configuration files can have <literal>.d</literal>
@@ -82,7 +82,7 @@
suffix. Either is optional. The prefix must be one of the
directories containing configuration files
(<filename>/etc</filename>, <filename>/run</filename>,
- <filename>/usr/lib</filename>, ...). If it is given, only
+ <filename>/usr/lib</filename>, …). If it is given, only
overriding files contained in this directory will be shown.
Otherwise, all overriding files will be shown. The suffix must be
a name of a subdirectory containing configuration files like
diff --git a/man/systemd-detect-virt.xml b/man/systemd-detect-virt.xml
index 996c2fa256..72ea35892f 100644
--- a/man/systemd-detect-virt.xml
+++ b/man/systemd-detect-virt.xml
@@ -91,12 +91,13 @@
<row>
<entry valign="top" morerows="10">VM</entry>
<entry><varname>qemu</varname></entry>
- <entry>QEMU software virtualization</entry>
+ <entry>QEMU software virtualization, without KVM</entry>
</row>
<row>
<entry><varname>kvm</varname></entry>
- <entry>Linux KVM kernel virtual machine</entry>
+ <entry>Linux KVM kernel virtual machine, with whatever software, except
+ Oracle Virtualbox</entry>
</row>
<row>
@@ -116,7 +117,8 @@
<row>
<entry><varname>oracle</varname></entry>
- <entry>Oracle VM VirtualBox (historically marketed by innotek and Sun Microsystems)</entry>
+ <entry>Oracle VM VirtualBox (historically marketed by innotek and Sun Microsystems),
+ for legacy and KVM hypervisor</entry>
</row>
<row>
diff --git a/man/systemd-environment-d-generator.xml b/man/systemd-environment-d-generator.xml
new file mode 100644
index 0000000000..cc00a5256d
--- /dev/null
+++ b/man/systemd-environment-d-generator.xml
@@ -0,0 +1,80 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+<!ENTITY % entities SYSTEM "custom-entities.ent" >
+%entities;
+]>
+
+<!--
+ This file is part of systemd.
+
+ Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-environment-d-generator">
+
+ <refentryinfo>
+ <title>systemd-environment-d-generator</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <contrib>Developer</contrib>
+ <firstname>Zbigniew</firstname>
+ <surname>Jędrzejewski-Szmek</surname>
+ <email>zbyszek@in.waw.pl</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>systemd-environment-d-generator</refentrytitle>
+ <manvolnum>8</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>systemd-environment-d-generator</refname>
+ <refname>30-systemd-environment-d-generator</refname>
+ <refpurpose>Load variables specified by <filename>environment.d</filename>
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <para><filename>&userenvgeneratordir;/30-systemd-environment-d-generator</filename></para>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><filename>systemd-environment-d-generator</filename> is a
+ <citerefentry><refentrytitle>systemd.environment-generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+ that reads environment configuration specified by
+ <citerefentry><refentrytitle>environment.d</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+ configuration files and passes it to the
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ user manager instance.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+ <para>
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd.environment-generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/systemd-escape.xml b/man/systemd-escape.xml
index 5e95e22536..bb4c7e48e5 100644
--- a/man/systemd-escape.xml
+++ b/man/systemd-escape.xml
@@ -86,8 +86,8 @@
<listitem><para>Appends the specified unit type suffix to the
escaped string. Takes one of the unit types supported by
- systemd, such as <literal>.service</literal> or
- <literal>.mount</literal>. May not be used in conjunction with
+ systemd, such as <literal>service</literal> or
+ <literal>mount</literal>. May not be used in conjunction with
<option>--template=</option>, <option>--unescape</option> or
<option>--mangle</option>.</para></listitem>
</varlistentry>
diff --git a/man/systemd-firstboot.xml b/man/systemd-firstboot.xml
index b269e48113..539422ab98 100644
--- a/man/systemd-firstboot.xml
+++ b/man/systemd-firstboot.xml
@@ -63,8 +63,14 @@
<para><command>systemd-firstboot</command> initializes the most
basic system settings interactively on the first boot, or
- optionally non-interactively when a system image is created. The
- following settings may be set up:</para>
+ optionally non-interactively when a system image is created.
+ The service is started if <varname>ConditionFirstBoot=yes</varname>
+ is satisfied. This essentially means that <filename>/etc</filename>
+ is empty, see
+ <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for details.</para>
+
+ <para>The following settings may be set up:</para>
<itemizedlist>
<listitem><para>The system locale, more specifically the two
@@ -241,6 +247,20 @@
</refsect1>
<refsect1>
+ <title>Kernel Command Line</title>
+
+ <variablelist class='kernel-commandline-options'>
+ <varlistentry>
+ <term><varname>systemd.firstboot=</varname></term>
+
+ <listitem><para>Takes a boolean argument, defaults to on. If off, <filename>systemd-firstboot.service</filename>
+ won't interactively query the user for basic settings at first boot, even if those settings are not
+ initialized yet.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
diff --git a/man/systemd-fsck@.service.xml b/man/systemd-fsck@.service.xml
index 933c3247ad..711e269016 100644
--- a/man/systemd-fsck@.service.xml
+++ b/man/systemd-fsck@.service.xml
@@ -88,8 +88,8 @@
<refsect1>
<title>Kernel Command Line</title>
- <para><filename>systemd-fsck</filename> understands one kernel
- command line parameter:</para>
+ <para><filename>systemd-fsck</filename> understands these kernel
+ command line parameters:</para>
<variablelist class='kernel-commandline-options'>
<varlistentry>
@@ -110,9 +110,9 @@
<listitem><para>One of <literal>preen</literal>,
<literal>yes</literal>, <literal>no</literal>. Controls the
- mode of operation. The default is <literal> preen</literal>,
+ mode of operation. The default is <literal>preen</literal>,
and will automatically repair problems that can be safely
- fixed. <literal>yes </literal> will answer yes to all
+ fixed. <literal>yes</literal> will answer yes to all
questions by fsck and <literal>no</literal> will answer no to
all questions. </para></listitem>
</varlistentry>
diff --git a/man/systemd-fstab-generator.xml b/man/systemd-fstab-generator.xml
index a971cb3675..50d24d67f0 100644
--- a/man/systemd-fstab-generator.xml
+++ b/man/systemd-fstab-generator.xml
@@ -89,12 +89,13 @@
<listitem><para>Takes a boolean argument. Defaults to
<literal>yes</literal>. If <literal>no</literal>, causes the
- generator to ignore any mounts or swaps configured in
+ generator to ignore any mounts or swap devices configured in
<filename>/etc/fstab</filename>. <varname>rd.fstab=</varname>
- is honored only by initial RAM disk (initrd) while
+ is honored only by the initial RAM disk (initrd) while
<varname>fstab=</varname> is honored by both the main system
and the initrd.</para></listitem>
</varlistentry>
+
<varlistentry>
<term><varname>root=</varname></term>
@@ -102,6 +103,7 @@
initrd. <varname>root=</varname> is honored by the
initrd.</para></listitem>
</varlistentry>
+
<varlistentry>
<term><varname>rootfstype=</varname></term>
@@ -109,6 +111,7 @@
passed to the mount command. <varname>rootfstype=</varname> is
honored by the initrd.</para></listitem>
</varlistentry>
+
<varlistentry>
<term><varname>rootflags=</varname></term>
@@ -116,6 +119,7 @@
use. <varname>rootflags=</varname> is honored by the
initrd.</para></listitem>
</varlistentry>
+
<varlistentry>
<term><varname>mount.usr=</varname></term>
@@ -133,6 +137,7 @@
<para><varname>mount.usr=</varname> is honored by the initrd.
</para></listitem>
</varlistentry>
+
<varlistentry>
<term><varname>mount.usrfstype=</varname></term>
@@ -150,6 +155,7 @@
<para><varname>mount.usrfstype=</varname> is honored by the
initrd.</para></listitem>
</varlistentry>
+
<varlistentry>
<term><varname>mount.usrflags=</varname></term>
@@ -166,6 +172,39 @@
<para><varname>mount.usrflags=</varname> is honored by the
initrd.</para></listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><varname>systemd.volatile=</varname></term>
+
+ <listitem><para>Controls whether the system shall boot up in volatile mode. Takes a boolean argument or the
+ special value <option>state</option>.</para>
+
+ <para>If false (the default), this generator makes no changes to the mount tree and the system is booted up in
+ normal mode.</para>
+
+ <para>If true the generator ensures
+ <citerefentry><refentrytitle>systemd-volatile-root.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ is run as part of the initial RAM disk ("initrd"). This service changes the mount table before transitioning to
+ the host system, so that a volatile memory file system (<literal>tmpfs</literal>) is used as root directory,
+ with only <filename>/usr</filename> mounted into it from the configured root file system, in read-only
+ mode. This way the system operates in fully stateless mode, with all configuration and state reset at boot and
+ lost at shutdown, as <filename>/etc</filename> and <filename>/var</filename> will be served from the (initially
+ unpopulated) volatile memory file system.</para>
+
+ <para>If set to <option>state</option> the generator will leave the root
+ directory mount point unaltered, however will mount a <literal>tmpfs</literal> file system to
+ <filename>/var</filename>. In this mode the normal system configuration (i.e. the contents of
+ <literal>/etc</literal>) is in effect (and may be modified during system runtime), however the system state
+ (i.e. the contents of <literal>/var</literal>) is reset at boot and lost at shutdown.</para>
+
+ <para>Note that in none of these modes the root directory, <filename>/etc</filename>, <filename>/var</filename>
+ or any other resources stored in the root file system are physically removed. It's thus safe to boot a system
+ that is normally operated in non-volatile mode temporarily into volatile mode, without losing data.</para>
+
+ <para>Note that enabling this setting will only work correctly on operating systems that can boot up with only
+ <filename>/usr</filename> mounted, and are able to automatically populate <filename>/etc</filename>, and also
+ <filename>/var</filename> in case of <literal>systemd.volatile=yes</literal>.</para></listitem>
+ </varlistentry>
</variablelist>
</refsect1>
@@ -176,7 +215,8 @@
<citerefentry project='man-pages'><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.swap</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd-cryptsetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>systemd-cryptsetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>kernel-command-line</refentrytitle><manvolnum>7</manvolnum></citerefentry>
</para>
</refsect1>
diff --git a/man/systemd-getty-generator.xml b/man/systemd-getty-generator.xml
index 338925964d..8bff3bb7f4 100644
--- a/man/systemd-getty-generator.xml
+++ b/man/systemd-getty-generator.xml
@@ -64,7 +64,7 @@
<filename>container-getty@.service</filename> instances for
additional container pseudo TTYs as requested by the container
manager (see <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface/"><filename>Container
+ url="https://www.freedesktop.org/wiki/Software/systemd/ContainerInterface/"><filename>Container
Interface</filename></ulink>). This should ensure that the user is
shown a login prompt at the right place, regardless of which
environment the system is started in. For example, it is
diff --git a/man/systemd-gpt-auto-generator.xml b/man/systemd-gpt-auto-generator.xml
index d26206710f..eb7a2c4c28 100644
--- a/man/systemd-gpt-auto-generator.xml
+++ b/man/systemd-gpt-auto-generator.xml
@@ -62,7 +62,7 @@
partitions and creates mount and swap units for them, based on the
partition type GUIDs of GUID partition tables (GPT). It implements
the <ulink
- url="http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/">Discoverable
+ url="https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/">Discoverable
Partitions Specification</ulink>. Note that this generator has no
effect on non-GPT systems, or where the directories under the
mount points are already non-empty. Also, on systems where the
@@ -123,6 +123,11 @@
<entry>On 64-bit ARM systems, the first ARM root partition on the disk the EFI ESP is located on is mounted to the root directory <filename>/</filename>.</entry>
</row>
<row>
+ <entry>993d8d3d-f80e-4225-855a-9daf8ed7ea97</entry>
+ <entry><filename>Root Partition (Itanium/IA-64)</filename></entry>
+ <entry>On Itanium systems, the first Itanium root partition on the disk the EFI ESP is located on is mounted to the root directory <filename>/</filename>.</entry>
+ </row>
+ <row>
<entry>933ac7e1-2eb4-4f13-b844-0e14e2aef915</entry>
<entry>Home Partition</entry>
<entry>The first home partition on the disk the root partition is located on is mounted to <filename>/home</filename>.</entry>
diff --git a/man/systemd-hostnamed.service.xml b/man/systemd-hostnamed.service.xml
index 6990d41b02..17755aa69e 100644
--- a/man/systemd-hostnamed.service.xml
+++ b/man/systemd-hostnamed.service.xml
@@ -66,7 +66,7 @@
is a command line client to this service.</para>
<para>See the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/hostnamed">
+ url="https://www.freedesktop.org/wiki/Software/systemd/hostnamed">
developer documentation</ulink> for information about the APIs
<filename>systemd-hostnamed</filename> provides.</para>
</refsect1>
diff --git a/man/systemd-importd.service.xml b/man/systemd-importd.service.xml
index 8fdced475c..70a618ce46 100644
--- a/man/systemd-importd.service.xml
+++ b/man/systemd-importd.service.xml
@@ -64,7 +64,7 @@
<command>import-tar</command>, <command>export-raw</command>, and <command>export-tar</command> commands.</para>
<para>See the
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/importd">
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/importd">
importd D-Bus API Documentation</ulink> for information about the
APIs <filename>systemd-importd</filename> provides.</para>
</refsect1>
diff --git a/man/systemd-inhibit.xml b/man/systemd-inhibit.xml
index ce169960d8..09b82b82c1 100644
--- a/man/systemd-inhibit.xml
+++ b/man/systemd-inhibit.xml
@@ -72,7 +72,7 @@
should not be interrupted.</para>
<para>For more information see the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/inhibit">Inhibitor
+ url="https://www.freedesktop.org/wiki/Software/systemd/inhibit">Inhibitor
Lock Developer Documentation</ulink>.</para>
</refsect1>
diff --git a/man/systemd-journal-gatewayd.service.xml b/man/systemd-journal-gatewayd.service.xml
index 2cb114f6e3..3ee344e50b 100644
--- a/man/systemd-journal-gatewayd.service.xml
+++ b/man/systemd-journal-gatewayd.service.xml
@@ -128,7 +128,7 @@
</varlistentry>
<varlistentry>
- <term><uri>/entries[?option1&amp;option2=value...]</uri></term>
+ <term><uri>/entries[?option1&amp;option2=value…]</uri></term>
<listitem><para>Retrieval of events in various formats.</para>
@@ -157,7 +157,7 @@
"hostname" : "fedora",
"os_pretty_name" : "Fedora 19 (Rawhide)",
"virtualization" : "kvm",
- ...}</programlisting>
+ …}</programlisting>
</para>
</listitem>
</varlistentry>
@@ -197,7 +197,7 @@
one per line
(like <command>journalctl --output json</command>).
See <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/json">Journal
+ url="https://www.freedesktop.org/wiki/Software/systemd/json">Journal
JSON Format</ulink> for more information.</para>
</listitem>
</varlistentry>
@@ -222,7 +222,7 @@
transfer
(like <command>journalctl --output export</command>).
See <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/export">Journal
+ url="https://www.freedesktop.org/wiki/Software/systemd/export">Journal
Export Format</ulink> for more information.</para>
</listitem>
</varlistentry>
@@ -289,7 +289,7 @@
<title>Examples</title>
<para>Retrieve events from this boot from local journal
in <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/export">Journal
+ url="https://www.freedesktop.org/wiki/Software/systemd/export">Journal
Export Format</ulink>:
<programlisting>curl --silent -H'Accept: application/vnd.fdo.journal' \
'http://localhost:19531/entries?boot'</programlisting>
diff --git a/man/systemd-journal-remote.xml b/man/systemd-journal-remote.xml
index ee2d5c2486..d7750e416e 100644
--- a/man/systemd-journal-remote.xml
+++ b/man/systemd-journal-remote.xml
@@ -64,7 +64,7 @@
<filename>systemd-journal-remote</filename> is a command to
receive serialized journal events and store them to the journal.
Input streams are in the
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/export">
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/export">
Journal Export Format
</ulink>,
i.e. like the output from
diff --git a/man/systemd-localed.service.xml b/man/systemd-localed.service.xml
index 06aa78c0e4..2a796c9045 100644
--- a/man/systemd-localed.service.xml
+++ b/man/systemd-localed.service.xml
@@ -68,7 +68,7 @@
is a command line client to this service.</para>
<para>See the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/localed">
+ url="https://www.freedesktop.org/wiki/Software/systemd/localed">
developer documentation</ulink> for information about the APIs
<filename>systemd-localed</filename> provides.</para>
</refsect1>
diff --git a/man/systemd-logind.service.xml b/man/systemd-logind.service.xml
index f0bdb1c756..5433269638 100644
--- a/man/systemd-logind.service.xml
+++ b/man/systemd-logind.service.xml
@@ -60,8 +60,14 @@
manages user logins. It is responsible for:</para>
<itemizedlist>
- <listitem><para>Keeping track of users and sessions, their
- processes and their idle state</para></listitem>
+ <listitem><para>Keeping track of users and sessions, their processes and their idle state. This is implemented by
+ allocating a systemd slice unit for each user below <filename>user.slice</filename>, and a scope unit below it
+ for each concurrent session of a user. Also, a per-user service manager is started as system service instance of
+ <filename>user@.service</filename> for each user logged in.</para></listitem>
+
+ <listitem><para>Generating and managing session IDs. If auditing is available and an audit session ID is set for
+ a session already, the session ID is initialized from it. Otherwise, an independent session counter is
+ used.</para></listitem>
<listitem><para>Providing PolicyKit-based access for users to
operations such as system shutdown or sleep</para></listitem>
@@ -93,17 +99,17 @@
for information about the configuration of this service.</para>
<para>See <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/multiseat">Multi-Seat
+ url="https://www.freedesktop.org/wiki/Software/systemd/multiseat">Multi-Seat
on Linux</ulink> for an introduction into basic concepts of logind
such as users, sessions and seats.</para>
<para>See the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/logind">
+ url="https://www.freedesktop.org/wiki/Software/systemd/logind">
logind D-Bus API Documentation</ulink> for information about the
APIs <filename>systemd-logind</filename> provides.</para>
<para>For more information on the inhibition logic see the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/inhibit">Inhibitor
+ url="https://www.freedesktop.org/wiki/Software/systemd/inhibit">Inhibitor
Lock Developer Documentation</ulink>.</para>
</refsect1>
diff --git a/man/systemd-machine-id-setup.xml b/man/systemd-machine-id-setup.xml
index 944e899bd4..714317c945 100644
--- a/man/systemd-machine-id-setup.xml
+++ b/man/systemd-machine-id-setup.xml
@@ -92,7 +92,7 @@
environment and a UUID is configured for the container, this is
used to initialize the machine ID. For details, see the
documentation of the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface">Container
+ url="https://www.freedesktop.org/wiki/Software/systemd/ContainerInterface">Container
Interface</ulink>.</para></listitem>
<listitem><para>Otherwise, a new ID is randomly
diff --git a/man/systemd-machined.service.xml b/man/systemd-machined.service.xml
index 999aeee1c6..c4f173f79b 100644
--- a/man/systemd-machined.service.xml
+++ b/man/systemd-machined.service.xml
@@ -71,7 +71,7 @@
names.</para>
<para>See the
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/machined">
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/machined">
machined D-Bus API Documentation</ulink> for information about the
APIs <filename>systemd-machined</filename> provides.</para>
</refsect1>
diff --git a/man/systemd-modules-load.service.xml b/man/systemd-modules-load.service.xml
index b25929b2e4..ee097d7f5c 100644
--- a/man/systemd-modules-load.service.xml
+++ b/man/systemd-modules-load.service.xml
@@ -73,8 +73,8 @@
<variablelist class='kernel-commandline-options'>
<varlistentry>
- <term><varname>modules-load=</varname></term>
- <term><varname>rd.modules-load=</varname></term>
+ <term><varname>modules_load=</varname></term>
+ <term><varname>rd.modules_load=</varname></term>
<listitem><para>Takes a comma-separated list of kernel modules
to statically load during early boot. The option prefixed with
diff --git a/man/systemd-mount.xml b/man/systemd-mount.xml
index 06b7c85bd8..8bba286787 100644
--- a/man/systemd-mount.xml
+++ b/man/systemd-mount.xml
@@ -45,7 +45,8 @@
<refnamediv>
<refname>systemd-mount</refname>
- <refpurpose>Establish a mount or auto-mount point transiently</refpurpose>
+ <refname>systemd-umount</refname>
+ <refpurpose>Establish and destroy transient mount or auto-mount points</refpurpose>
</refnamediv>
<refsynopsisdiv>
@@ -60,6 +61,11 @@
<arg choice="opt" rep="repeat"><replaceable>OPTIONS</replaceable></arg>
<arg choice="plain"><option>--list</option></arg>
</cmdsynopsis>
+ <cmdsynopsis>
+ <command>systemd-umount</command>
+ <arg choice="opt" rep="repeat"><replaceable>OPTIONS</replaceable></arg>
+ <arg choice="plain" rep="repeat"><replaceable>WHERE</replaceable></arg>
+ </cmdsynopsis>
</refsynopsisdiv>
<refsect1>
@@ -91,6 +97,9 @@
<para>Use the <option>--list</option> command to show a terse table of all local, known block devices with file
systems that may be mounted with this command.</para>
+
+ <para><command>systemd-umount</command> can be used to unmount a mount or automount point. It is the same
+ as <command>systemd-mount</command> <option>--unmount</option>.</para>
</refsect1>
<refsect1>
@@ -239,6 +248,15 @@
such as labels, etc.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>-u</option></term>
+ <term><option>--umount</option></term>
+
+ <listitem><para>Stop the mount and automount units corresponding to the specified mount points
+ <replaceable>WHERE</replaceable>.</para>
+ </listitem>
+ </varlistentry>
+
<xi:include href="user-system-options.xml" xpointer="user" />
<xi:include href="user-system-options.xml" xpointer="system" />
<xi:include href="user-system-options.xml" xpointer="host" />
diff --git a/man/systemd-notify.xml b/man/systemd-notify.xml
index a5f4077166..8c56a6b8ed 100644
--- a/man/systemd-notify.xml
+++ b/man/systemd-notify.xml
@@ -72,10 +72,24 @@
<para>The command line may carry a list of environment variables
to send as part of the status update.</para>
- <para>Note that systemd will refuse reception of status updates
- from this command unless <varname>NotifyAccess=all</varname> is
- set for the service unit this command is called from.</para>
-
+ <para>Note that systemd will refuse reception of status updates from this command unless
+ <varname>NotifyAccess=</varname> is set for the service unit this command is called from.</para>
+
+ <para>Note that <function>sd_notify()</function> notifications may be attributed to units correctly only if either
+ the sending process is still around at the time PID 1 processes the message, or if the sending process is
+ explicitly runtime-tracked by the service manager. The latter is the case if the service manager originally forked
+ off the process, i.e. on all processes that match <varname>NotifyAccess=</varname><option>main</option> or
+ <varname>NotifyAccess=</varname><option>exec</option>. Conversely, if an auxiliary process of the unit sends an
+ <function>sd_notify()</function> message and immediately exits, the service manager might not be able to properly
+ attribute the message to the unit, and thus will ignore it, even if
+ <varname>NotifyAccess=</varname><option>all</option> is set for it.</para>
+
+ <para><command>systemd-notify</command> will first attempt to invoke <function>sd_notify()</function> pretending to
+ have the PID of the invoking process. This will only succeed when invoked with sufficient privileges. On failure,
+ it will then fall back to invoking it under its own PID. This behaviour is useful in order that when the tool is
+ invoked from a shell script the shell process — and not the <command>systemd-notify</command> process — appears as
+ sender of the message, which in turn is helpful if the shell process is the main process of a service, due to the
+ limitations of <varname>NotifyAccess=</varname><option>all</option> described above.</para>
</refsect1>
<refsect1>
@@ -112,7 +126,7 @@
<listitem><para>Send a free-form status string for the daemon
to the init systemd. This option takes the status string as
argument. This is equivalent to <command>systemd-notify
- STATUS=...</command>. For details about the semantics of this
+ STATUS=…</command>. For details about the semantics of this
option see
<citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
</varlistentry>
@@ -158,15 +172,15 @@
<programlisting>#!/bin/bash
mkfifo /tmp/waldo
-systemd-notify --ready --status="Waiting for data..."
+systemd-notify --ready --status="Waiting for data…"
while : ; do
read a &lt; /tmp/waldo
systemd-notify --status="Processing $a"
- # Do something with $a ...
+ # Do something with $a …
- systemd-notify --status="Waiting for data..."
+ systemd-notify --status="Waiting for data…"
done</programlisting>
</example>
</refsect1>
diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index c449edee89..ef80d90ba4 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -135,7 +135,7 @@
container.</para>
<para><command>systemd-nspawn</command> implements the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface">Container Interface</ulink>
+ url="https://www.freedesktop.org/wiki/Software/systemd/ContainerInterface">Container Interface</ulink>
specification.</para>
<para>While running, containers invoked with <command>systemd-nspawn</command> are registered with the
@@ -181,25 +181,15 @@
<varlistentry>
<term><option>--template=</option></term>
- <listitem><para>Directory or <literal>btrfs</literal>
- subvolume to use as template for the container's root
- directory. If this is specified and the container's root
- directory (as configured by <option>--directory=</option>)
- does not yet exist it is created as <literal>btrfs</literal>
- subvolume and populated from this template tree. Ideally, the
- specified template path refers to the root of a
- <literal>btrfs</literal> subvolume, in which case a simple
- copy-on-write snapshot is taken, and populating the root
- directory is instant. If the specified template path does not
- refer to the root of a <literal>btrfs</literal> subvolume (or
- not even to a <literal>btrfs</literal> file system at all),
- the tree is copied, which can be substantially more
- time-consuming. Note that if this option is used the
- container's root directory (in contrast to the template
- directory!) must be located on a <literal>btrfs</literal> file
- system, so that the <literal>btrfs</literal> subvolume may be
- created. May not be specified together with
- <option>--image=</option> or
+ <listitem><para>Directory or <literal>btrfs</literal> subvolume to use as template for the container's root
+ directory. If this is specified and the container's root directory (as configured by
+ <option>--directory=</option>) does not yet exist it is created as <literal>btrfs</literal> snapshot (if
+ supported) or plain directory (otherwise) and populated from this template tree. Ideally, the specified
+ template path refers to the root of a <literal>btrfs</literal> subvolume, in which case a simple copy-on-write
+ snapshot is taken, and populating the root directory is instant. If the specified template path does not refer
+ to the root of a <literal>btrfs</literal> subvolume (or not even to a <literal>btrfs</literal> file system at
+ all), the tree is copied (though possibly in a copy-on-write scheme — if the file system supports that), which
+ can be substantially more time-consuming. May not be specified together with <option>--image=</option> or
<option>--ephemeral</option>.</para>
<para>Note that this switch leaves host name, machine ID and
@@ -211,13 +201,8 @@
<term><option>-x</option></term>
<term><option>--ephemeral</option></term>
- <listitem><para>If specified, the container is run with a
- temporary <literal>btrfs</literal> snapshot of its root
- directory (as configured with <option>--directory=</option>),
- that is removed immediately when the container terminates.
- This option is only supported if the root file system is
- <literal>btrfs</literal>. May not be specified together with
- <option>--image=</option> or
+ <listitem><para>If specified, the container is run with a temporary snapshot of its file system that is removed
+ immediately when the container terminates. May not be specified together with
<option>--template=</option>.</para>
<para>Note that this switch leaves host name, machine ID and
all other settings that could identify the instance
@@ -248,15 +233,37 @@
a server data partition which are mounted to the appropriate
places in the container. All these partitions must be
identified by the partition types defined by the <ulink
- url="http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/">Discoverable
+ url="https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/">Discoverable
Partitions Specification</ulink>.</para></listitem>
+
+ <listitem><para>No partition table, and a single file system spanning the whole image.</para></listitem>
</itemizedlist>
- <para>Any other partitions, such as foreign partitions, swap
- partitions or EFI system partitions are not mounted. May not
- be specified together with <option>--directory=</option>,
- <option>--template=</option> or
- <option>--ephemeral</option>.</para></listitem>
+ <para>On GPT images, if an EFI System Partition (ESP) is discovered, it is automatically mounted to
+ <filename>/efi</filename> (or <filename>/boot</filename> as fallback) in case a directory by this name exists
+ and is empty.</para>
+
+ <para>Partitions encrypted with LUKS are automatically decrypted. Also, on GPT images dm-verity data integrity
+ hash partitions are set up if the root hash for them is specified using the <option>--root-hash=</option>
+ option.</para>
+
+ <para>Any other partitions, such as foreign partitions or swap partitions are not mounted. May not be specified
+ together with <option>--directory=</option>, <option>--template=</option>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--root-hash=</option></term>
+
+ <listitem><para>Takes a data integrity (dm-verity) root hash specified in hexadecimal. This option enables data
+ integrity checks using dm-verity, if the used image contains the appropriate integrity data (see above). The
+ specified hash must match the root hash of integrity data, and is usually at least 256 bits (and hence 64
+ formatted hexadecimal characters) long (in case of SHA256 for example). If this option is not specified, but
+ the image file carries the <literal>user.verity.roothash</literal> extended file attribute (see <citerefentry
+ project='man-pages'><refentrytitle>xattr</refentrytitle><manvolnum>7</manvolnum></citerefentry>), then the root
+ hash is read from it, also as formatted hexadecimal characters. If the extended file attribute is not found (or
+ is not supported by the underlying file system), but a file with the <filename>.roothash</filename> suffix is
+ found next to the image file, bearing otherwise the same name, the root hash is read from it and automatically
+ used, also as formatted hexadecimal characters.</para></listitem>
</varlistentry>
<varlistentry>
@@ -333,6 +340,22 @@
</varlistentry>
<varlistentry>
+ <term><option>--pivot-root=</option></term>
+
+ <listitem><para>Pivot the specified directory to <filename>/</filename> inside the container, and either unmount the
+ container's old root, or pivot it to another specified directory. Takes one of: a path argument — in which case the
+ specified path will be pivoted to <filename>/</filename> and the old root will be unmounted; or a colon-separated pair
+ of new root path and pivot destination for the old root. The new root path will be pivoted to <filename>/</filename>,
+ and the old <filename>/</filename> will be pivoted to the other directory. Both paths must be absolute, and are resolved
+ in the container's file system namespace.</para>
+
+ <para>This is for containers which have several bootable directories in them; for example, several
+ <ulink url="https://ostree.readthedocs.io/en/latest/">OSTree</ulink> deployments. It emulates the behavior of
+ the boot loader and initial RAM disk which normally select which directory to mount as the root and start the
+ container's PID 1 in.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>-u</option></term>
<term><option>--user=</option></term>
@@ -451,7 +474,12 @@
<para>Note that the picked UID/GID range is not written to <filename>/etc/passwd</filename> or
<filename>/etc/group</filename>. In fact, the allocation of the range is not stored persistently anywhere,
- except in the file ownership of the files and directories of the container.</para></listitem>
+ except in the file ownership of the files and directories of the container.</para>
+
+ <para>Note that when user namespacing is used file ownership on disk reflects this, and all of the container's
+ files and directories are owned by the container's effective user and group IDs. This means that copying files
+ from and to the container image requires correction of the numeric UID/GID values, according to the UID/GID
+ shift applied.</para></listitem>
</varlistentry>
<varlistentry>
@@ -608,7 +636,7 @@
broadcast domain, here called a "zone". Each container may only be part of one zone, but each zone may contain
any number of containers. Each zone is referenced by its name. Names may be chosen freely (as long as they form
valid network interface names when prefixed with <literal>vz-</literal>), and it is sufficient to pass the same
- name to the <option>--network-zones=</option> switch of the various concurrently running containers to join
+ name to the <option>--network-zone=</option> switch of the various concurrently running containers to join
them in one zone.</para>
<para>Note that
@@ -754,21 +782,19 @@
<term><option>--bind=</option></term>
<term><option>--bind-ro=</option></term>
- <listitem><para>Bind mount a file or directory from the host
- into the container. Takes one of: a path argument — in which
- case the specified path will be mounted from the host to the
- same path in the container —, or a colon-separated pair of
- paths — in which case the first specified path is the source
- in the host, and the second path is the destination in the
- container —, or a colon-separated triple of source path,
- destination path and mount options. Mount options are
- comma-separated and currently, only "rbind" and "norbind"
- are allowed. Defaults to "rbind". Backslash escapes are interpreted, so
- <literal>\:</literal> may be used to embed colons in either path.
- This option may be specified multiple times for
- creating multiple independent bind mount points. The
- <option>--bind-ro=</option> option creates read-only bind
- mounts.</para></listitem>
+ <listitem><para>Bind mount a file or directory from the host into the container. Takes one of: a path
+ argument — in which case the specified path will be mounted from the host to the same path in the container, or
+ a colon-separated pair of paths — in which case the first specified path is the source in the host, and the
+ second path is the destination in the container, or a colon-separated triple of source path, destination path
+ and mount options. The source path may optionally be prefixed with a <literal>+</literal> character. If so, the
+ source path is taken relative to the image's root directory. This permits setting up bind mounts within the
+ container image. The source path may be specified as empty string, in which case a temporary directory below
+ the host's <filename>/var/tmp</filename> directory is used. It is automatically removed when the container is
+ shut down. Mount options are comma-separated and currently, only <option>rbind</option> and
+ <option>norbind</option> are allowed, controlling whether to create a recursive or a regular bind
+ mount. Defaults to "rbind". Backslash escapes are interpreted, so <literal>\:</literal> may be used to embed
+ colons in either path. This option may be specified multiple times for creating multiple independent bind
+ mount points. The <option>--bind-ro=</option> option creates read-only bind mounts.</para></listitem>
</varlistentry>
<varlistentry>
@@ -822,6 +848,14 @@
point for the overlay file system in the container. At least
two paths have to be specified.</para>
+ <para>The source paths may optionally be prefixed with <literal>+</literal> character. If so they are taken
+ relative to the image's root directory. The uppermost source path may also be specified as empty string, in
+ which case a temporary directory below the host's <filename>/var/tmp</filename> is used. The directory is
+ removed automatically when the container is shut down. This behaviour is useful in order to make read-only
+ container directories writable while the container is running. For example, use the
+ <literal>--overlay=+/var::/var</literal> option in order to automatically overlay a writable temporary
+ directory on a read-only <filename>/var</filename> directory.</para>
+
<para>For details about overlay file systems, see <ulink
url="https://www.kernel.org/doc/Documentation/filesystems/overlayfs.txt">overlayfs.txt</ulink>. Note
that the semantics of overlay file systems are substantially
@@ -930,12 +964,15 @@
<option>no</option> (the default), the whole OS tree is made
available writable.</para>
- <para>Note that setting this to <option>yes</option> or
- <option>state</option> will only work correctly with
- operating systems in the container that can boot up with only
- <filename>/usr</filename> mounted, and are able to populate
- <filename>/var</filename> automatically, as
- needed.</para></listitem>
+ <para>This option provides similar functionality for containers as the <literal>systemd.volatile=</literal>
+ kernel command line switch provides for host systems. See
+ <citerefentry><refentrytitle>kernel-command-line</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
+ details.</para>
+
+ <para>Note that enabling this setting will only work correctly with operating systems in the container that can
+ boot up with only <filename>/usr</filename> mounted, and are able to automatically populate
+ <filename>/var</filename>, and also <filename>/etc</filename> in case of
+ <literal>--volatile=yes</literal>.</para></listitem>
</varlistentry>
<varlistentry>
@@ -1011,10 +1048,26 @@
<refsect1>
<title>Examples</title>
+<!-- TODO: This example needs switched to an FSDG OS; but I'm not sure of a good machinectl-compatible image to use.
+ <example>
+ <title>Download a Fedora image and start a shell in it</title>
+
+ <programlisting># machinectl pull-raw -&2D;verify=no \
+ https://download.fedoraproject.org/pub/fedora/linux/releases/25/CloudImages/x86_64/images/Fedora-Cloud-Base-25-1.3.x86_64.raw.xz
+# systemd-nspawn -M Fedora-Cloud-Base-25-1.3.x86_64.raw</programlisting>
+
+ <para>This downloads an image using
+ <citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ and opens a shell in it.</para>
+ </example>
+-->
+
<example>
<title>Build and boot a minimal BLAG distribution in a container</title>
- <programlisting># dnf -y --releasever=210k --installroot=/srv/mycontainer --disablerepo='*' --enablerepo=blag --enablerepo=updates install systemd passwd dnf blag-release vim-minimal
+ <programlisting># dnf -y --releasever=210k --installroot=/srv/mycontainer \
+ --disablerepo='*' --enablerepo=blag --enablerepo=updates install \
+ systemd passwd dnf blag-release vim-minimal
# systemd-nspawn -bD /srv/mycontainer</programlisting>
<para>This installs a minimal BLAG distribution into the
@@ -1045,21 +1098,28 @@
</example>
<example>
- <title>Boot into an ephemeral <literal>btrfs</literal> snapshot of the host system</title>
+ <title>Boot into an ephemeral snapshot of the host system</title>
<programlisting># systemd-nspawn -D / -xb</programlisting>
- <para>This runs a copy of the host system in a
- <literal>btrfs</literal> snapshot which is removed immediately
- when the container exits. All file system changes made during
- runtime will be lost on shutdown, hence.</para>
+ <para>This runs a copy of the host system in a snapshot which is removed immediately when the container
+ exits. All file system changes made during runtime will be lost on shutdown, hence.</para>
</example>
<example>
<title>Run a container with SELinux sandbox security contexts</title>
<programlisting># chcon system_u:object_r:svirt_sandbox_file_t:s0:c0,c1 -R /srv/container
-# systemd-nspawn -L system_u:object_r:svirt_sandbox_file_t:s0:c0,c1 -Z system_u:system_r:svirt_lxc_net_t:s0:c0,c1 -D /srv/container /bin/sh</programlisting>
+# systemd-nspawn -L system_u:object_r:svirt_sandbox_file_t:s0:c0,c1 \
+ -Z system_u:system_r:svirt_lxc_net_t:s0:c0,c1 -D /srv/container /bin/sh</programlisting>
+ </example>
+
+ <example>
+ <title>Run a container with an OSTree deployment</title>
+
+ <programlisting># systemd-nspawn -b -i ~/image.raw \
+ --pivot-root=/ostree/deploy/$OS/deploy/$CHECKSUM:/sysroot \
+ --bind=+/sysroot/ostree/deploy/$OS/var:/var</programlisting>
</example>
</refsect1>
diff --git a/man/systemd-remount-fs.service.xml b/man/systemd-remount-fs.service.xml
index 176f2b2d20..6a5f0e6e38 100644
--- a/man/systemd-remount-fs.service.xml
+++ b/man/systemd-remount-fs.service.xml
@@ -72,7 +72,7 @@
systems.</para>
<para>For a longer discussion of kernel API file systems see
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems">API
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems">API
File Systems</ulink>.</para>
</refsect1>
diff --git a/man/systemd-resolve.xml b/man/systemd-resolve.xml
index 2bc917ac26..50da971b07 100644
--- a/man/systemd-resolve.xml
+++ b/man/systemd-resolve.xml
@@ -120,7 +120,7 @@
originating from local, trusted sources is also reported authenticated, including resolution of the local host
name, the <literal>localhost</literal> host name or all data from <filename>/etc/hosts</filename>.</para>
- <para>The <option>--type=</option> switch may be used to specify a DNS resource record type (A, AAAA, SOA, MX, ...) in
+ <para>The <option>--type=</option> switch may be used to specify a DNS resource record type (A, AAAA, SOA, MX, …) in
order to request a specific DNS resource record, instead of the address or reverse address lookups.
The special value <literal>help</literal> may be used to list known values.</para>
@@ -182,7 +182,9 @@
(i.e. classic unicast DNS), <literal>llmnr</literal> (<ulink
url="https://tools.ietf.org/html/rfc4795">Link-Local Multicast Name Resolution</ulink>),
<literal>llmnr-ipv4</literal>, <literal>llmnr-ipv6</literal> (LLMNR via the indicated underlying IP
- protocols). By default the lookup is done via all protocols suitable for the lookup. If used, limits the set of
+ protocols), <literal>mdns</literal> (<ulink url="https://www.ietf.org/rfc/rfc6762.txt">Multicast DNS</ulink>),
+ <literal>mdns-ipv4</literal>, <literal>mdns-ipv6</literal> (MDNS via the indicated underlying IP protocols).
+ By default the lookup is done via all protocols suitable for the lookup. If used, limits the set of
protocols that may be used. Use this option multiple times to enable resolving via multiple protocols at the
same time. The setting <literal>llmnr</literal> is identical to specifying this switch once with
<literal>llmnr-ipv4</literal> and once via <literal>llmnr-ipv6</literal>. Note that this option does not force
@@ -271,7 +273,7 @@
<literal>payload</literal>, the payload of the packet is exported. If the argument is
<literal>packet</literal>, the whole packet is dumped in wire format, prefixed by
length specified as a little-endian 64-bit number. This format allows multiple packets
- to be dumped and unambigously parsed.</para></listitem>
+ to be dumped and unambiguously parsed.</para></listitem>
</varlistentry>
<varlistentry>
@@ -356,7 +358,7 @@ _xmpp-server._tcp/gmail.com: alt1.xmpp-server.l.google.com:5269 [priority=20, we
173.194.210.125
alt4.xmpp-server.l.google.com:5269 [priority=20, weight=0]
173.194.65.125
- ...
+ …
</programlisting>
</example>
@@ -367,7 +369,7 @@ _xmpp-server._tcp/gmail.com: alt1.xmpp-server.l.google.com:5269 [priority=20, we
d08ee310438ca124a6149ea5cc21b6313b390dce485576eff96f8722._openpgpkey.fedoraproject.org. IN OPENPGPKEY
mQINBFBHPMsBEACeInGYJCb+7TurKfb6wGyTottCDtiSJB310i37/6ZYoeIay/5soJjlMyf
MFQ9T2XNT/0LM6gTa0MpC1st9LnzYTMsT6tzRly1D1UbVI6xw0g0vE5y2Cjk3xUwAynCsSs
- ...
+ …
</programlisting>
</example>
diff --git a/man/systemd-resolved.service.xml b/man/systemd-resolved.service.xml
index 56f67960ce..f6831848c7 100644
--- a/man/systemd-resolved.service.xml
+++ b/man/systemd-resolved.service.xml
@@ -62,7 +62,7 @@
<itemizedlist>
<listitem><para>The native, fully-featured API <command>systemd-resolved</command> exposes on the bus. See the
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/resolved">API Documentation</ulink> for
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/resolved">API Documentation</ulink> for
details. Usage of this API is generally recommended to clients as it is asynchronous and fully featured (for
example, properly returns DNSSEC validation status and interface scope for addresses as necessary for supporting
link-local networking).</para></listitem>
@@ -116,8 +116,9 @@
current gateway, useful for referencing it independently of the
current network configuration state.</para></listitem>
- <listitem><para>The mappings defined in <filename>/etc/hosts</filename> are resolved to their configured
- addresses and back.</para></listitem>
+ <listitem><para>The mappings defined in <filename>/etc/hosts</filename> are resolved
+ to their configured addresses and back, but they will not affect lookups for
+ non-address types (like MX).</para></listitem>
</itemizedlist>
<para>Lookup requests are routed to the available DNS servers
@@ -155,7 +156,7 @@
per-interface domains are exclusively routed to the matching
interfaces.</para>
- <para>See the <ulink url="http://www.freedesktop.org/wiki/Software/systemd/resolved"> resolved D-Bus API
+ <para>See the <ulink url="https://www.freedesktop.org/wiki/Software/systemd/resolved"> resolved D-Bus API
Documentation</ulink> for information about the APIs <filename>systemd-resolved</filename> provides.</para>
</refsect1>
diff --git a/man/systemd-run.xml b/man/systemd-run.xml
index 2ad8cb0835..5e44b1523d 100644
--- a/man/systemd-run.xml
+++ b/man/systemd-run.xml
@@ -77,7 +77,7 @@
other service, and thus shows up in the output of <command>systemctl list-units</command> like any other unit. It
will run in a clean and detached execution environment, with the service manager as its parent process. In this
mode, <command>systemd-run</command> will start the service asynchronously in the background and return after the
- command has begun execution (unless <option>--no-block</option> or <option>--watch</option> are specified, see
+ command has begun execution (unless <option>--no-block</option> or <option>--wait</option> are specified, see
below).</para>
<para>If a command is run as transient scope unit, it will be executed by <command>systemd-run</command> itself as
@@ -221,7 +221,12 @@
<listitem><para>When invoking the command, the transient service connects its standard input and output to the
terminal <command>systemd-run</command> is invoked on, via a pseudo TTY device. This allows running binaries
- that expect interactive user input as services, such as interactive command shells.</para></listitem>
+ that expect interactive user input as services, such as interactive command shells.</para>
+
+ <para>Note that
+ <citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
+ <command>shell</command> command is usually a better alternative for requesting a new, interactive login
+ session on the local host or a local container.</para></listitem>
</varlistentry>
<varlistentry>
@@ -245,7 +250,7 @@
command. See <varname>OnActiveSec=</varname>, <varname>OnBootSec=</varname>, <varname>OnStartupSec=</varname>,
<varname>OnUnitActiveSec=</varname> and <varname>OnUnitInactiveSec=</varname> in
<citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
- details. These options may not be combined with <option>--scope</option>.</para>
+ details. These options may not be combined with <option>--scope</option> or <option>--pty</option>.</para>
</listitem>
</varlistentry>
@@ -254,7 +259,7 @@
<listitem><para>Defines a calendar timer for starting the specified command. See <varname>OnCalendar=</varname>
in <citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry>. This
- option may not be combined with <option>--scope</option>.</para>
+ option may not be combined with <option>--scope</option> or <option>--pty</option>.</para>
</listitem>
</varlistentry>
diff --git a/man/systemd-socket-activate.xml b/man/systemd-socket-activate.xml
index 1c0619a840..356bc10359 100644
--- a/man/systemd-socket-activate.xml
+++ b/man/systemd-socket-activate.xml
@@ -136,7 +136,7 @@
</varlistentry>
<varlistentry>
- <term><option>--fdname=</option><replaceable>NAME</replaceable><optional>:<replaceable>NAME</replaceable>...</optional></term>
+ <term><option>--fdname=</option><replaceable>NAME</replaceable><optional>:<replaceable>NAME</replaceable>…</optional></term>
<listitem><para>Specify names for the file descriptors passed. This is equivalent to setting
<varname>FileDescriptorName=</varname> in socket unit files, and enables use of
diff --git a/man/systemd-socket-proxyd.xml b/man/systemd-socket-proxyd.xml
index ae4217b910..b8a7800b82 100644
--- a/man/systemd-socket-proxyd.xml
+++ b/man/systemd-socket-proxyd.xml
@@ -85,6 +85,13 @@
<variablelist>
<xi:include href="standard-options.xml" xpointer="help" />
<xi:include href="standard-options.xml" xpointer="version" />
+ <varlistentry>
+ <term><option>--connections-max=</option></term>
+ <term><option>-c</option></term>
+
+ <listitem><para>Sets the maximum number of simultaneous connections, defaults to 256.
+ If the limit of concurrent connections is reached further connections will be refused.</para></listitem>
+ </varlistentry>
</variablelist>
</refsect1>
<refsect1>
@@ -120,16 +127,15 @@ PrivateNetwork=yes]]></programlisting>
<example>
<title>nginx.conf</title>
<programlisting>
-<![CDATA[[...]
+<![CDATA[[…]
server {
listen unix:/tmp/nginx.sock;
- [...]]]>
+ […]]]>
</programlisting>
</example>
<example>
<title>Enabling the proxy</title>
- <programlisting><![CDATA[# systemctl enable proxy-to-nginx.socket
-# systemctl start proxy-to-nginx.socket
+ <programlisting><![CDATA[# systemctl enable --now proxy-to-nginx.socket
$ curl http://localhost:80/]]></programlisting>
</example>
</refsect2>
@@ -162,15 +168,14 @@ PrivateNetwork=yes]]></programlisting>
</example>
<example>
<title>nginx.conf</title>
- <programlisting><![CDATA[[...]
+ <programlisting><![CDATA[[…]
server {
listen 8080;
- [...]]]></programlisting>
+ […]]]></programlisting>
</example>
<example>
<title>Enabling the proxy</title>
- <programlisting><![CDATA[# systemctl enable proxy-to-nginx.socket
-# systemctl start proxy-to-nginx.socket
+ <programlisting><![CDATA[# systemctl enable --now proxy-to-nginx.socket
$ curl http://localhost:80/]]></programlisting>
</example>
</refsect2>
diff --git a/man/systemd-suspend.service.xml b/man/systemd-suspend.service.xml
index a8beb86f4d..2aa172e990 100644
--- a/man/systemd-suspend.service.xml
+++ b/man/systemd-suspend.service.xml
@@ -89,8 +89,10 @@
<para>Note that scripts or binaries dropped in
<filename>/usr/lib/systemd/system-sleep/</filename> are intended
for local use only and should be considered hacks. If applications
- want to be notified of system suspend/hibernation and resume,
- there are much nicer interfaces available.</para>
+ want to react to system suspend/hibernation and resume,
+ they should rather use the <ulink
+ url="https://www.freedesktop.org/wiki/Software/systemd/inhibit">Inhibitor
+ interface</ulink>.</para>
<para>Note that
<filename>systemd-suspend.service</filename>,
diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml
index e4e81f7f2e..336c7a5fd1 100644
--- a/man/systemd-system.conf.xml
+++ b/man/systemd-system.conf.xml
@@ -97,12 +97,10 @@
<term><varname>DefaultStandardOutput=journal</varname></term>
<term><varname>DefaultStandardError=inherit</varname></term>
- <listitem><para>Configures various parameters of basic manager
- operation. These options may be overridden by the respective
- command line arguments. See
- <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
- for details about these command line
- arguments.</para></listitem>
+ <listitem><para>Configures various parameters of basic manager operation. These options may be overridden by
+ the respective process and kernel command line arguments. See
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> for
+ details.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/systemd-timedated.service.xml b/man/systemd-timedated.service.xml
index e44163aefb..fee860204d 100644
--- a/man/systemd-timedated.service.xml
+++ b/man/systemd-timedated.service.xml
@@ -67,7 +67,7 @@
is a command line client to this service.</para>
<para>See the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/timedated">
+ url="https://www.freedesktop.org/wiki/Software/systemd/timedated">
developer documentation</ulink> for information about the APIs
<filename>systemd-timedated</filename> provides.</para>
</refsect1>
diff --git a/man/systemd-timesyncd.service.xml b/man/systemd-timesyncd.service.xml
index 6ec384313b..3edcaf1b4e 100644
--- a/man/systemd-timesyncd.service.xml
+++ b/man/systemd-timesyncd.service.xml
@@ -64,6 +64,12 @@
reboots to ensure it monotonically advances even if the system
lacks a battery-buffered RTC chip.</para>
+ <para>The <filename>systemd-timesyncd</filename> service
+ specifically implements only SNTP. This minimalistic
+ service will set the system clock for large offsets or
+ slowly adjust it for smaller deltas. More complex use
+ cases are not covered by <filename>systemd-timesyncd</filename>.</para>
+
<para>The NTP servers contacted are determined from the global
settings in
<citerefentry><refentrytitle>timesyncd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
diff --git a/man/systemd-tty-ask-password-agent.xml b/man/systemd-tty-ask-password-agent.xml
index 2876fab644..2c114f4631 100644
--- a/man/systemd-tty-ask-password-agent.xml
+++ b/man/systemd-tty-ask-password-agent.xml
@@ -50,7 +50,9 @@
<refsynopsisdiv>
<cmdsynopsis>
- <command>systemd-tty-ask-password-agent <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt" rep="repeat">VARIABLE=VALUE</arg></command>
+ <command>systemd-tty-ask-password-agent</command>
+ <arg choice="opt" rep="repeat">OPTIONS</arg>
+ <arg choice="opt" rep="repeat">VARIABLE=VALUE</arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -64,9 +66,11 @@
runtime.</para>
<para><command>systemd-tty-ask-password-agent</command> implements
- the <ulink url="http://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">Password
- Agents Specification</ulink>.</para>
-
+ the <ulink url="https://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">Password
+ Agents Specification</ulink>, and is one of many possible response agents which
+ answer to queries formulated with
+ <citerefentry><refentrytitle>systemd-ask-password</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
+ </para>
</refsect1>
<refsect1>
diff --git a/man/systemd-udevd.service.xml b/man/systemd-udevd.service.xml
index 243fd06471..81b957b0c8 100644
--- a/man/systemd-udevd.service.xml
+++ b/man/systemd-udevd.service.xml
@@ -133,22 +133,22 @@
<para>Parameters starting with "rd." will be read when
<command>systemd-udevd</command> is used in an initrd.</para>
<varlistentry>
- <term><varname>udev.log-priority=</varname></term>
- <term><varname>rd.udev.log-priority=</varname></term>
+ <term><varname>udev.log_priority=</varname></term>
+ <term><varname>rd.udev.log_priority=</varname></term>
<listitem>
<para>Set the log level.</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><varname>udev.children-max=</varname></term>
- <term><varname>rd.udev.children-max=</varname></term>
+ <term><varname>udev.children_max=</varname></term>
+ <term><varname>rd.udev.children_max=</varname></term>
<listitem>
<para>Limit the number of events executed in parallel.</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><varname>udev.exec-delay=</varname></term>
- <term><varname>rd.udev.exec-delay=</varname></term>
+ <term><varname>udev.exec_delay=</varname></term>
+ <term><varname>rd.udev.exec_delay=</varname></term>
<listitem>
<para>Delay the execution of <varname>RUN</varname> instructions by the given
number of seconds. This option might be useful when
@@ -157,8 +157,8 @@
</listitem>
</varlistentry>
<varlistentry>
- <term><varname>udev.event-timeout=</varname></term>
- <term><varname>rd.udev.event-timeout=</varname></term>
+ <term><varname>udev.event_timeout=</varname></term>
+ <term><varname>rd.udev.event_timeout=</varname></term>
<listitem>
<para>Wait for events to finish up to the given number
of seconds. This option might be useful if events are
diff --git a/man/systemd-veritysetup-generator.xml b/man/systemd-veritysetup-generator.xml
new file mode 100644
index 0000000000..87d66e9ee5
--- /dev/null
+++ b/man/systemd-veritysetup-generator.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-veritysetup-generator" conditional='HAVE_LIBCRYPTSETUP'>
+
+ <refentryinfo>
+ <title>systemd-veritysetup-generator</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <contrib>Developer</contrib>
+ <firstname>Lennart</firstname>
+ <surname>Poettering</surname>
+ <email>lennart@poettering.net</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>systemd-veritysetup-generator</refentrytitle>
+ <manvolnum>8</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>systemd-veritysetup-generator</refname>
+ <refpurpose>Unit generator for integrity protected block devices</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <para><filename>/usr/lib/systemd/system-generators/systemd-veritysetup-generator</filename></para>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><filename>systemd-veritysetup-generator</filename> is a generator that translates kernel command line options
+ configuring integrity protected block devices (verity) into native systemd units early at boot and when
+ configuration of the system manager is reloaded. This will create
+ <citerefentry><refentrytitle>systemd-veritysetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ units as necessary.</para>
+
+ <para>Currently, only a single verity device may be se up with this generator, backing the root file system of the
+ OS.</para>
+
+ <para><filename>systemd-veritysetup-generator</filename> implements
+ <citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Kernel Command Line</title>
+
+ <para><filename>systemd-veritysetup-generator</filename>
+ understands the following kernel command line parameters:</para>
+
+ <variablelist class='kernel-commandline-options'>
+ <varlistentry>
+ <term><varname>systemd.verity=</varname></term>
+ <term><varname>rd.systemd.verity=</varname></term>
+
+ <listitem><para>Takes a boolean argument. Defaults to <literal>yes</literal>. If <literal>no</literal>,
+ disables the generator entirely. <varname>rd.systemd.verity=</varname> is honored only by the initial RAM disk
+ (initrd) while <varname>systemd.verity=</varname> is honored by both the host system and the
+ initrd. </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>roothash=</varname></term>
+
+ <listitem><para>Takes a root hash value for the root file system. Expects a hash value formatted in hexadecimal
+ characters, of the appropriate length (i.e. most likely 256 bit/64 characters, or longer). If not specified via
+ <varname>systemd.verity_root_data=</varname> and <varname>systemd.verity_root_hash=</varname>, the hash and
+ data devices to use are automatically derived from the specified hash value. Specifically, the data partition
+ device is looked for under a GPT partition UUID derived from the first 128bit of the root hash, the hash
+ partition device is looked for under a GPT partition UUID derived from the last 128bit of the root hash. Hence
+ it is usually sufficient to specify the root hash to boot from an integrity protected root file system, as
+ device paths are automatically determined from it — as long as the partition table is properly set up.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>systemd.verity_root_data=</varname></term>
+ <term><varname>systemd.verity_root_hash=</varname></term>
+
+ <listitem><para>These two settings take block device paths as arguments, and may be use to explicitly configure
+ the data partition and hash partition to use for setting up the integrity protection for the root file
+ system. If not specified, these paths are automatically derived from the <varname>roothash=</varname> argument
+ (see above).</para></listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+ <para>
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-veritysetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry project='die-net'><refentrytitle>veritysetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/systemd-veritysetup@.service.xml b/man/systemd-veritysetup@.service.xml
new file mode 100644
index 0000000000..173e5358e0
--- /dev/null
+++ b/man/systemd-veritysetup@.service.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-veritysetup@.service" conditional='HAVE_LIBCRYPTSETUP'>
+
+ <refentryinfo>
+ <title>systemd-veritysetup@.service</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <contrib>Developer</contrib>
+ <firstname>Lennart</firstname>
+ <surname>Poettering</surname>
+ <email>lennart@poettering.net</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>systemd-veritysetup@.service</refentrytitle>
+ <manvolnum>8</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>systemd-veritysetup@.service</refname>
+ <refname>systemd-veritysetup</refname>
+ <refpurpose>Disk integrity protection logic</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <para><filename>systemd-veritysetup@.service</filename></para>
+ <para><filename>/usr/lib/systemd/systemd-veritysetup</filename></para>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><filename>systemd-veritysetup@.service</filename> is a service responsible for setting up integrity
+ protection (verity) block devices. It should be instantiated for each device that requires integrity
+ protection.</para>
+
+ <para>At early boot and when the system manager configuration is reloaded kernel command line configuration for
+ integrity protected block devices is translated into <filename>systemd-veritysetup@.service</filename> units by
+ <citerefentry><refentrytitle>systemd-veritysetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+ <para>
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-veritysetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry project='die-net'><refentrytitle>veritysetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/systemd-volatile-root.service.xml b/man/systemd-volatile-root.service.xml
new file mode 100644
index 0000000000..b90a3261fa
--- /dev/null
+++ b/man/systemd-volatile-root.service.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-volatile-root.service">
+
+ <refentryinfo>
+ <title>systemd-volatile-root.service</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <contrib>Developer</contrib>
+ <firstname>Lennart</firstname>
+ <surname>Poettering</surname>
+ <email>lennart@poettering.net</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>systemd-volatile-root.service</refentrytitle>
+ <manvolnum>8</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>systemd-volatile-root.service</refname>
+ <refname>systemd-volatile-root</refname>
+ <refpurpose>Make the root file system volatile</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <para><filename>systemd-volatile-root.service</filename></para>
+ <para><filename>/usr/lib/systemd/systemd-volatile-root</filename></para>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><filename>systemd-volatile-root.service</filename> is a service that replaces the root directory with a
+ volatile memory file system (<literal>tmpfs</literal>), mounting the original (non-volatile)
+ <filename>/usr</filename> inside it read-only. This way, vendor data from <filename>/usr</filename> is available as
+ usual, but all configuration data in <filename>/etc</filename>, all state data in <filename>/var</filename> and all
+ other resources stored directly under the root directory are reset on boot and lost at shutdown, enabling fully
+ stateless systems.</para>
+
+ <para>This service is only enabled if full volatile mode is selected, for example by specifying
+ <literal>systemd.volatile=yes</literal> on the kernel command line. This service runs only in the initial RAM disk
+ ("initrd"), before the system transitions to the host's root directory. Note that this service is not used if
+ <literal>systemd.volatile=state</literal> is used, as in that mode the root directory is non-volatile.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+ <para>
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>kernel-command-line</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/systemd.environment-generator.xml b/man/systemd.environment-generator.xml
new file mode 100644
index 0000000000..fedbd60175
--- /dev/null
+++ b/man/systemd.environment-generator.xml
@@ -0,0 +1,160 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+<!ENTITY % entities SYSTEM "custom-entities.ent" >
+%entities;
+]>
+
+<!--
+ This file is part of systemd.
+
+ Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.environment-generator" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <refentryinfo>
+ <title>systemd.environment-generator</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <contrib>Developer</contrib>
+ <firstname>Zbigniew</firstname>
+ <surname>Jędrzejewski-Szmek</surname>
+ <email>zbyszek@in.waw.pl</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>systemd.environment-generator</refentrytitle>
+ <manvolnum>7</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>systemd.environment-generator</refname>
+ <refpurpose>Systemd environment file generators</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>&systemenvgeneratordir;/some-generator</command>
+ </cmdsynopsis>
+ <cmdsynopsis>
+ <command>&userenvgeneratordir;/some-generator</command>
+ </cmdsynopsis>
+
+ <para>
+ <literallayout><filename>/run/systemd/system-environment-generators/*</filename>
+<filename>/etc/systemd/system-environment-generators/*</filename>
+<filename>/usr/local/lib/systemd/system-environment-generators/*</filename>
+<filename>&systemenvgeneratordir;/*</filename></literallayout>
+ </para>
+
+ <para>
+ <literallayout><filename>/run/systemd/user-environment-generators/*</filename>
+<filename>/etc/systemd/user-environment-generators/*</filename>
+<filename>/usr/local/lib/systemd/user-environment-generators/*</filename>
+<filename>&userenvgeneratordir;/*</filename></literallayout>
+ </para>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>Generators are small executables that live in
+ <filename>&systemenvgeneratordir;/</filename> and other directories listed above.
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> will
+ execute those binaries very early at the startup of each manager and at configuration
+ reload time, before running the generators described in
+ <citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+ and before starting any units. Environment generators can override the environment that the
+ manager exports to services and other processes.</para>
+
+ <para>Generators are loaded from a set of paths determined during compilation, as listed
+ above. System and user environment generators are loaded from directories with names ending in
+ <filename>system-environment-generators/</filename> and
+ <filename>user-environment-generators/</filename>, respectively. Generators found in directories
+ listed earlier override the ones with the same name in directories lower in the list. A symlink
+ to <filename>/dev/null</filename> or an empty file can be used to mask a generator, thereby
+ preventing it from running. Please note that the order of the two directories with the highest
+ priority is reversed with respect to the unit load path, and generators in
+ <filename>/run</filename> overwrite those in <filename>/etc</filename>.</para>
+
+ <para>After installing new generators or updating the configuration, <command>systemctl
+ daemon-reload</command> may be executed. This will re-run all generators, updating environment
+ configuration. It will be used for any services that are started subsequently.</para>
+
+ <para>Environment file generators are executed similarly to unit file generators described
+ in
+ <citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ with the following differences:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Generators are executed sequentially in the alphanumerical order of the final
+ component of their name. The output of each generator output is immediately parsed and used
+ to update the environment for generators that run after that. Thus, later generators can use
+ and/or modify the output of earlier generators.</para>
+ </listitem>
+
+ <listitem>
+ <para>Generators are run by every manager instance, their output can be different for each
+ user.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>It is recommended to use numerical prefixes for generator names to simplify ordering.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <example>
+ <title>A simple generator that extends an environment variable if a directory exists in the file system</title>
+
+ <programlisting># 50-xdg-data-dirs.sh
+
+<xi:include href="50-xdg-data-dirs.sh" parse="text" /></programlisting>
+ </example>
+
+ <example>
+ <title>A more complicated generator which reads existing configuration and mutates one variable</title>
+
+ <programlisting># 90-rearrange-path.py
+
+<xi:include href="90-rearrange-path.py" parse="text" /></programlisting>
+ </example>
+
+ <example>
+ <title>Debugging a generator</title>
+
+ <programlisting>SYSTEMD_LOG_LEVEL=debug VAR_A=something VAR_B="something else" \
+&systemenvgeneratordir;/path-to-generator
+</programlisting>
+ </example>
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+
+ <para>
+ <citerefentry><refentrytitle>systemd-environment-d-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+</refentry>
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
index 3c350df11f..9a9387b798 100644
--- a/man/systemd.exec.xml
+++ b/man/systemd.exec.xml
@@ -86,17 +86,15 @@
<para>A few execution parameters result in additional, automatic
dependencies to be added.</para>
- <para>Units with <varname>WorkingDirectory=</varname> or
- <varname>RootDirectory=</varname> set automatically gain
- dependencies of type <varname>Requires=</varname> and
- <varname>After=</varname> on all mount units required to access
- the specified paths. This is equivalent to having them listed
- explicitly in <varname>RequiresMountsFor=</varname>.</para>
-
- <para>Similar, units with <varname>PrivateTmp=</varname> enabled
- automatically get mount unit dependencies for all mounts
- required to access <filename>/tmp</filename> and
- <filename>/var/tmp</filename>.</para>
+ <para>Units with <varname>WorkingDirectory=</varname>, <varname>RootDirectory=</varname> or
+ <varname>RootImage=</varname> set automatically gain dependencies of type <varname>Requires=</varname> and
+ <varname>After=</varname> on all mount units required to access the specified paths. This is equivalent to having
+ them listed explicitly in <varname>RequiresMountsFor=</varname>.</para>
+
+ <para>Similar, units with <varname>PrivateTmp=</varname> enabled automatically get mount unit dependencies for all
+ mounts required to access <filename>/tmp</filename> and <filename>/var/tmp</filename>. They will also gain an
+ automatic <varname>After=</varname> dependency on
+ <citerefentry><refentrytitle>systemd-tmpfiles-setup.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
<para>Units whose standard output or error output is connected to <option>journal</option>, <option>syslog</option>
or <option>kmsg</option> (or their combinations with console output, see below) automatically acquire dependencies
@@ -117,9 +115,10 @@
<varname>User=</varname> is used. If not set, defaults to the root directory when systemd is running as a
system instance and the respective user's home directory if run as user. If the setting is prefixed with the
<literal>-</literal> character, a missing working directory is not considered fatal. If
- <varname>RootDirectory=</varname> is not set, then <varname>WorkingDirectory=</varname> is relative to the root
- of the system running the service manager. Note that setting this parameter might result in additional
- dependencies to be added to the unit (see above).</para></listitem>
+ <varname>RootDirectory=</varname>/<varname>RootImage=</varname> is not set, then
+ <varname>WorkingDirectory=</varname> is relative to the root of the system running the service manager. Note
+ that setting this parameter might result in additional dependencies to be added to the unit (see
+ above).</para></listitem>
</varlistentry>
<varlistentry>
@@ -132,8 +131,33 @@
the <function>chroot()</function> jail. Note that setting this parameter might result in additional
dependencies to be added to the unit (see above).</para>
- <para>The <varname>PrivateUsers=</varname> setting is particularly useful in conjunction with
- <varname>RootDirectory=</varname>. For details, see below.</para></listitem>
+ <para>The <varname>MountAPIVFS=</varname> and <varname>PrivateUsers=</varname> settings are particularly useful
+ in conjunction with <varname>RootDirectory=</varname>. For details, see below.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>RootImage=</varname></term>
+ <listitem><para>Takes a path to a block device node or regular file as argument. This call is similar to
+ <varname>RootDirectory=</varname> however mounts a file system hierarchy from a block device node or loopback
+ file instead of a directory. The device node or file system image file needs to contain a file system without a
+ partition table, or a file system within an MBR/MS-DOS or GPT partition table with only a single
+ Linux-compatible partition, or a set of file systems within a GPT partition table that follows the <ulink
+ url="https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/">Discoverable Partitions
+ Specification</ulink>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>MountAPIVFS=</varname></term>
+
+ <listitem><para>Takes a boolean argument. If on, a private mount namespace for the unit's processes is created
+ and the API file systems <filename>/proc</filename>, <filename>/sys</filename>, and <filename>/dev</filename>
+ are mounted inside of it, unless they are already mounted. Note that this option has no effect unless used in
+ conjunction with <varname>RootDirectory=</varname>/<varname>RootImage=</varname> as these three mounts are
+ generally mounted in the host anyway, and unless the root directory is changed, the private mount namespace
+ will be a 1:1 copy of the host's, and include these three mounts. Note that the <filename>/dev</filename> file
+ system of the host is bind mounted if this option is used without <varname>PrivateDevices=</varname>. To run
+ the service with a private, minimal version of <filename>/dev/</filename>, combine this option with
+ <varname>PrivateDevices=</varname>.</para></listitem>
</varlistentry>
<varlistentry>
@@ -859,14 +883,17 @@
<varlistentry>
<term><varname>PAMName=</varname></term>
- <listitem><para>Sets the PAM service name to set up a session
- as. If set, the executed process will be registered as a PAM
- session under the specified service name. This is only useful
- in conjunction with the <varname>User=</varname> setting. If
- not set, no PAM session will be opened for the executed
- processes. See
- <citerefentry project='man-pages'><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>
- for details.</para></listitem>
+ <listitem><para>Sets the PAM service name to set up a session as. If set, the executed process will be
+ registered as a PAM session under the specified service name. This is only useful in conjunction with the
+ <varname>User=</varname> setting, and is otherwise ignored. If not set, no PAM session will be opened for the
+ executed processes. See <citerefentry
+ project='man-pages'><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry> for
+ details.</para>
+
+ <para>Note that for each unit making use of this option a PAM session handler process will be maintained as
+ part of the unit and stays around as long as the unit is active, to ensure that appropriate actions can be
+ taken when the unit and hence the PAM session terminates. This process is named <literal>(sd-pam)</literal> and
+ is an immediate child process of the unit's main process.</para></listitem>
</varlistentry>
<varlistentry>
@@ -935,7 +962,7 @@
access a process might have to the file system hierarchy. Each setting takes a space-separated list of paths
relative to the host's root directory (i.e. the system running the service manager). Note that if paths
contain symlinks, they are resolved relative to the root directory set with
- <varname>RootDirectory=</varname>.</para>
+ <varname>RootDirectory=</varname>/<varname>RootImage=</varname>.</para>
<para>Paths listed in <varname>ReadWritePaths=</varname> are accessible from within the namespace with the same
access modes as from outside of it. Paths listed in <varname>ReadOnlyPaths=</varname> are accessible for
@@ -952,13 +979,45 @@
assigned to this option, the specific list is reset, and all prior assignments have no effect.</para>
<para>Paths in <varname>ReadWritePaths=</varname>, <varname>ReadOnlyPaths=</varname> and
- <varname>InaccessiblePaths=</varname> may be prefixed with <literal>-</literal>, in which case they will be ignored
- when they do not exist. Note that using this setting will disconnect propagation of mounts from the service to
- the host (propagation in the opposite direction continues to work). This means that this setting may not be used
- for services which shall be able to install mount points in the main mount namespace. Note that the effect of
- these settings may be undone by privileged processes. In order to set up an effective sandboxed environment for
- a unit it is thus recommended to combine these settings with either
- <varname>CapabilityBoundingSet=~CAP_SYS_ADMIN</varname> or <varname>SystemCallFilter=~@mount</varname>.</para></listitem>
+ <varname>InaccessiblePaths=</varname> may be prefixed with <literal>-</literal>, in which case they will be
+ ignored when they do not exist. If prefixed with <literal>+</literal> the paths are taken relative to the root
+ directory of the unit, as configured with <varname>RootDirectory=</varname>/<varname>RootImage=</varname>,
+ instead of relative to the root directory of the host (see above). When combining <literal>-</literal> and
+ <literal>+</literal> on the same path make sure to specify <literal>-</literal> first, and <literal>+</literal>
+ second.</para>
+
+ <para>Note that using this setting will disconnect propagation of mounts from the service to the host
+ (propagation in the opposite direction continues to work). This means that this setting may not be used for
+ services which shall be able to install mount points in the main mount namespace. Note that the effect of these
+ settings may be undone by privileged processes. In order to set up an effective sandboxed environment for a
+ unit it is thus recommended to combine these settings with either
+ <varname>CapabilityBoundingSet=~CAP_SYS_ADMIN</varname> or
+ <varname>SystemCallFilter=~@mount</varname>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>BindPaths=</varname></term>
+ <term><varname>BindReadOnlyPaths=</varname></term>
+
+ <listitem><para>Configures unit-specific bind mounts. A bind mount makes a particular file or directory
+ available at an additional place in the unit's view of the file system. Any bind mounts created with this
+ option are specific to the unit, and are not visible in the host's mount table. This option expects a
+ whitespace separated list of bind mount definitions. Each definition consists of a colon-separated triple of
+ source path, destination path and option string, where the latter two are optional. If only a source path is
+ specified the source and destination is taken to be the same. The option string may be either
+ <literal>rbind</literal> or <literal>norbind</literal> for configuring a recursive or non-recursive bind
+ mount. If the destination path is omitted, the option string must be omitted too.</para>
+
+ <para><varname>BindPaths=</varname> creates regular writable bind mounts (unless the source file system mount
+ is already marked read-only), while <varname>BindReadOnlyPaths=</varname> creates read-only bind mounts. These
+ settings may be used more than once, each usage appends to the unit's list of bind mounts. If the empty string
+ is assigned to either of these two options the entire list of bind mounts defined prior to this is reset. Note
+ that in this case both read-only and regular bind mounts are reset, regardless which of the two settings is
+ used.</para>
+
+ <para>This option is particularly useful when <varname>RootDirectory=</varname>/<varname>RootImage=</varname>
+ is used. In this case the source path refers to a path on the host file system, while the destination path
+ refers to a path below the root directory of the unit.</para></listitem>
</varlistentry>
<varlistentry>
@@ -975,8 +1034,11 @@
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
details. This setting is implied if <varname>DynamicUser=</varname> is set. For this setting the same
restrictions regarding mount propagation and privileges apply as for <varname>ReadOnlyPaths=</varname> and
- related calls, see above.</para></listitem>
-
+ related calls, see above. Enabling this setting has the side effect of adding <varname>Requires=</varname> and
+ <varname>After=</varname> dependencies on all mount units necessary to access <filename>/tmp</filename> and
+ <filename>/var/tmp</filename>. Moreover an implicitly <varname>After=</varname> ordering on
+ <citerefentry><refentrytitle>systemd-tmpfiles-setup.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ is added.</para></listitem>
</varlistentry>
<varlistentry>
@@ -999,7 +1061,11 @@
using <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry> of
<filename>/dev/zero</filename> instead of using <constant>MAP_ANON</constant>. This setting is implied if
<varname>DynamicUser=</varname> is set. For this setting the same restrictions regarding mount propagation and
- privileges apply as for <varname>ReadOnlyPaths=</varname> and related calls, see above.</para></listitem>
+ privileges apply as for <varname>ReadOnlyPaths=</varname> and related calls, see above.
+ If turned on and if running in user mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant>
+ capability (e.g. setting <varname>User=</varname>), <varname>NoNewPrivileges=yes</varname>
+ is implied.
+ </para></listitem>
</varlistentry>
<varlistentry>
@@ -1039,10 +1105,10 @@
such as <varname>CapabilityBoundingSet=</varname> will affect only the latter, and there's no way to acquire
additional capabilities in the host's user namespace. Defaults to off.</para>
- <para>This setting is particularly useful in conjunction with <varname>RootDirectory=</varname>, as the need to
- synchronize the user and group databases in the root directory and on the host is reduced, as the only users
- and groups who need to be matched are <literal>root</literal>, <literal>nobody</literal> and the unit's own
- user and group.</para></listitem>
+ <para>This setting is particularly useful in conjunction with
+ <varname>RootDirectory=</varname>/<varname>RootImage=</varname>, as the need to synchronize the user and group
+ databases in the root directory and on the host is reduced, as the only users and groups who need to be matched
+ are <literal>root</literal>, <literal>nobody</literal> and the unit's own user and group.</para></listitem>
</varlistentry>
<varlistentry>
@@ -1085,14 +1151,42 @@
<filename>/proc/sys</filename>, <filename>/sys</filename>, <filename>/proc/sysrq-trigger</filename>,
<filename>/proc/latency_stats</filename>, <filename>/proc/acpi</filename>,
<filename>/proc/timer_stats</filename>, <filename>/proc/fs</filename> and <filename>/proc/irq</filename> will
- be made read-only to all processes of the unit. Usually, tunable kernel variables should only be written at
- boot-time, with the <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- mechanism. Almost no services need to write to these at runtime; it is hence recommended to turn this on for
- most services. For this setting the same restrictions regarding mount propagation and privileges apply as for
- <varname>ReadOnlyPaths=</varname> and related calls, see above. Defaults to off.
- Note that this option does not prevent kernel tuning through IPC interfaces and external programs. However
- <varname>InaccessiblePaths=</varname> can be used to make some IPC file system objects
- inaccessible.</para></listitem>
+ be made read-only to all processes of the unit. Usually, tunable kernel variables should be initialized only at
+ boot-time, for example with the
+ <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> mechanism. Few
+ services need to write to these at runtime; it is hence recommended to turn this on for most services. For this
+ setting the same restrictions regarding mount propagation and privileges apply as for
+ <varname>ReadOnlyPaths=</varname> and related calls, see above. Defaults to off. If turned on and if running
+ in user mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant> capability (e.g. services
+ for which <varname>User=</varname> is set), <varname>NoNewPrivileges=yes</varname> is implied. Note that this
+ option does not prevent indirect changes to kernel tunables effected by IPC calls to other processes. However,
+ <varname>InaccessiblePaths=</varname> may be used to make relevant IPC file system objects inaccessible. If
+ <varname>ProtectKernelTunables=</varname> is set, <varname>MountAPIVFS=yes</varname> is
+ implied.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>ProtectKernelModules=</varname></term>
+
+ <listitem><para>Takes a boolean argument. If true, explicit module loading will
+ be denied. This allows to turn off module load and unload operations on modular
+ kernels. It is recommended to turn this on for most services that do not need special
+ file systems or extra kernel modules to work. Default to off. Enabling this option
+ removes <constant>CAP_SYS_MODULE</constant> from the capability bounding set for
+ the unit, and installs a system call filter to block module system calls,
+ also <filename>/usr/lib/modules</filename> is made inaccessible. For this
+ setting the same restrictions regarding mount propagation and privileges
+ apply as for <varname>ReadOnlyPaths=</varname> and related calls, see above.
+ Note that limited automatic module loading due to user configuration or kernel
+ mapping tables might still happen as side effect of requested user operations,
+ both privileged and unprivileged. To disable module auto-load feature please see
+ <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ <constant>kernel.modules_disabled</constant> mechanism and
+ <filename>/proc/sys/kernel/modules_disabled</filename> documentation.
+ If turned on and if running in user mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant>
+ capability (e.g. setting <varname>User=</varname>), <varname>NoNewPrivileges=yes</varname>
+ is implied.
+ </para></listitem>
</varlistentry>
<varlistentry>
@@ -1104,7 +1198,8 @@
unit. Except for container managers no services should require write access to the control groups hierarchies;
it is hence recommended to turn this on for most services. For this setting the same restrictions regarding
mount propagation and privileges apply as for <varname>ReadOnlyPaths=</varname> and related calls, see
- above. Defaults to off.</para></listitem>
+ above. Defaults to off. If <varname>ProtectControlGroups=</varname> is set, <varname>MountAPIVFS=yes</varname> is
+ implied.</para></listitem>
</varlistentry>
<varlistentry>
@@ -1112,12 +1207,16 @@
<listitem><para>Takes a mount propagation flag: <option>shared</option>, <option>slave</option> or
<option>private</option>, which control whether mounts in the file system namespace set up for this unit's
- processes will receive or propagate mounts or unmounts. See <citerefentry
+ processes will receive or propagate mounts and unmounts. See <citerefentry
project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
details. Defaults to <option>shared</option>. Use <option>shared</option> to ensure that mounts and unmounts
- are propagated from the host to the container and vice versa. Use <option>slave</option> to run processes so
- that none of their mounts and unmounts will propagate to the host. Use <option>private</option> to also ensure
- that no mounts and unmounts from the host will propagate into the unit processes' namespace. Note that
+ are propagated from systemd's namespace to the service's namespace and vice versa. Use <option>slave</option>
+ to run processes so that none of their mounts and unmounts will propagate to the host. Use <option>private</option>
+ to also ensure that no mounts and unmounts from the host will propagate into the unit processes' namespace.
+ If this is set to <option>slave</option> or <option>private</option>, any mounts created by spawned processes
+ will be unmounted after the completion of the current command line of <varname>ExecStartPre=</varname>,
+ <varname>ExecStartPost=</varname>, <varname>ExecStart=</varname>,
+ and <varname>ExecStopPost=</varname>. Note that
<option>slave</option> means that file systems mounted on the host might stay mounted continuously in the
unit's namespace, and thus keep the device busy. Note that the file system namespace related options
(<varname>PrivateTmp=</varname>, <varname>PrivateDevices=</varname>, <varname>ProtectSystem=</varname>,
@@ -1234,22 +1333,16 @@
<varlistentry>
<term><varname>NoNewPrivileges=</varname></term>
- <listitem><para>Takes a boolean argument. If true, ensures that the service
- process and all its children can never gain new privileges. This option is more
- powerful than the respective secure bits flags (see above), as it also prohibits
- UID changes of any kind. This is the simplest and most effective way to ensure that
- a process and its children can never elevate privileges again. Defaults to false,
- but in the user manager instance certain settings force
- <varname>NoNewPrivileges=yes</varname>, ignoring the value of this setting.
- Those is the case when <varname>SystemCallFilter=</varname>,
- <varname>SystemCallArchitectures=</varname>,
- <varname>RestrictAddressFamilies=</varname>,
- <varname>PrivateDevices=</varname>,
- <varname>ProtectKernelTunables=</varname>,
- <varname>ProtectKernelModules=</varname>,
- <varname>MemoryDenyWriteExecute=</varname>, or
- <varname>RestrictRealtime=</varname> are specified.
- </para></listitem>
+ <listitem><para>Takes a boolean argument. If true, ensures that the service process and all its children can
+ never gain new privileges through <function>execve()</function> (e.g. via setuid or setgid bits, or filesystem
+ capabilities). This is the simplest and most effective way to ensure that a process and its children can never
+ elevate privileges again. Defaults to false, but certain settings force
+ <varname>NoNewPrivileges=yes</varname>, ignoring the value of this setting. This is the case when
+ <varname>SystemCallFilter=</varname>, <varname>SystemCallArchitectures=</varname>,
+ <varname>RestrictAddressFamilies=</varname>, <varname>RestrictNamespaces=</varname>,
+ <varname>PrivateDevices=</varname>, <varname>ProtectKernelTunables=</varname>,
+ <varname>ProtectKernelModules=</varname>, <varname>MemoryDenyWriteExecute=</varname>, or
+ <varname>RestrictRealtime=</varname> are specified.</para></listitem>
</varlistentry>
<varlistentry>
@@ -1270,6 +1363,11 @@
filter is reset, all prior assignments will have no effect. This does not affect commands prefixed with
<literal>+</literal>.</para>
+ <para>Note that on systems supporting multiple ABIs (such as x86/x86-64) it is recommended to turn off
+ alternative ABIs for services, so that they cannot be used to circumvent the restrictions of this
+ option. Specifically, it is recommended to combine this option with
+ <varname>SystemCallArchitectures=native</varname> or similar.</para>
+
<para>Note that strict system call filters may impact execution and error handling code paths of the service
invocation. Specifically, access to the <function>execve</function> system call is required for the execution
of the service binary — if it is blocked service invocation will necessarily fail. Also, if execution of the
@@ -1326,6 +1424,10 @@
<entry>Debugging, performance monitoring and tracing functionality (<citerefentry project='man-pages'><refentrytitle>ptrace</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>perf_event_open</refentrytitle><manvolnum>2</manvolnum></citerefentry> and related calls)</entry>
</row>
<row>
+ <entry>@file-system</entry>
+ <entry>File system operations: opening, creating files and directories for read and write, renaming and removing them, reading file properties, or creating hard and symbolic links.</entry>
+ </row>
+ <row>
<entry>@io-event</entry>
<entry>Event loop system calls (<citerefentry project='man-pages'><refentrytitle>poll</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>select</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>epoll</refentrytitle><manvolnum>7</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>eventfd</refentrytitle><manvolnum>2</manvolnum></citerefentry> and related calls)</entry>
</row>
@@ -1339,11 +1441,11 @@
</row>
<row>
<entry>@module</entry>
- <entry>Kernel module control (<citerefentry project='man-pages'><refentrytitle>init_module</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>delete_module</refentrytitle><manvolnum>2</manvolnum></citerefentry> and related calls)</entry>
+ <entry>Loading and unloading of kernel modules (<citerefentry project='man-pages'><refentrytitle>init_module</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>delete_module</refentrytitle><manvolnum>2</manvolnum></citerefentry> and related calls)</entry>
</row>
<row>
<entry>@mount</entry>
- <entry>File system mounting and unmounting (<citerefentry project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>chroot</refentrytitle><manvolnum>2</manvolnum></citerefentry>, and related calls)</entry>
+ <entry>Mounting and unmounting of file systems (<citerefentry project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>chroot</refentrytitle><manvolnum>2</manvolnum></citerefentry>, and related calls)</entry>
</row>
<row>
<entry>@network-io</entry>
@@ -1359,22 +1461,35 @@
</row>
<row>
<entry>@process</entry>
- <entry>Process control, execution, namespaces (<citerefentry project='man-pages'><refentrytitle>clone</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>kill</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>namespaces</refentrytitle><manvolnum>7</manvolnum></citerefentry>, …</entry>
+ <entry>Process control, execution, namespaceing operations (<citerefentry project='man-pages'><refentrytitle>clone</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>kill</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>namespaces</refentrytitle><manvolnum>7</manvolnum></citerefentry>, …</entry>
</row>
<row>
<entry>@raw-io</entry>
<entry>Raw I/O port access (<citerefentry project='man-pages'><refentrytitle>ioperm</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>iopl</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <function>pciconfig_read()</function>, …)</entry>
</row>
<row>
+ <entry>@reboot</entry>
+ <entry>System calls for rebooting and reboot preparation (<citerefentry project='man-pages'><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <function>kexec()</function>, …)</entry>
+ </row>
+ <row>
<entry>@resources</entry>
<entry>System calls for changing resource limits, memory and scheduling parameters (<citerefentry project='man-pages'><refentrytitle>setrlimit</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>setpriority</refentrytitle><manvolnum>2</manvolnum></citerefentry>, …)</entry>
</row>
+ <row>
+ <entry>@swap</entry>
+ <entry>System calls for enabling/disabling swap devices (<citerefentry project='man-pages'><refentrytitle>swapon</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>swapoff</refentrytitle><manvolnum>2</manvolnum></citerefentry>)</entry>
+ </row>
</tbody>
</tgroup>
</table>
- Note that as new system calls are added to the kernel, additional system calls might be added to the groups
- above, so the contents of the sets may change between systemd versions.</para>
+ Note, that as new system calls are added to the kernel, additional system calls might be
+ added to the groups above. Contents of the sets may also change between systemd
+ versions. In addition, the list of system calls depends on the kernel version and
+ architecture for which systemd was compiled. Use
+ <command>systemd-analyze syscall-filter</command> to list the actual list of system calls in
+ each filter.
+ </para>
<para>It is recommended to combine the file system namespacing related options with
<varname>SystemCallFilter=~@mount</varname>, in order to prohibit the unit's processes to undo the
@@ -1402,84 +1517,89 @@
<varlistentry>
<term><varname>SystemCallArchitectures=</varname></term>
- <listitem><para>Takes a space-separated list of architecture identifiers to
- include in the system call filter. The known architecture identifiers are the same
- as for <varname>ConditionArchitecture=</varname> described in
- <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- as well as <constant>x32</constant>, <constant>mips64-n32</constant>,
- <constant>mips64-le-n32</constant>, and the special identifier
- <constant>native</constant>. Only system calls of the specified architectures will
- be permitted to processes of this unit. This is an effective way to disable
- compatibility with non-native architectures for processes, for example to prohibit
- execution of 32-bit x86 binaries on 64-bit x86-64 systems. The special
- <constant>native</constant> identifier implicitly maps to the native architecture
- of the system (or more strictly: to the architecture the system manager is
- compiled for). If running in user mode, or in system mode, but without the
- <constant>CAP_SYS_ADMIN</constant> capability (e.g. setting
- <varname>User=nobody</varname>), <varname>NoNewPrivileges=yes</varname> is
- implied. Note that setting this option to a non-empty list implies that
- <constant>native</constant> is included too. By default, this option is set to the
- empty list, i.e. no architecture system call filtering is applied.
- </para></listitem>
+ <listitem><para>Takes a space-separated list of architecture identifiers to include in the system call
+ filter. The known architecture identifiers are the same as for <varname>ConditionArchitecture=</varname>
+ described in <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ as well as <constant>x32</constant>, <constant>mips64-n32</constant>, <constant>mips64-le-n32</constant>, and
+ the special identifier <constant>native</constant>. Only system calls of the specified architectures will be
+ permitted to processes of this unit. This is an effective way to disable compatibility with non-native
+ architectures for processes, for example to prohibit execution of 32-bit x86 binaries on 64-bit x86-64
+ systems. The special <constant>native</constant> identifier implicitly maps to the native architecture of the
+ system (or more strictly: to the architecture the system manager is compiled for). If running in user mode, or
+ in system mode, but without the <constant>CAP_SYS_ADMIN</constant> capability (e.g. setting
+ <varname>User=nobody</varname>), <varname>NoNewPrivileges=yes</varname> is implied. Note that setting this
+ option to a non-empty list implies that <constant>native</constant> is included too. By default, this option is
+ set to the empty list, i.e. no system call architecture filtering is applied.</para>
+
+ <para>Note that system call filtering is not equally effective on all architectures. For example, on x86
+ filtering of network socket-related calls is not possible, due to ABI limitations — a limitation that x86-64
+ does not have, however. On systems supporting multiple ABIs at the same time — such as x86/x86-64 — it is hence
+ recommended to limit the set of permitted system call architectures so that secondary ABIs may not be used to
+ circumvent the restrictions applied to the native ABI of the system. In particular, setting
+ <varname>SystemCallFilter=native</varname> is a good choice for disabling non-native ABIs.</para>
+
+ <para>System call architectures may also be restricted system-wide via the
+ <varname>SystemCallArchitectures=</varname> option in the global configuration. See
+ <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
+ details.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>RestrictAddressFamilies=</varname></term>
- <listitem><para>Restricts the set of socket address families
- accessible to the processes of this unit. Takes a
- space-separated list of address family names to whitelist,
- such as
- <constant>AF_UNIX</constant>,
- <constant>AF_INET</constant> or
- <constant>AF_INET6</constant>. When
- prefixed with <constant>~</constant> the listed address
- families will be applied as blacklist, otherwise as whitelist.
- Note that this restricts access to the
- <citerefentry project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>2</manvolnum></citerefentry>
- system call only. Sockets passed into the process by other
- means (for example, by using socket activation with socket
- units, see
- <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>)
- are unaffected. Also, sockets created with
- <function>socketpair()</function> (which creates connected
- AF_UNIX sockets only) are unaffected. Note that this option
- has no effect on 32-bit x86 and is ignored (but works
- correctly on x86-64). If running in user mode, or in system
- mode, but without the <constant>CAP_SYS_ADMIN</constant>
- capability (e.g. setting <varname>User=nobody</varname>),
- <varname>NoNewPrivileges=yes</varname> is implied. By
- default, no restriction applies, all address families are
- accessible to processes. If assigned the empty string, any
- previous list changes are undone.</para>
-
- <para>Use this option to limit exposure of processes to remote
- systems, in particular via exotic network protocols. Note that
- in most cases, the local <constant>AF_UNIX</constant> address
- family should be included in the configured whitelist as it is
- frequently used for local communication, including for
+ <listitem><para>Restricts the set of socket address families accessible to the processes of this unit. Takes a
+ space-separated list of address family names to whitelist, such as <constant>AF_UNIX</constant>,
+ <constant>AF_INET</constant> or <constant>AF_INET6</constant>. When prefixed with <constant>~</constant> the
+ listed address families will be applied as blacklist, otherwise as whitelist. Note that this restricts access
+ to the <citerefentry
+ project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>2</manvolnum></citerefentry> system call
+ only. Sockets passed into the process by other means (for example, by using socket activation with socket
+ units, see <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>)
+ are unaffected. Also, sockets created with <function>socketpair()</function> (which creates connected AF_UNIX
+ sockets only) are unaffected. Note that this option has no effect on 32-bit x86, s390, s390x, mips, mips-le,
+ ppc, ppc-le, pcc64, ppc64-le and is ignored (but works correctly on other ABIs, including x86-64). Note that on
+ systems supporting multiple ABIs (such as x86/x86-64) it is recommended to turn off alternative ABIs for
+ services, so that they cannot be used to circumvent the restrictions of this option. Specifically, it is
+ recommended to combine this option with <varname>SystemCallArchitectures=native</varname> or similar. If
+ running in user mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant> capability
+ (e.g. setting <varname>User=nobody</varname>), <varname>NoNewPrivileges=yes</varname> is implied. By default,
+ no restrictions apply, all address families are accessible to processes. If assigned the empty string, any
+ previous address familiy restriction changes are undone. This setting does not affect commands prefixed with
+ <literal>+</literal>.</para>
+
+ <para>Use this option to limit exposure of processes to remote access, in particular via exotic and sensitive
+ network protocols, such as <constant>AF_PACKET</constant>. Note that in most cases, the local
+ <constant>AF_UNIX</constant> address family should be included in the configured whitelist as it is frequently
+ used for local communication, including for
<citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>2</manvolnum></citerefentry>
- logging. This does not affect commands prefixed with <literal>+</literal>.</para></listitem>
+ logging.</para></listitem>
</varlistentry>
<varlistentry>
- <term><varname>ProtectKernelModules=</varname></term>
+ <term><varname>RestrictNamespaces=</varname></term>
- <listitem><para>Takes a boolean argument. If true, explicit module loading will
- be denied. This allows to turn off module load and unload operations on modular
- kernels. It is recommended to turn this on for most services that do not need special
- file systems or extra kernel modules to work. Default to off. Enabling this option
- removes <constant>CAP_SYS_MODULE</constant> from the capability bounding set for
- the unit, and installs a system call filter to block module system calls,
- also <filename>/usr/lib/modules</filename> is made inaccessible. For this
- setting the same restrictions regarding mount propagation and privileges
- apply as for <varname>ReadOnlyPaths=</varname> and related calls, see above.
- Note that limited automatic module loading due to user configuration or kernel
- mapping tables might still happen as side effect of requested user operations,
- both privileged and unprivileged. To disable module auto-load feature please see
- <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- <constant>kernel.modules_disabled</constant> mechanism and
- <filename>/proc/sys/kernel/modules_disabled</filename> documentation.</para></listitem>
+ <listitem><para>Restricts access to Linux namespace functionality for the processes of this unit. For details
+ about Linux namespaces, see
+ <citerefentry><refentrytitle>namespaces</refentrytitle><manvolnum>7</manvolnum></citerefentry>. Either takes a
+ boolean argument, or a space-separated list of namespace type identifiers. If false (the default), no
+ restrictions on namespace creation and switching are made. If true, access to any kind of namespacing is
+ prohibited. Otherwise, a space-separated list of namespace type identifiers must be specified, consisting of
+ any combination of: <constant>cgroup</constant>, <constant>ipc</constant>, <constant>net</constant>,
+ <constant>mnt</constant>, <constant>pid</constant>, <constant>user</constant> and <constant>uts</constant>. Any
+ namespace type listed is made accessible to the unit's processes, access to namespace types not listed is
+ prohibited (whitelisting). By prepending the list with a single tilda character (<literal>~</literal>) the
+ effect may be inverted: only the listed namespace types will be made inaccessible, all unlisted ones are
+ permitted (blacklisting). If the empty string is assigned, the default namespace restrictions are applied,
+ which is equivalent to false. Internally, this setting limits access to the
+ <citerefentry><refentrytitle>unshare</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>clone</refentrytitle><manvolnum>2</manvolnum></citerefentry> and
+ <citerefentry><refentrytitle>setns</refentrytitle><manvolnum>2</manvolnum></citerefentry> system calls, taking
+ the specified flags parameters into account. Note that — if this option is used — in addition to restricting
+ creation and switching of the specified types of namespaces (or all of them, if true) access to the
+ <function>setns()</function> system call with a zero flags parameter is prohibited. This setting is only
+ supported on x86, x86-64, s390 and s390x, and enforces no restrictions on other architectures. If running in user
+ mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant> capability (e.g. setting
+ <varname>User=</varname>), <varname>NoNewPrivileges=yes</varname> is implied. </para></listitem>
</varlistentry>
<varlistentry>
@@ -1528,19 +1648,23 @@
<term><varname>MemoryDenyWriteExecute=</varname></term>
<listitem><para>Takes a boolean argument. If set, attempts to create memory mappings that are writable and
- executable at the same time, or to change existing memory mappings to become executable, or mapping shared memory
- segments as executable are prohibited.
- Specifically, a system call filter is added that rejects
- <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry>
- system calls with both <constant>PROT_EXEC</constant> and <constant>PROT_WRITE</constant> set,
- <citerefentry><refentrytitle>mprotect</refentrytitle><manvolnum>2</manvolnum></citerefentry>
- system calls with <constant>PROT_EXEC</constant> set and
- <citerefentry><refentrytitle>shmat</refentrytitle><manvolnum>2</manvolnum></citerefentry>
- system calls with <constant>SHM_EXEC</constant> set. Note that this option is incompatible with programs
- that generate program code dynamically at runtime, such as JIT execution engines, or programs compiled making
- use of the code "trampoline" feature of various C compilers. This option improves service security, as it makes
- harder for software exploits to change running code dynamically.
- </para></listitem>
+ executable at the same time, or to change existing memory mappings to become executable, or mapping shared
+ memory segments as executable are prohibited. Specifically, a system call filter is added that rejects
+ <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry> system calls with both
+ <constant>PROT_EXEC</constant> and <constant>PROT_WRITE</constant> set,
+ <citerefentry><refentrytitle>mprotect</refentrytitle><manvolnum>2</manvolnum></citerefentry> system calls with
+ <constant>PROT_EXEC</constant> set and
+ <citerefentry><refentrytitle>shmat</refentrytitle><manvolnum>2</manvolnum></citerefentry> system calls with
+ <constant>SHM_EXEC</constant> set. Note that this option is incompatible with programs and libraries that
+ generate program code dynamically at runtime, including JIT execution engines, executable stacks, and code
+ "trampoline" feature of various C compilers. This option improves service security, as it makes harder for
+ software exploits to change running code dynamically. Note that this feature is fully available on x86-64, and
+ partially on x86. Specifically, the <function>shmat()</function> protection is not available on x86. Note that
+ on systems supporting multiple ABIs (such as x86/x86-64) it is recommended to turn off alternative ABIs for
+ services, so that they cannot be used to circumvent the restrictions of this option. Specifically, it is
+ recommended to combine this option with <varname>SystemCallArchitectures=native</varname> or similar. If
+ running in user mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant> capability
+ (e.g. setting <varname>User=</varname>), <varname>NoNewPrivileges=yes</varname> is implied. </para></listitem>
</varlistentry>
<varlistentry>
@@ -1550,7 +1674,10 @@
the unit are refused. This restricts access to realtime task scheduling policies such as
<constant>SCHED_FIFO</constant>, <constant>SCHED_RR</constant> or <constant>SCHED_DEADLINE</constant>. See
<citerefentry project='man-pages'><refentrytitle>sched</refentrytitle><manvolnum>7</manvolnum></citerefentry> for details about
- these scheduling policies. Realtime scheduling policies may be used to monopolize CPU time for longer periods
+ these scheduling policies. If running in user mode, or in system mode, but
+ without the <constant>CAP_SYS_ADMIN</constant> capability
+ (e.g. setting <varname>User=</varname>), <varname>NoNewPrivileges=yes</varname>
+ is implied. Realtime scheduling policies may be used to monopolize CPU time for longer periods
of time, and may hence be used to lock up or otherwise trigger Denial-of-Service situations on the system. It
is hence recommended to restrict access to realtime scheduling to the few programs that actually require
them. Defaults to off.</para></listitem>
@@ -1718,14 +1845,15 @@
<listitem><para>Only defined for the service unit type, this environment variable is passed to all
<varname>ExecStop=</varname> and <varname>ExecStopPost=</varname> processes, and encodes the service
- "result". Currently, the following values are defined: <literal>timeout</literal> (in case of an operation
- timeout), <literal>exit-code</literal> (if a service process exited with a non-zero exit code; see
- <varname>$EXIT_CODE</varname> below for the actual exit code returned), <literal>signal</literal> (if a
- service process was terminated abnormally by a signal; see <varname>$EXIT_CODE</varname> below for the actual
- signal used for the termination), <literal>core-dump</literal> (if a service process terminated abnormally and
- dumped core), <literal>watchdog</literal> (if the watchdog keep-alive ping was enabled for the service but it
- missed the deadline), or <literal>resources</literal> (a catch-all condition in case a system operation
- failed).</para>
+ "result". Currently, the following values are defined: <literal>protocol</literal> (in case of a protocol
+ violation; if a service did not take the steps required by its unit configuration), <literal>timeout</literal>
+ (in case of an operation timeout), <literal>exit-code</literal> (if a service process exited with a non-zero
+ exit code; see <varname>$EXIT_CODE</varname> below for the actual exit code returned), <literal>signal</literal>
+ (if a service process was terminated abnormally by a signal; see <varname>$EXIT_CODE</varname> below for the
+ actual signal used for the termination), <literal>core-dump</literal> (if a service process terminated
+ abnormally and dumped core), <literal>watchdog</literal> (if the watchdog keep-alive ping was enabled for the
+ service but it missed the deadline), or <literal>resources</literal> (a catch-all condition in case a system
+ operation failed).</para>
<para>This environment variable is useful to monitor failure or successful termination of a service. Even
though this variable is available in both <varname>ExecStop=</varname> and <varname>ExecStopPost=</varname>, it
@@ -1752,23 +1880,32 @@
<title>Summary of possible service result variable values</title>
<tgroup cols='3'>
<colspec colname='result' />
- <colspec colname='status' />
<colspec colname='code' />
+ <colspec colname='status' />
<thead>
<row>
<entry><varname>$SERVICE_RESULT</varname></entry>
- <entry><varname>$EXIT_STATUS</varname></entry>
<entry><varname>$EXIT_CODE</varname></entry>
+ <entry><varname>$EXIT_STATUS</varname></entry>
</row>
</thead>
<tbody>
<row>
+ <entry morerows="1" valign="top"><literal>protocol</literal></entry>
+ <entry valign="top">not set</entry>
+ <entry>not set</entry>
+ </row>
+ <row>
+ <entry><literal>exited</literal></entry>
+ <entry><literal>0</literal></entry>
+ </row>
+
+ <row>
<entry morerows="1" valign="top"><literal>timeout</literal></entry>
<entry valign="top"><literal>killed</literal></entry>
<entry><literal>TERM</literal>, <literal>KILL</literal></entry>
</row>
-
<row>
<entry valign="top"><literal>exited</literal></entry>
<entry><literal>0</literal>, <literal>1</literal>, <literal>2</literal>, <literal
@@ -1844,6 +1981,7 @@
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-analyze</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
diff --git a/man/systemd.generator.xml b/man/systemd.generator.xml
index b268104c9d..fb0f0c4da8 100644
--- a/man/systemd.generator.xml
+++ b/man/systemd.generator.xml
@@ -342,7 +342,8 @@ find $dir</programlisting>
<citerefentry><refentrytitle>systemd-system-update-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-sysv-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd.environment-generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>
diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml
index 494f97aad1..747d985aa1 100644
--- a/man/systemd.journal-fields.xml
+++ b/man/systemd.journal-fields.xml
@@ -243,6 +243,16 @@
</varlistentry>
<varlistentry>
+ <term><varname>_SYSTEMD_INVOCATION_ID=</varname></term>
+ <listitem>
+ <para>The invocation ID for the runtime cycle of the unit
+ the message was generated in, as available to processes
+ of the unit in <varname>$INVOCATION_ID</varname> (see
+ <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>_HOSTNAME=</varname></term>
<listitem>
<para>The name of the originating host.</para>
@@ -457,9 +467,9 @@
<para>During serialization into external formats, such as the
<ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/export">Journal
+ url="https://www.freedesktop.org/wiki/Software/systemd/export">Journal
Export Format</ulink> or the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/json">Journal
+ url="https://www.freedesktop.org/wiki/Software/systemd/json">Journal
JSON Format</ulink>, the addresses of journal entries are
serialized into fields prefixed with double underscores. Note that
these are not proper fields when stored in the journal but for
diff --git a/man/systemd.link.xml b/man/systemd.link.xml
index 8edbe758d9..023e24eeb3 100644
--- a/man/systemd.link.xml
+++ b/man/systemd.link.xml
@@ -359,6 +359,20 @@
</listitem>
</varlistentry>
<varlistentry>
+ <term><varname>AutoNegotiation=</varname></term>
+ <listitem>
+ <para>Enables or disables automatic negotiation of transmission parameters.
+ Autonegotiation is a procedure by which two connected ethernet devices choose
+ common transmission parameters, such as speed, duplex mode, and flow control.
+ Takes a boolean value. Unset by default, which means that the kernel default
+ will be used.</para>
+
+ <para>Note that if autonegotiation is enabled, speed and duplex settings are
+ read-only. If autonegotation is disabled, speed and duplex settings are writable
+ if the driver supports multiple link modes.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><varname>WakeOnLan=</varname></term>
<listitem>
<para>The Wake-on-LAN policy to set for the device. The
diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml
index b0f156f6df..4a404fb424 100644
--- a/man/systemd.mount.xml
+++ b/man/systemd.mount.xml
@@ -104,7 +104,7 @@
for kernel-to-userspace and userspace-to-userspace interfaces. Some
of them may not be changed via mount units, and cannot be
disabled. For a longer discussion see <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems">API
+ url="https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems">API
File Systems</ulink>.</para>
</refsect1>
@@ -194,6 +194,25 @@
</varlistentry>
<varlistentry>
+ <term><option>x-systemd.before=</option></term>
+ <term><option>x-systemd.after=</option></term>
+
+ <listitem><para>Configures a <varname>Before=</varname>
+ dependency or <varname>After=</varname> between the created
+ mount unit and another systemd unit, such as a mount unit.
+ The argument should be a unit name or an absolute path
+ to a mount point. This option may be specified more than once.
+ This option is particularly useful for mount point declarations
+ with <option>nofail</option> option that are mounted
+ asynchronously but need to be mounted before or after some unit
+ start, for example, before <filename>local-fs.target</filename>
+ unit.
+ See <varname>Before=</varname> and <varname>After=</varname> in
+ <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for details.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>x-systemd.requires-mounts-for=</option></term>
<listitem><para>Configures a
@@ -206,6 +225,19 @@
</varlistentry>
<varlistentry>
+ <term><option>x-systemd.device-bound</option></term>
+
+ <listitem><para>The block device backed file system will be upgraded
+ to <varname>BindsTo=</varname> dependency. This option is only useful
+ when mounting file systems manually with
+ <citerefentry><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ as the default dependency in this case is <varname>Requires=</varname>.
+ This option is already implied by entries in <filename>/etc/fstab</filename>
+ or by mount units.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>x-systemd.automount</option></term>
<listitem><para>An automount unit will be created for the file
@@ -241,6 +273,25 @@
</varlistentry>
<varlistentry>
+ <term><option>x-systemd.mount-timeout=</option></term>
+
+ <listitem><para>Configure how long systemd should wait for the
+ mount command to finish before giving up on an entry from
+ <filename>/etc/fstab</filename>. Specify a time in seconds or
+ explicitly append a unit such as <literal>s</literal>,
+ <literal>min</literal>, <literal>h</literal>,
+ <literal>ms</literal>.</para>
+
+ <para>Note that this option can only be used in
+ <filename>/etc/fstab</filename>, and will be
+ ignored when part of the <varname>Options=</varname>
+ setting in a unit file.</para>
+
+ <para>See <varname>TimeoutSec=</varname> below for
+ details.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><option>noauto</option></term>
<term><option>auto</option></term>
@@ -305,14 +356,12 @@
<varlistentry>
<term><varname>What=</varname></term>
- <listitem><para>Takes an absolute path of a device node, file
- or other resource to mount. See
- <citerefentry project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>
- for details. If this refers to a device node, a dependency on
- the respective device unit is automatically created. (See
- <citerefentry><refentrytitle>systemd.device</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- for more information.) This option is
- mandatory.</para></listitem>
+ <listitem><para>Takes an absolute path of a device node, file or other resource to mount. See <citerefentry
+ project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry> for details. If
+ this refers to a device node, a dependency on the respective device unit is automatically created. (See
+ <citerefentry><refentrytitle>systemd.device</refentrytitle><manvolnum>5</manvolnum></citerefentry> for more
+ information.) This option is mandatory. Note that the usual specifier expansion is applied to this setting,
+ literal percent characters should hence be written as <literal>%%</literal>.</para></listitem>
</varlistentry>
<varlistentry>
@@ -334,9 +383,9 @@
<varlistentry>
<term><varname>Options=</varname></term>
- <listitem><para>Mount options to use when mounting. This takes
- a comma-separated list of options. This setting is
- optional.</para></listitem>
+ <listitem><para>Mount options to use when mounting. This takes a comma-separated list of options. This setting
+ is optional. Note that the usual specifier expansion is applied to this setting, literal percent characters
+ should hence be written as <literal>%%</literal>.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml
index ffb66e735b..39e69480ec 100644
--- a/man/systemd.netdev.xml
+++ b/man/systemd.netdev.xml
@@ -469,12 +469,18 @@
</listitem>
</varlistentry>
<varlistentry>
- <term><varname>Group=</varname></term>
+ <term><varname>Remote=</varname></term>
<listitem>
- <para>An assigned multicast group IP address.</para>
+ <para>Configures destination multicast group IP address.</para>
</listitem>
</varlistentry>
<varlistentry>
+ <term><varname>Local=</varname></term>
+ <listitem>
+ <para>Configures local IP address.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><varname>TOS=</varname></term>
<listitem>
<para>The Type Of Service byte value for a vxlan interface.</para>
@@ -510,9 +516,13 @@
</listitem>
</varlistentry>
<varlistentry>
- <term><varname>ARPProxy=</varname></term>
+ <term><varname>ReduceARPProxy=</varname></term>
<listitem>
- <para>A boolean. When true, enables ARP proxying.</para>
+ <para>A boolean. When true, bridge-connected VXLAN tunnel
+ endpoint answers ARP requests from the local bridge on behalf
+ of remote Distributed Overlay Virtual Ethernet
+ <ulink url="https://en.wikipedia.org/wiki/Distributed_Overlay_Virtual_Ethernet">
+ (DVOE)</ulink> clients. Defaults to false.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -1068,6 +1078,33 @@
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>ActiveSlave=</varname></term>
+ <listitem>
+ <para>A boolean. Specifies the new active slave. The <literal>ActiveSlave=</literal>
+ option is only valid for following modes:
+ <literal>active-backup</literal>,
+ <literal>balance-alb</literal> and
+ <literal>balance-tlb</literal>. Defaults to false.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>PrimarySlave=</varname></term>
+ <listitem>
+ <para>A boolean. Specifies which slave is the primary device. The specified
+ device will always be the active slave while it is available. Only when the
+ primary is off-line will alternate devices be used. This is useful when
+ one slave is preferred over another, e.g. when one slave has higher throughput
+ than another. The <literal>PrimarySlave=</literal> option is only valid for
+ following modes:
+ <literal>active-backup</literal>,
+ <literal>balance-alb</literal> and
+ <literal>balance-tlb</literal>. Defaults to false.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
<para>For more detail information see
@@ -1199,6 +1236,15 @@ Kind=vrf
[VRF]
TableId=42</programlisting>
</example>
+
+ <example>
+ <title>/etc/systemd/network/25-macvtap.netdev</title>
+ <para>Create a MacVTap device.</para>
+ <programlisting>[NetDev]
+Name=macvtap-test
+Kind=macvtap
+ </programlisting>
+ </example>
</refsect1>
<refsect1>
<title>See Also</title>
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 2fb4907634..aaa7b0968d 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -123,7 +123,10 @@
<listitem>
<para>A whitespace-separated list of shell-style globs
matching the persistent path, as exposed by the udev
- property <literal>ID_PATH</literal>.</para>
+ property <literal>ID_PATH</literal>. If the list is
+ prefixed with a "!", the test is inverted; i.e. it is
+ true when <literal>ID_PATH</literal> does not match any
+ item in the list.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -134,7 +137,8 @@
exposed by the udev property <literal>DRIVER</literal>
of its parent device, or if that is not set the driver
as exposed by <literal>ethtool -i</literal> of the
- device itself.</para>
+ device itself. If the list is prefixed with a "!", the
+ test is inverted.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -142,7 +146,8 @@
<listitem>
<para>A whitespace-separated list of shell-style globs
matching the device type, as exposed by the udev property
- <literal>DEVTYPE</literal>.</para>
+ <literal>DEVTYPE</literal>. If the list is prefixed with
+ a "!", the test is inverted.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -150,7 +155,8 @@
<listitem>
<para>A whitespace-separated list of shell-style globs
matching the device name, as exposed by the udev property
- <literal>INTERFACE</literal>.</para>
+ <literal>INTERFACE</literal>. If the list is prefixed
+ with a "!", the test is inverted.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -232,6 +238,18 @@
the network otherwise.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>Unmanaged=</varname></term>
+ <listitem>
+ <para>A boolean. When <literal>yes</literal>, no attempts are
+ made to bring up or configure matching links, equivalent to
+ when there are no matching network files. Defaults to
+ <literal>no</literal>.</para>
+ <para>This is useful for preventing later matching network
+ files from interfering with certain interfaces that are fully
+ controlled by other applications.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
@@ -585,8 +603,8 @@
</para></listitem>
</varlistentry>
<varlistentry>
- <term><varname>ProxyARP=</varname></term>
- <listitem><para>A boolean. Configures proxy ARP. Proxy ARP is the technique in which one host,
+ <term><varname>IPv4ProxyARP=</varname></term>
+ <listitem><para>A boolean. Configures proxy ARP for IPv4. Proxy ARP is the technique in which one host,
usually a router, answers ARP requests intended for another machine. By "faking" its identity,
the router accepts responsibility for routing packets to the "real" destination. (see <ulink
url="https://tools.ietf.org/html/rfc1027">RFC 1027</ulink>.
@@ -594,49 +612,78 @@
</para></listitem>
</varlistentry>
<varlistentry>
+ <term><varname>IPv6ProxyNDPAddress=</varname></term>
+ <listitem><para>An IPv6 address, for which Neighbour Advertisement
+ messages will be proxied.
+ Proxy NDP (Neighbor Discovery Protocol) is a technique for IPv6 to
+ allow routing of addresses to a different destination when peers expect them
+ to be present on a certain physical link.
+ In this case a router answers Neighbour Advertisement messages intended for
+ another machine by offering its own MAC address as destination.
+ Unlike proxy ARP for IPv4, is not enabled globally, but will only send Neighbour
+ Advertisement messages for addresses in the IPv6 neighbor proxy table,
+ which can also be shown by <command>ip -6 neighbour show proxy</command>
+ This option may be specified more than once. systemd-networkd will control the
+ per-interface `proxy_ndp` switch for each configured interface, depending on whether
+ there are <option>IPv6ProxyNDPAddress=</option> entries configured and add these to
+ the kernels IPv6 neighbor proxy table.
+ Defaults to unset.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
<term><varname>Bridge=</varname></term>
<listitem>
- <para>The name of the bridge to add the link to.</para>
+ <para>The name of the bridge to add the link to. See
+ <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+ </para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Bond=</varname></term>
<listitem>
- <para>The name of the bond to add the link to.</para>
+ <para>The name of the bond to add the link to. See
+ <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+ </para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>VRF=</varname></term>
<listitem>
- <para>The name of the VRF to add the link to.</para>
+ <para>The name of the VRF to add the link to. See
+ <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+ </para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>VLAN=</varname></term>
<listitem>
- <para>The name of a VLAN to create on the link. This
- option may be specified more than once.</para>
+ <para>The name of a VLAN to create on the link. See
+ <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+ This option may be specified more than once.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>MACVLAN=</varname></term>
<listitem>
- <para>The name of a MACVLAN to create on the link. This
- option may be specified more than once.</para>
+ <para>The name of a MACVLAN to create on the link. See
+ <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+ This option may be specified more than once.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>VXLAN=</varname></term>
<listitem>
- <para>The name of a VXLAN to create on the link. This
- option may be specified more than once.</para>
+ <para>The name of a VXLAN to create on the link. See
+ <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+ This option may be specified more than once.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Tunnel=</varname></term>
<listitem>
- <para>The name of a Tunnel to create on the link. This
- option may be specified more than once.</para>
+ <para>The name of a Tunnel to create on the link. See
+ <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+ This option may be specified more than once.</para>
</listitem>
</varlistentry>
</variablelist>
@@ -890,9 +937,11 @@
<varlistentry>
<term><varname>UseRoutes=</varname></term>
<listitem>
- <para>When true (the default), the static routes will be
- requested from the DHCP server and added to the routing
- table with a metric of 1024.</para>
+ <para>When true (the default), the static routes will be requested from the DHCP server and added to the
+ routing table with a metric of 1024, and a scope of "global", "link" or "host", depending on the route's
+ destination and gateway. If the destination is on the local host, e.g., 127.x.x.x, or the same as the
+ link's own address, the scope will be set to "host". Otherwise if the gateway is null (a direct route), a
+ "link" scope will be used. For anything else, scope defaults to "global".</para>
</listitem>
</varlistentry>
@@ -984,6 +1033,13 @@
</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><varname>ListenPort=</varname></term>
+ <listitem>
+ <para>Allow setting custom port for the DHCP client to listen on.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
@@ -1268,53 +1324,75 @@
</refsect1>
<refsect1>
- <title>Example</title>
+ <title>Examples</title>
<example>
- <title>/etc/systemd/network/50-static.network</title>
+ <title>Static network configuration</title>
- <programlisting>[Match]
+ <programlisting># /etc/systemd/network/50-static.network
+[Match]
Name=enp2s0
[Network]
Address=192.168.0.15/24
Gateway=192.168.0.1</programlisting>
+
+ <para>This brings interface <literal>enp2s0</literal> up with a static address. The
+ specified gateway will be used for a default route.</para>
</example>
<example>
- <title>/etc/systemd/network/80-dhcp.network</title>
+ <title>DHCP on ethernet links</title>
- <programlisting>[Match]
+ <programlisting># /etc/systemd/network/80-dhcp.network
+[Match]
Name=en*
[Network]
DHCP=yes</programlisting>
+
+ <para>This will enable DHCPv4 and DHCPv6 on all interfaces with names starting with
+ <literal>en</literal> (i.e. ethernet interfaces).</para>
</example>
<example>
- <title>/etc/systemd/network/25-bridge-static.network</title>
+ <title>A bridge with two enslaved links</title>
- <programlisting>[Match]
+ <programlisting># /etc/systemd/network/25-bridge-static.network
+[Match]
Name=bridge0
[Network]
Address=192.168.0.15/24
Gateway=192.168.0.1
DNS=192.168.0.1</programlisting>
- </example>
- <example>
- <title>/etc/systemd/network/25-bridge-slave-interface.network</title>
-
- <programlisting>[Match]
+ <programlisting># /etc/systemd/network/25-bridge-slave-interface-1.network
+[Match]
Name=enp2s0
[Network]
Bridge=bridge0</programlisting>
+
+ <programlisting># /etc/systemd/network/25-bridge-slave-interface-2.network
+[Match]
+Name=wlp3s0
+
+[Network]
+Bridge=bridge0</programlisting>
+
+ <para>This creates a bridge and attaches devices <literal>enp2s0</literal> and
+ <literal>wlp3s0</literal> to it. The bridge will have the specified static address
+ and network assigned, and a default route via the specified gateway will be
+ added. The specified DNS server will be added to the global list of DNS resolvers.
+ </para>
</example>
+
<example>
- <title>/etc/systemd/network/25-bridge-slave-interface-vlan.network</title>
+ <title></title>
- <programlisting>[Match]
+ <programlisting>
+# /etc/systemd/network/20-bridge-slave-interface-vlan.network
+[Match]
Name=enp2s0
[Network]
@@ -1330,69 +1408,121 @@ VLAN=100-200
[BridgeVLAN]
EgressUntagged=300-400</programlisting>
+
+ <para>This overrides the configuration specified in the previous example for the
+ interface <literal>enp2s0</literal>, and enables VLAN on that bridge port. VLAN IDs
+ 1-32, 42, 100-400 will be allowed. Packets tagged with VLAN IDs 42, 300-400 will be
+ untagged when they leave on this interface. Untagged packets which arrive on this
+ interface will be assigned VLAN ID 42.</para>
</example>
+
<example>
- <title>/etc/systemd/network/25-ipip.network</title>
+ <title>Various tunnels</title>
- <programlisting>[Match]
-Name=em1
+ <programlisting>/etc/systemd/network/25-tunnels.network
+[Match]
+Name=ens1
[Network]
-Tunnel=ipip-tun</programlisting>
+Tunnel=ipip-tun
+Tunnel=sit-tun
+Tunnel=gre-tun
+Tunnel=vti-tun
+ </programlisting>
+
+ <programlisting>/etc/systemd/network/25-tunnel-ipip.netdev
+[NetDev]
+Name=ipip-tun
+Kind=ipip
+ </programlisting>
+
+ <programlisting>/etc/systemd/network/25-tunnel-sit.netdev
+[NetDev]
+Name=sit-tun
+Kind=sit
+ </programlisting>
+
+ <programlisting>/etc/systemd/network/25-tunnel-gre.netdev
+[NetDev]
+Name=gre-tun
+Kind=gre
+ </programlisting>
+
+ <programlisting>/etc/systemd/network/25-tunnel-vti.netdev
+[NetDev]
+Name=vti-tun
+Kind=vti
+ </programlisting>
+
+ <para>This will bring interface <literal>ens1</literal> up and create an IPIP tunnel,
+ a SIT tunnel, a GRE tunnel, and a VTI tunnel using it.</para>
</example>
<example>
- <title>/etc/systemd/network/25-sit.network</title>
+ <title>A bond device</title>
- <programlisting>[Match]
-Name=em1
+ <programlisting># /etc/systemd/network/30-bond1.network
+[Match]
+Name=bond1
[Network]
-Tunnel=sit-tun</programlisting>
- </example>
+DHCP=ipv6
+</programlisting>
- <example>
- <title>/etc/systemd/network/25-gre.network</title>
+ <programlisting># /etc/systemd/network/30-bond1.netdev
+[NetDev]
+Name=bond1
+Kind=bond
+</programlisting>
- <programlisting>[Match]
-Name=em1
+ <programlisting># /etc/systemd/network/30-bond1-dev1.network
+[Match]
+MACAddress=52:54:00:e9:64:41
[Network]
-Tunnel=gre-tun</programlisting>
- </example>
-
- <example>
- <title>/etc/systemd/network/25-vti.network</title>
+Bond=bond1
+</programlisting>
- <programlisting>[Match]
-Name=em1
+ <programlisting># /etc/systemd/network/30-bond1-dev2.network
+[Match]
+MACAddress=52:54:00:e9:64:42
[Network]
-Tunnel=vti-tun</programlisting>
+Bond=bond1
+</programlisting>
+
+ <para>This will create a bond device <literal>bond1</literal> and enslave the two
+ devices with MAC addresses 52:54:00:e9:64:41 and 52:54:00:e9:64:42 to it. IPv6 DHCP
+ will be used to acquire an address.</para>
</example>
<example>
- <title>/etc/systemd/network/25-bond.network</title>
-
- <programlisting>[Match]
+ <title>Virtual Routing and Forwarding (VRF)</title>
+ <para>Add the <literal>bond1</literal> interface to the VRF master interface
+ <literal>vrf1</literal>. This will redirect routes generated on this interface to be
+ within the routing table defined during VRF creation. Traffic won't be redirected
+ towards the VRFs routing table unless specific ip-rules are added.</para>
+ <programlisting># /etc/systemd/network/25-vrf.network
+[Match]
Name=bond1
[Network]
-DHCP=yes
+VRF=vrf1
</programlisting>
</example>
<example>
- <title>/etc/systemd/network/25-vrf.network</title>
- <para>Add the bond1 interface to the VRF master interface vrf-test. This will redirect routes generated on this interface to be within the routing table defined during VRF creation. Traffic won't be redirected towards the VRFs routing table unless specific ip-rules are added.</para>
- <programlisting>[Match]
-Name=bond1
+ <title>MacVTap</title>
+ <para>This brings up a network interface <literal>macvtap-test</literal>
+ and attaches it to <literal>enp0s25</literal>.</para>
+ <programlisting># /lib/systemd/network/25-macvtap.network
+[Match]
+Name=enp0s25
[Network]
-VRF=vrf-test
+MACVTAP=macvtap-test
</programlisting>
</example>
-
</refsect1>
<refsect1>
diff --git a/man/systemd.nspawn.xml b/man/systemd.nspawn.xml
index b1344d6c10..4f3f052911 100644
--- a/man/systemd.nspawn.xml
+++ b/man/systemd.nspawn.xml
@@ -202,6 +202,15 @@
</varlistentry>
<varlistentry>
+ <term><varname>PivotRoot=</varname></term>
+
+ <listitem><para>Selects a directory to pivot to <filename>/</filename> inside the container when starting up.
+ Takes a single path, or a pair of two paths separated by a colon. Both paths must be absolute, and are resolved
+ in the container's file system namespace. This corresponds to the <option>--pivot-root=</option> command line
+ switch.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>Capability=</varname></term>
<term><varname>DropCapability=</varname></term>
@@ -335,6 +344,17 @@
</varlistentry>
<varlistentry>
+ <term><varname>Overlay=</varname></term>
+ <term><varname>OverlayReadOnly=</varname></term>
+
+ <listitem><para>Adds an overlay mount point. Takes a colon-separated list of paths. This option may be used
+ multiple times to configure multiple overlay mounts. This option is equivalent to the command line switches
+ <option>--overlay=</option> and <option>--overlay-ro=</option>, see
+ <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry> for details
+ about the specific options supported. This setting is privileged (see above).</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>PrivateUsersChown=</varname></term>
<listitem><para>Configures whether the ownership of the files and directories in the container tree shall be
diff --git a/man/systemd.offline-updates.xml b/man/systemd.offline-updates.xml
index 07a5225512..b4dce3e92d 100644
--- a/man/systemd.offline-updates.xml
+++ b/man/systemd.offline-updates.xml
@@ -86,34 +86,44 @@
</listitem>
<listitem>
- <para>The system now continues to boot into <filename>default.target</filename>, and thus
- into <filename>system-update.target</filename>. This target pulls in the system update unit,
- which starts the system update script after all file systems have been mounted.</para>
+ <para>The system now continues to boot into <filename>default.target</filename>, and
+ thus into <filename>system-update.target</filename>. This target pulls in all system
+ update units. Only one service should perform an update (see the next point), and all
+ the other ones should exit cleanly with a "success" return code and without doing
+ anything. Update services should be ordered after <filename>sysinit.target</filename>
+ so that the update starts after all file systems have been mounted.</para>
</listitem>
<listitem>
- <para>As the first step, the update script should check if the
+ <para>As the first step, an update service should check if the
<filename>/system-update</filename> symlink points to the location used by that update
- script. In case it does not exists or points to a different location, the script must exit
+ service. In case it does not exist or points to a different location, the service must exit
without error. It is possible for multiple update services to be installed, and for multiple
- update scripts to be launched in parallel, and only the one that corresponds to the tool
+ update services to be launched in parallel, and only the one that corresponds to the tool
that <emphasis>created</emphasis> the symlink before reboot should perform any actions. It
is unsafe to run multiple updates in parallel.</para>
</listitem>
<listitem>
- <para>The update script should now do its job. If applicable and possible, it should
- create a file system snapshot, then install all packages.
- After completion (regardless whether the update succeeded or failed) the machine
- must be rebooted, for example by calling <command>systemctl reboot</command>.
- In addition, on failure the script should revert to the old file system snapshot
- (without the symlink).</para>
+ <para>The update service should now do its job. If applicable and possible, it should
+ create a file system snapshot, then install all packages. After completion (regardless
+ whether the update succeeded or failed) the machine must be rebooted, for example by
+ calling <command>systemctl reboot</command>. In addition, on failure the script should
+ revert to the old file system snapshot (without the symlink).</para>
</listitem>
<listitem>
- <para>The system is rebooted. Since the <filename>/system-update</filename> symlink is gone,
- the generator won't redirect <filename>default.target</filename> after reboot and the
- system now boots into the default target again.</para>
+ <para>The upgrade scripts should exit only after the update is finished. It is expected
+ that the service which performs the upgrade will cause the machine to reboot after it
+ is done. If the <filename>system-update.target</filename> is successfully reached, i.e.
+ all update services have run, and the <filename>/system-update</filename> symlink still
+ exists, it will be removed and the machine rebooted as a safety measure.</para>
+ </listitem>
+
+ <listitem>
+ <para>After a reboot, now that the <filename>/system-update</filename> symlink is gone,
+ the generator won't redirect <filename>default.target</filename> anymore and the system
+ now boots into the default target again.</para>
</listitem>
</orderedlist>
</refsect1>
@@ -144,13 +154,14 @@
script exits uncleanly (by non-zero error code, or signal/coredump). If your script succeeds
you should trigger the reboot in your own code, for example by invoking logind's
<command>Reboot()</command> call or calling <command>systemctl reboot</command>. See
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/logind">logind dbus API</ulink>
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/logind">logind dbus API</ulink>
for details.</para>
</listitem>
<listitem>
<para>The update service should declare <varname>DefaultDependencies=false</varname>,
- and pull in any services it requires explicitly.</para>
+ <varname>Requires=sysinit.target</varname>, <varname>After=sysinit.target</varname>,
+ and explicitly pull in any other services it requires.</para>
</listitem>
</orderedlist>
</refsect1>
@@ -159,7 +170,7 @@
<title>See also</title>
<para>
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/SystemUpdates/">Implementing Offline System Updates</ulink>,
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/SystemUpdates/">Implementing Offline System Updates</ulink>,
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-system-update-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
diff --git a/man/systemd.preset.xml b/man/systemd.preset.xml
index d09167baaf..92eb4e8280 100644
--- a/man/systemd.preset.xml
+++ b/man/systemd.preset.xml
@@ -72,7 +72,7 @@
<para>For more information on the preset logic please have a look
at the <ulink
- url="http://freedesktop.org/wiki/Software/systemd/Preset">Presets</ulink>
+ url="https://www.freedesktop.org/wiki/Software/systemd/Preset">Presets</ulink>
document.</para>
<para>It is not recommended to ship preset files within the
diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml
index 02878b28a0..9b1f5dbbab 100644
--- a/man/systemd.resource-control.xml
+++ b/man/systemd.resource-control.xml
@@ -87,7 +87,7 @@
Those options complement options listed here.</para>
<para>See the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/">New
+ url="https://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/">New
Control Group Interfaces</ulink> for an introduction on how to make
use of resource control APIs from programs.</para>
</refsect1>
diff --git a/man/systemd.scope.xml b/man/systemd.scope.xml
index f69b2ef635..36f24d46a1 100644
--- a/man/systemd.scope.xml
+++ b/man/systemd.scope.xml
@@ -69,7 +69,7 @@
command line.</para>
<para>See the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/">New
+ url="https://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/">New
Control Group Interfaces</ulink> for an introduction on how to make
use of scope units from programs.</para>
</refsect1>
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index 5c65957bda..555719186e 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -84,7 +84,7 @@
This is useful for compatibility with SysV. Note that this
compatibility is quite comprehensive but not 100%. For details
about the incompatibilities, see the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/Incompatibilities">Incompatibilities
+ url="https://www.freedesktop.org/wiki/Software/systemd/Incompatibilities">Incompatibilities
with SysV</ulink> document.</para>
</refsect1>
@@ -136,9 +136,10 @@
process it supervises. A number of options that may be used in
this section are shared with other unit types. These options are
documented in
- <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>
and
- <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+ <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
The options specific to the <literal>[Service]</literal> section
of service units are the following:</para>
@@ -183,7 +184,7 @@
process has to exit before systemd starts follow-up units.
<varname>RemainAfterExit=</varname> is particularly useful for
this type of service. This is the implied default if neither
- <varname>Type=</varname> or <varname>ExecStart=</varname> are
+ <varname>Type=</varname> nor <varname>ExecStart=</varname> are
specified.</para>
<para>Behavior of <option>dbus</option> is similar to
@@ -284,7 +285,9 @@
providing multiple command lines in the same directive, or alternatively, this directive may be specified more
than once with the same effect. If the empty string is assigned to this option, the list of commands to start
is reset, prior assignments of this option will have no effect. If no <varname>ExecStart=</varname> is
- specified, then the service must have <varname>RemainAfterExit=yes</varname> set.</para>
+ specified, then the service must have <varname>RemainAfterExit=yes</varname> and at least one
+ <varname>ExecStop=</varname> line set. (Services lacking both <varname>ExecStart=</varname> and
+ <varname>ExecStop=</varname> are not valid.)</para>
<para>For each of the specified commands, the first argument must be an absolute path to an
executable. Optionally, if this file name is prefixed with <literal>@</literal>, the second token will be
@@ -390,15 +393,11 @@
variable substitution is supported (including
<varname>$MAINPID</varname>, see above).</para>
- <para>Note that it is usually not sufficient to specify a
- command for this setting that only asks the service to
- terminate (for example, by queuing some form of termination
- signal for it), but does not wait for it to do so. Since the
- remaining processes of the services are killed using
- <constant>SIGKILL</constant> immediately after the command
- exited, this would not result in a clean stop. The specified
- command should hence be a synchronous operation, not an
- asynchronous one.</para>
+ <para>Note that it is usually not sufficient to specify a command for this setting that only asks the service
+ to terminate (for example, by queuing some form of termination signal for it), but does not wait for it to do
+ so. Since the remaining processes of the services are killed according to <varname>KillMode=</varname> and
+ <varname>KillSignal=</varname> as described above immediately after the command exited, this may not result in
+ a clean stop. The specified command should hence be a synchronous operation, not an asynchronous one.</para>
<para>Note that the commands specified in <varname>ExecStop=</varname> are only executed when the service
started successfully first. They are not invoked if the service was never started at all, or in case its
@@ -663,6 +662,12 @@
or signal is specified in
<varname>RestartForceExitStatus=</varname> (see below).</para>
+ <para>Note that service restart is subject to unit start rate
+ limiting configured with <varname>StartLimitIntervalSec=</varname>
+ and <varname>StartLimitBurst=</varname>, see
+ <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for details.</para>
+
<para>Setting this to <option>on-failure</option> is the
recommended choice for long-running services, in order to
increase reliability by attempting automatic recovery from
@@ -788,23 +793,26 @@
<varlistentry>
<term><varname>NotifyAccess=</varname></term>
- <listitem><para>Controls access to the service status
- notification socket, as accessible via the
- <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- call. Takes one of <option>none</option> (the default),
- <option>main</option> or <option>all</option>. If
- <option>none</option>, no daemon status updates are accepted
- from the service processes, all status update messages are
- ignored. If <option>main</option>, only service updates sent
- from the main process of the service are accepted. If
- <option>all</option>, all services updates from all members of
- the service's control group are accepted. This option should
- be set to open access to the notification socket when using
- <varname>Type=notify</varname> or
- <varname>WatchdogSec=</varname> (see above). If those options
- are used but <varname>NotifyAccess=</varname> is not
- configured, it will be implicitly set to
- <option>main</option>.</para></listitem>
+ <listitem><para>Controls access to the service status notification socket, as accessible via the
+ <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry> call. Takes one
+ of <option>none</option> (the default), <option>main</option>, <option>exec</option> or
+ <option>all</option>. If <option>none</option>, no daemon status updates are accepted from the service
+ processes, all status update messages are ignored. If <option>main</option>, only service updates sent from the
+ main process of the service are accepted. If <option>exec</option>, only service updates sent from any of the
+ main or control processes originating from one of the <varname>Exec*=</varname> commands are accepted. If
+ <option>all</option>, all services updates from all members of the service's control group are accepted. This
+ option should be set to open access to the notification socket when using <varname>Type=notify</varname> or
+ <varname>WatchdogSec=</varname> (see above). If those options are used but <varname>NotifyAccess=</varname> is
+ not configured, it will be implicitly set to <option>main</option>.</para>
+
+ <para>Note that <function>sd_notify()</function> notifications may be attributed to units correctly only if
+ either the sending process is still around at the time PID 1 processes the message, or if the sending process
+ is explicitly runtime-tracked by the service manager. The latter is the case if the service manager originally
+ forked off the process, i.e. on all processes that match <option>main</option> or
+ <option>exec</option>. Conversely, if an auxiliary process of the unit sends an
+ <function>sd_notify()</function> message and immediately exits, the service manager might not be able to
+ properly attribute the message to the unit, and thus will ignore it, even if
+ <varname>NotifyAccess=</varname><option>all</option> is set for it.</para></listitem>
</varlistentry>
<varlistentry>
@@ -909,23 +917,18 @@
must be passed as separate words). Lone semicolons may be escaped
as <literal>\;</literal>.</para>
- <para>Each command line is split on whitespace, with the first
- item being the command to execute, and the subsequent items being
- the arguments. Double quotes ("...") and single quotes ('...') may
- be used, in which case everything until the next matching quote
- becomes part of the same argument. C-style escapes are also
- supported. The table below contains the list of allowed escape
- patterns. Only patterns which match the syntax in the table are
- allowed; others will result in an error, and must be escaped by
- doubling the backslash. Quotes themselves are removed after
- parsing and escape sequences substituted. In addition, a trailing
- backslash (<literal>\</literal>) may be used to merge lines.
- </para>
-
- <para>This syntax is intended to be very similar to shell syntax,
- but only the meta-characters and expansions described in the
- following paragraphs are understood. Specifically, redirection
- using
+ <para>Each command line is split on whitespace, with the first item being the command to
+ execute, and the subsequent items being the arguments. Double quotes ("…") and single quotes
+ ('…') may be used, in which case everything until the next matching quote becomes part of the
+ same argument. Quotes themselves are removed. C-style escapes are also supported. The table
+ below contains the list of known escape patterns. Only escape patterns which match the syntax in
+ the table are allowed; other patterns may be added in the future and unknown patterns will
+ result in a warning. In particular, any backslashes should be doubled. Finally, a trailing
+ backslash (<literal>\</literal>) may be used to merge lines.</para>
+
+ <para>This syntax is inspired by shell syntax, but only the meta-characters and expansions
+ described in the following paragraphs are understood, and the expansion of variables is
+ different. Specifically, redirection using
<literal>&lt;</literal>,
<literal>&lt;&lt;</literal>,
<literal>&gt;</literal>, and
diff --git a/man/systemd.slice.xml b/man/systemd.slice.xml
index eee98d99ee..3ff3cc5188 100644
--- a/man/systemd.slice.xml
+++ b/man/systemd.slice.xml
@@ -97,7 +97,7 @@
</para>
<para>See the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/">New
+ url="https://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/">New
Control Group Interfaces</ulink> for an introduction on how to make
use of slice units from programs.</para>
</refsect1>
diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
index 0ce1203cfb..1d20a8f7f7 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -216,6 +216,14 @@
<varname>BindIPv6Only=</varname> setting (see below).
</para>
+ <para>If the address string is a string in the format
+ <literal>vsock:x:y</literal>, it is read as CID <literal>x</literal> on
+ a port <literal>y</literal> address in the
+ <constant>AF_VSOCK</constant> family. The CID is a unique 32-bit
+ integer identifier in <constant>AF_VSOCK</constant> analogous to an IP
+ address. Specifying the CID is optional, and may be set to the empty
+ string.</para>
+
<para>Note that <constant>SOCK_SEQPACKET</constant> (i.e.
<varname>ListenSequentialPacket=</varname>) is only available
for <constant>AF_UNIX</constant> sockets.
diff --git a/man/systemd.special.xml b/man/systemd.special.xml
index d977298cd8..fa3dc1c5d4 100644
--- a/man/systemd.special.xml
+++ b/man/systemd.special.xml
@@ -47,16 +47,14 @@
<refpurpose>Special systemd units</refpurpose>
</refnamediv>
- <refsynopsisdiv>
- <para><filename>basic.target</filename>,
+ <refsynopsisdiv><para>
+ <!-- sort alphabetically, targets first -->
+ <filename>basic.target</filename>,
<filename>bluetooth.target</filename>,
- <filename>ctrl-alt-del.target</filename>,
- <filename>cryptsetup.target</filename>,
<filename>cryptsetup-pre.target</filename>,
- <filename>dbus.service</filename>,
- <filename>dbus.socket</filename>,
+ <filename>cryptsetup.target</filename>,
+ <filename>ctrl-alt-del.target</filename>,
<filename>default.target</filename>,
- <filename>display-manager.service</filename>,
<filename>emergency.target</filename>,
<filename>exit.target</filename>,
<filename>final.target</filename>,
@@ -66,25 +64,26 @@
<filename>hibernate.target</filename>,
<filename>hybrid-sleep.target</filename>,
<filename>initrd-fs.target</filename>,
+ <filename>initrd-root-device.target</filename>,
+ <filename>initrd-root-fs.target</filename>,
<filename>kbrequest.target</filename>,
<filename>kexec.target</filename>,
- <filename>local-fs.target</filename>,
<filename>local-fs-pre.target</filename>,
+ <filename>local-fs.target</filename>,
+ <filename>machines.target</filename>
<filename>multi-user.target</filename>,
- <filename>network.target</filename>,
<filename>network-online.target</filename>,
<filename>network-pre.target</filename>,
+ <filename>network.target</filename>,
<filename>nss-lookup.target</filename>,
<filename>nss-user-lookup.target</filename>,
<filename>paths.target</filename>,
<filename>poweroff.target</filename>,
<filename>printer.target</filename>,
<filename>reboot.target</filename>,
- <filename>remote-fs.target</filename>,
<filename>remote-fs-pre.target</filename>,
+ <filename>remote-fs.target</filename>,
<filename>rescue.target</filename>,
- <filename>initrd-root-device.target</filename>,
- <filename>initrd-root-fs.target</filename>,
<filename>rpcbind.target</filename>,
<filename>runlevel2.target</filename>,
<filename>runlevel3.target</filename>,
@@ -105,17 +104,24 @@
<filename>time-sync.target</filename>,
<filename>timers.target</filename>,
<filename>umount.target</filename>,
+ <!-- slices -->
<filename>-.slice</filename>,
<filename>system.slice</filename>,
<filename>user.slice</filename>,
- <filename>machine.slice</filename></para>
- </refsynopsisdiv>
+ <filename>machine.slice</filename>,
+ <!-- the rest -->
+ <filename>dbus.service</filename>,
+ <filename>dbus.socket</filename>,
+ <filename>display-manager.service</filename>,
+ <filename>system-update-cleanup.service</filename>
+ </para></refsynopsisdiv>
<refsect1>
<title>Description</title>
- <para>A few units are treated specially by systemd. They have
- special internal semantics and cannot be renamed.</para>
+ <para>A few units are treated specially by systemd. Many of them have
+ special internal semantics and cannot be renamed, while others simply
+ have a standard meaning and should be present on all systems.</para>
</refsect1>
<refsect1>
@@ -348,6 +354,14 @@
</listitem>
</varlistentry>
<varlistentry>
+ <term><filename>machines.target</filename></term>
+ <listitem>
+ <para>A standard target unit for starting all the containers
+ and other virtual machines. See <filename>systemd-nspawn@.service</filename>
+ for an example.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><filename>multi-user.target</filename></term>
<listitem>
<para>A special target unit for setting up a multi-user
@@ -385,7 +399,7 @@
is part of the boot of most systems, while
<filename>network-online.target</filename> is not, except
when at least one unit requires it. Also see <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget">Running
+ url="https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget">Running
Services After the Network is up</ulink> for more
information.</para>
@@ -602,21 +616,27 @@
on. All userspace log messages will be made available on
this socket. For more information about syslog integration,
please consult the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/syslog">Syslog
+ url="https://www.freedesktop.org/wiki/Software/systemd/syslog">Syslog
Interface</ulink> document.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>system-update.target</filename></term>
+ <term><filename>system-update-cleanup.service</filename></term>
<listitem>
- <para>A special target unit that is used for off-line system
- updates.
+ <para>A special target unit that is used for offline system updates.
<citerefentry><refentrytitle>systemd-system-update-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
- will redirect the boot process to this target if
- <filename>/system-update</filename> exists. For more
- information see the <ulink
- url="http://freedesktop.org/wiki/Software/systemd/SystemUpdates">System
- Updates Specification</ulink>.</para>
+ will redirect the boot process to this target if <filename>/system-update</filename>
+ exists. For more information see
+ <citerefentry><refentrytitle>systemd.offline-updates</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
+ </para>
+
+ <para>Updates should happen before the <filename>system-update.target</filename> is
+ reached, and the services which implement them should cause the machine to reboot. As
+ a safety measure, if this does not happen, and <filename>/system-update</filename>
+ still exists after <filename>system-update.target</filename> is reached,
+ <filename>system-update-cleanup.service</filename> will remove this symlink and
+ reboot the machine.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -765,7 +785,7 @@
is shut down. It is hence useful when writing service files
that require network access on shutdown, which should order
themselves after this target, but not pull it in. Also see
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget">Running
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget">Running
Services After the Network is up</ulink> for more
information. Also see
<filename>network-online.target</filename> described
@@ -923,7 +943,7 @@ Description=Render the desktop icons with Nautilus
PartOf=graphical-session.target
[Service]
-...
+…
</programlisting>
</example>
</refsect2>
diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml
index cf4e1ba839..184abff260 100644
--- a/man/systemd.swap.xml
+++ b/man/systemd.swap.xml
@@ -94,10 +94,10 @@
dependencies on the device units or the mount units of the files
they are activated from.</para>
- <para>Swap units with <varname>DefaultDependencies=</varname> in the <literal>[Unit]</literal> section enabled
- implicitly acquire a <varname>Conflicts=</varname> and an <varname>After=</varname> dependency on
- <filename>umount.target</filename> so that they are deactivated at shutdown, unless
- <varname>DefaultDependencies=no</varname> is specified.</para>
+ <para>Swap units with <varname>DefaultDependencies=</varname> set to its default <option>yes</option> value in the
+ <literal>[Unit]</literal> section enabled implicitly acquire a <varname>Conflicts=</varname> and a
+ <varname>Before=</varname> dependency on <filename>umount.target</filename> so that they are deactivated at
+ shutdown as well as a <varname>Before=swap.target</varname> dependency.</para>
<para>Additional implicit dependencies may be added as result of
execution and resource control parameters as documented in
@@ -170,17 +170,15 @@
<varlistentry>
<term><varname>What=</varname></term>
- <listitem><para>Takes an absolute path of a device node or
- file to use for paging. See
- <citerefentry project='man-pages'><refentrytitle>swapon</refentrytitle><manvolnum>8</manvolnum></citerefentry>
- for details. If this refers to a device node, a dependency on
- the respective device unit is automatically created. (See
- <citerefentry><refentrytitle>systemd.device</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- for more information.) If this refers to a file, a dependency
- on the respective mount unit is automatically created. (See
- <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- for more information.) This option is
- mandatory.</para></listitem>
+ <listitem><para>Takes an absolute path of a device node or file to use for paging. See <citerefentry
+ project='man-pages'><refentrytitle>swapon</refentrytitle><manvolnum>8</manvolnum></citerefentry> for
+ details. If this refers to a device node, a dependency on the respective device unit is automatically
+ created. (See
+ <citerefentry><refentrytitle>systemd.device</refentrytitle><manvolnum>5</manvolnum></citerefentry> for more
+ information.) If this refers to a file, a dependency on the respective mount unit is automatically
+ created. (See <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for more information.) This option is mandatory. Note that the usual specifier expansion is applied to this
+ setting, literal percent characters should hence be written as <literal>%%</literal>.</para></listitem>
</varlistentry>
<varlistentry>
@@ -195,12 +193,11 @@
<varlistentry>
<term><varname>Options=</varname></term>
- <listitem><para>May contain an option string for the swap
- device. This may be used for controlling discard options among
- other functionality, if the swap backing device supports the
- discard or trim operation. (See
+ <listitem><para>May contain an option string for the swap device. This may be used for controlling discard
+ options among other functionality, if the swap backing device supports the discard or trim operation. (See
<citerefentry project='man-pages'><refentrytitle>swapon</refentrytitle><manvolnum>8</manvolnum></citerefentry>
- for more information.) </para></listitem>
+ for more information.) Note that the usual specifier expansion is applied to this setting, literal percent
+ characters should hence be written as <literal>%%</literal>.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/systemd.time.xml b/man/systemd.time.xml
index 47229b4a4e..d30c6cffc9 100644
--- a/man/systemd.time.xml
+++ b/man/systemd.time.xml
@@ -217,11 +217,17 @@
<para>In the date and time specifications, any component may be
specified as <literal>*</literal> in which case any value will
match. Alternatively, each component can be specified as a list of
- values separated by commas. Values may also be suffixed with
+ values separated by commas. Values may be suffixed with
<literal>/</literal> and a repetition value, which indicates that
the value itself and the value plus all multiples of the repetition value
- are matched. Each component may also contain a range of values
- separated by <literal>..</literal>.</para>
+ are matched. Two values separated by <literal>..</literal> may be used
+ to indicate a range of values; ranges may also be followed with
+ <literal>/</literal> and a repetition value.</para>
+
+ <para>A date specification may use <literal>~</literal> to indicate the
+ last day(s) in a month. For example, <literal>*-02~03</literal> means
+ "the third last day in February," and <literal>Mon *-05~07/1</literal>
+ means "the last Monday in May."</para>
<para>The seconds component may contain decimal fractions both in
the value and the repetition. All fractions are rounded to 6
@@ -268,7 +274,7 @@ Wed..Sat,Tue 12-10-15 1:2:3 → Tue..Sat 2012-10-15 01:02:03
monday *-12-* 17:00 → Mon *-12-* 17:00:00
Mon,Fri *-*-3,1,2 *:30:45 → Mon,Fri *-*-01,02,03 *:30:45
12,14,13,12:20,10,30 → *-*-* 12,13,14:10,20,30:00
- 12..14:10,20,30 → *-*-* 12,13,14:10,20,30:00
+ 12..14:10,20,30 → *-*-* 12..14:10,20,30:00
mon,fri *-1/2-1,3 *:30:45 → Mon,Fri *-01/2-01,03 *:30:45
03-05 08:05:40 → *-03-05 08:05:40
08:05:40 → *-*-* 08:05:40
@@ -276,8 +282,8 @@ Wed..Sat,Tue 12-10-15 1:2:3 → Tue..Sat 2012-10-15 01:02:03
Sat,Sun 12-05 08:05:40 → Sat,Sun *-12-05 08:05:40
Sat,Sun 08:05:40 → Sat,Sun *-*-* 08:05:40
2003-03-05 05:40 → 2003-03-05 05:40:00
- 05:40:23.4200004/3.1700005 → 05:40:23.420000/3.170001
- 2003-02..04-05 → 2003-02,03,04-05 00:00:00
+ 05:40:23.4200004/3.1700005 → *-*-* 05:40:23.420000/3.170001
+ 2003-02..04-05 → 2003-02..04-05 00:00:00
2003-03-05 05:40 UTC → 2003-03-05 05:40:00 UTC
2003-03-05 → 2003-03-05 00:00:00
03-05 → *-03-05 00:00:00
diff --git a/man/systemd.timer.xml b/man/systemd.timer.xml
index 4fe140e4bc..7102d626e1 100644
--- a/man/systemd.timer.xml
+++ b/man/systemd.timer.xml
@@ -93,7 +93,7 @@
on <filename>timers.target</filename>, as well as <varname>Conflicts=</varname> and <varname>Before=</varname> on
<filename>shutdown.target</filename> to ensure that they are stopped cleanly prior to system shutdown. Timer units
with at least one <varname>OnCalendar=</varname> directive will have an additional <varname>After=</varname>
- dependency on <filename>timer-sync.target</filename> to avoid being started before the system clock has been
+ dependency on <filename>time-sync.target</filename> to avoid being started before the system clock has been
correctly set. Only timer units involved with early boot or late system shutdown should disable the
<varname>DefaultDependencies=</varname> option.</para>
</refsect1>
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index 40c4cfd854..c963a93531 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -203,7 +203,8 @@
<filename>/run/systemd/system</filename> directories. Drop-in files in <filename>/etc</filename>
take precedence over those in <filename>/run</filename> which in turn take precedence over those
in <filename>/usr/lib</filename>. Drop-in files under any of these directories take precedence
- over unit files wherever located.</para>
+ over unit files wherever located. Multiple drop-in files with different names are applied in
+ lexicographic order, regardless of which of the directories they reside in.</para>
<!-- Note that we do not document .include here, as we consider it mostly obsolete, and want
people to use .d/ drop-ins instead. -->
@@ -255,7 +256,7 @@
<para>The unit file format is covered by the
<ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/InterfaceStabilityPromise">Interface
+ url="https://www.freedesktop.org/wiki/Software/systemd/InterfaceStabilityPromise">Interface
Stability Promise</ulink>.</para>
</refsect1>
@@ -435,32 +436,30 @@
<varlistentry>
<term><varname>Requires=</varname></term>
- <listitem><para>Configures requirement dependencies on other
- units. If this unit gets activated, the units listed here will
- be activated as well. If one of the other units gets
- deactivated or its activation fails, this unit will be
- deactivated. This option may be specified more than once or
- multiple space-separated units may be specified in one option
- in which case requirement dependencies for all listed names
- will be created. Note that requirement dependencies do not
- influence the order in which services are started or stopped.
- This has to be configured independently with the
- <varname>After=</varname> or <varname>Before=</varname>
- options. If a unit <filename>foo.service</filename> requires a
- unit <filename>bar.service</filename> as configured with
- <varname>Requires=</varname> and no ordering is configured
- with <varname>After=</varname> or <varname>Before=</varname>,
- then both units will be started simultaneously and without any
- delay between them if <filename>foo.service</filename> is
- activated. Often, it is a better choice to use
- <varname>Wants=</varname> instead of
- <varname>Requires=</varname> in order to achieve a system that
- is more robust when dealing with failing services.</para>
-
- <para>Note that dependencies of this type may also be
- configured outside of the unit configuration file by adding a
- symlink to a <filename>.requires/</filename> directory
- accompanying the unit file. For details, see
+ <listitem><para>Configures requirement dependencies on other units. If this unit gets activated, the units
+ listed here will be activated as well. If one of the other units gets deactivated or its activation fails, this
+ unit will be deactivated. This option may be specified more than once or multiple space-separated units may be
+ specified in one option in which case requirement dependencies for all listed names will be created. Note that
+ requirement dependencies do not influence the order in which services are started or stopped. This has to be
+ configured independently with the <varname>After=</varname> or <varname>Before=</varname> options. If a unit
+ <filename>foo.service</filename> requires a unit <filename>bar.service</filename> as configured with
+ <varname>Requires=</varname> and no ordering is configured with <varname>After=</varname> or
+ <varname>Before=</varname>, then both units will be started simultaneously and without any delay between them
+ if <filename>foo.service</filename> is activated. Often, it is a better choice to use <varname>Wants=</varname>
+ instead of <varname>Requires=</varname> in order to achieve a system that is more robust when dealing with
+ failing services.</para>
+
+ <para>Note that this dependency type does not imply that the other unit always has to be in active state when
+ this unit is running. Specifically: failing condition checks (such as <varname>ConditionPathExists=</varname>,
+ <varname>ConditionPathExists=</varname>, … — see below) do not cause the start job of a unit with a
+ <varname>Requires=</varname> dependency on it to fail. Also, some unit types may deactivate on their own (for
+ example, a service process may decide to exit cleanly, or a device may be unplugged by the user), which is not
+ propagated to units having a <varname>Requires=</varname> dependency. Use the <varname>BindsTo=</varname>
+ dependency type together with <varname>After=</varname> to ensure that a unit may never be in active state
+ without a specific other unit also in active state (see below).</para>
+
+ <para>Note that dependencies of this type may also be configured outside of the unit configuration file by
+ adding a symlink to a <filename>.requires/</filename> directory accompanying the unit file. For details, see
above.</para></listitem>
</varlistentry>
@@ -494,14 +493,21 @@
<varlistentry>
<term><varname>BindsTo=</varname></term>
- <listitem><para>Configures requirement dependencies, very
- similar in style to <varname>Requires=</varname>, however in
- addition to this behavior, it also declares that this unit is
- stopped when any of the units listed suddenly disappears.
- Units can suddenly, unexpectedly disappear if a service
- terminates on its own choice, a device is unplugged or a mount
- point unmounted without involvement of
- systemd.</para></listitem>
+ <listitem><para>Configures requirement dependencies, very similar in style to
+ <varname>Requires=</varname>. However, this dependency type is stronger: in addition to the effect of
+ <varname>Requires=</varname> it declares that if the unit bound to is stopped, this unit will be stopped
+ too. This means a unit bound to another unit that suddenly enters inactive state will be stopped too.
+ Units can suddenly, unexpectedly enter inactive state for different reasons: the main process of a service unit
+ might terminate on its own choice, the backing device of a device unit might be unplugged or the mount point of
+ a mount unit might be unmounted without involvement of the system and service manager.</para>
+
+ <para>When used in conjunction with <varname>After=</varname> on the same unit the behaviour of
+ <varname>BindsTo=</varname> is even stronger. In this case, the unit bound to strictly has to be in active
+ state for this unit to also be in active state. This not only means a unit bound to another unit that suddenly
+ enters inactive state, but also one that is bound to another unit that gets skipped due to a failed condition
+ check (such as <varname>ConditionPathExists=</varname>, <varname>ConditionPathIsSymbolicLink=</varname>, … —
+ see below) will be stopped, should it be running. Hence, in many cases it is best to combine
+ <varname>BindsTo=</varname> with <varname>After=</varname>.</para></listitem>
</varlistentry>
<varlistentry>
@@ -540,42 +546,26 @@
<term><varname>Before=</varname></term>
<term><varname>After=</varname></term>
- <listitem><para>A space-separated list of unit names.
- Configures ordering dependencies between units. If a unit
- <filename>foo.service</filename> contains a setting
- <option>Before=bar.service</option> and both units are being
- started, <filename>bar.service</filename>'s start-up is
- delayed until <filename>foo.service</filename> is started up.
- Note that this setting is independent of and orthogonal to the
- requirement dependencies as configured by
- <varname>Requires=</varname>. It is a common pattern to
- include a unit name in both the <varname>After=</varname> and
- <varname>Requires=</varname> option, in which case the unit
- listed will be started before the unit that is configured with
- these options. This option may be specified more than once, in
- which case ordering dependencies for all listed names are
- created. <varname>After=</varname> is the inverse of
- <varname>Before=</varname>, i.e. while
- <varname>After=</varname> ensures that the configured unit is
- started after the listed unit finished starting up,
- <varname>Before=</varname> ensures the opposite, i.e. that the
- configured unit is fully started up before the listed unit is
- started. Note that when two units with an ordering dependency
- between them are shut down, the inverse of the start-up order
- is applied. i.e. if a unit is configured with
- <varname>After=</varname> on another unit, the former is
- stopped before the latter if both are shut down. Given two units
- with any ordering dependency between them, if one unit is shut
- down and the other is started up, the shutdown is ordered
- before the start-up. It doesn't matter if the ordering
- dependency is <varname>After=</varname> or
- <varname>Before=</varname>. It also doesn't matter which of the
- two is shut down, as long as one is shut down and the other is
- started up. The shutdown is ordered before the start-up in all
- cases. If two units have no ordering dependencies between them,
- they are shut down or started up simultaneously, and no ordering
- takes place.
- </para></listitem>
+ <listitem><para>A space-separated list of unit names. Configures ordering dependencies between units. If a
+ unit <filename>foo.service</filename> contains a setting <option>Before=bar.service</option> and both units are
+ being started, <filename>bar.service</filename>'s start-up is delayed until <filename>foo.service</filename> is
+ started up. Note that this setting is independent of and orthogonal to the requirement dependencies as
+ configured by <varname>Requires=</varname>, <varname>Wants=</varname> or <varname>BindsTo=</varname>. It is a
+ common pattern to include a unit name in both the <varname>After=</varname> and <varname>Requires=</varname>
+ option, in which case the unit listed will be started before the unit that is configured with these
+ options. This option may be specified more than once, in which case ordering dependencies for all listed names
+ are created. <varname>After=</varname> is the inverse of <varname>Before=</varname>, i.e. while
+ <varname>After=</varname> ensures that the configured unit is started after the listed unit finished starting
+ up, <varname>Before=</varname> ensures the opposite, i.e. that the configured unit is fully started up before
+ the listed unit is started. Note that when two units with an ordering dependency between them are shut down,
+ the inverse of the start-up order is applied. i.e. if a unit is configured with <varname>After=</varname> on
+ another unit, the former is stopped before the latter if both are shut down. Given two units with any ordering
+ dependency between them, if one unit is shut down and the other is started up, the shutdown is ordered before
+ the start-up. It doesn't matter if the ordering dependency is <varname>After=</varname> or
+ <varname>Before=</varname>, in this case. It also doesn't matter which of the two is shut down, as long as one
+ is shut down and the other is started up. The shutdown is ordered before the start-up in all cases. If two
+ units have no ordering dependencies between them, they are shut down or started up simultaneously, and no
+ ordering takes place. </para></listitem>
</varlistentry>
<varlistentry>
@@ -630,11 +620,9 @@
all mount units required to access the specified path.</para>
<para>Mount points marked with <option>noauto</option> are not
- mounted automatically and will be ignored for the purposes of
- this option. If such a mount should be a requirement for this
- unit, direct dependencies on the mount units may be added
- (<varname>Requires=</varname> and <varname>After=</varname> or
- some other combination). </para></listitem>
+ mounted automatically through <filename>local-fs.target</filename>,
+ but are still honored for the purposes of this option, i.e. they
+ will be pulled in by this unit.</para></listitem>
</varlistentry>
<varlistentry>
@@ -871,7 +859,7 @@
<varname>arm64-be</varname>,
<varname>sh</varname>,
<varname>sh64</varname>,
- <varname>m86k</varname>,
+ <varname>m68k</varname>,
<varname>tilegx</varname>,
<varname>cris</varname> to test
against a specific architecture. The architecture is
@@ -1246,21 +1234,6 @@
<entry>This is either the unescaped instance name (if applicable) with <filename>/</filename> prepended (if applicable), or the unescaped prefix name prepended with <filename>/</filename>.</entry>
</row>
<row>
- <entry><literal>%c</literal></entry>
- <entry>Control group path of the unit</entry>
- <entry>This path does not include the <filename>/sys/fs/cgroup/systemd/</filename> prefix.</entry>
- </row>
- <row>
- <entry><literal>%r</literal></entry>
- <entry>Control group path of the slice the unit is placed in</entry>
- <entry>This usually maps to the parent control group path of <literal>%c</literal>.</entry>
- </row>
- <row>
- <entry><literal>%R</literal></entry>
- <entry>Root control group path below which slices and units are placed</entry>
- <entry>For system instances, this resolves to <filename>/</filename>, except in containers, where this maps to the container's root control group path.</entry>
- </row>
- <row>
<entry><literal>%t</literal></entry>
<entry>Runtime directory</entry>
<entry>This is either <filename>/run</filename> (for the system manager) or the path <literal>$XDG_RUNTIME_DIR</literal> resolves to (for user managers).</entry>
@@ -1314,13 +1287,6 @@
</tgroup>
</table>
- <para>Please note that specifiers <literal>%U</literal>,
- <literal>%h</literal>, <literal>%s</literal> are mostly useless
- when systemd is running in system mode. PID 1 cannot query the
- user account database for information, so the specifiers only work
- as shortcuts for things which are already specified in a different
- way in the unit file. They are fully functional when systemd is
- running in <option>--user</option> mode.</para>
</refsect1>
<refsect1>
@@ -1365,7 +1331,7 @@ ExecStart=/usr/sbin/foo-daemon
file <filename><replaceable>name</replaceable>.conf</filename>
there that only changes the specific settings one is interested
in. Note that multiple such drop-in files are read if
- present.</para>
+ present, processed in lexicographic order of their filename.</para>
<para>The advantage of the first method is that one easily
overrides the complete unit, the vendor unit is not parsed at
diff --git a/man/systemd.xml b/man/systemd.xml
index 79d8aedbbc..ea7dad1aea 100644
--- a/man/systemd.xml
+++ b/man/systemd.xml
@@ -51,10 +51,13 @@
<refsynopsisdiv>
<cmdsynopsis>
- <command>systemd <arg choice="opt" rep="repeat">OPTIONS</arg></command>
+ <command>systemd</command>
+ <arg choice="opt" rep="repeat">OPTIONS</arg>
</cmdsynopsis>
<cmdsynopsis>
- <command>init <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="req">COMMAND</arg></command>
+ <command>init</command>
+ <arg choice="opt" rep="repeat">OPTIONS</arg>
+ <arg choice="req">COMMAND</arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -150,6 +153,7 @@
user instance. This setting may also be enabled during boot,
on the kernel command line via the
<varname>systemd.crash_vt=</varname> option, see
+ <!-- FIXME: there is no crash_vt command line option? -->
below.</para></listitem>
</varlistentry>
@@ -183,10 +187,14 @@
<varlistentry>
<term><option>--show-status=</option></term>
- <listitem><para>Show terse service status information while
- booting. This switch has no effect when run as user instance.
- Takes a boolean argument which may be omitted which is
- interpreted as <option>true</option>.</para></listitem>
+ <listitem><para>Takes a boolean argument or the special value <constant>auto</constant>. If on, terse unit
+ status information is shown on the console during boot-up and shutdown. If off, no such status information is
+ shown. If set to <constant>auto</constant> behavior is similar to off, except that it is automatically switched
+ to on, as soon as the first unit failure or significant boot delay is encountered. This switch has no effect
+ when invoked as user instance. If specified, overrides both the kernel command line setting
+ <varname>systemd.show_status=</varname> (see below) and the configuration file option
+ <option>ShowStatus=</option>, see
+ <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--log-target=</option></term>
@@ -280,9 +288,9 @@
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
however some are created automatically from other configuration,
dynamically from system state or programmatically at runtime.
- Units may be "active" (meaning started, bound, plugged in, ...,
+ Units may be "active" (meaning started, bound, plugged in, …,
depending on the unit type, see below), or "inactive" (meaning
- stopped, unbound, unplugged, ...), as well as in the process of
+ stopped, unbound, unplugged, …), as well as in the process of
being activated or deactivated, i.e. between the two states (these
states are called "activating", "deactivating"). A special
"failed" state is available as well, which is very similar to
@@ -445,7 +453,7 @@
<para>Note that some but not all interfaces provided
by systemd are covered by the
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/InterfaceStabilityPromise">Interface
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/InterfaceStabilityPromise">Interface
Stability Promise</ulink>.</para>
<para>Units may be generated dynamically at boot and system
@@ -455,8 +463,8 @@
<para>Systems which invoke systemd in a container or initrd
environment should implement the
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface">Container Interface</ulink> or
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/InitrdInterface">initrd Interface</ulink>
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/ContainerInterface">Container Interface</ulink> or
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/InitrdInterface">initrd Interface</ulink>
specifications, respectively.</para>
</refsect1>
@@ -753,7 +761,7 @@
<term><constant>SIGRTMIN+27</constant></term>
<term><constant>SIGRTMIN+28</constant></term>
- <listitem><para>Sets the log level to
+ <listitem><para>Sets the log target to
<literal>journal-or-kmsg</literal> (or
<literal>console</literal> on
<constant>SIGRTMIN+27</constant>, <literal>kmsg</literal> on
@@ -894,84 +902,91 @@
</varlistentry>
<varlistentry>
- <term><varname>systemd.dump_core=</varname></term>
+ <term><varname>systemd.dump_core</varname></term>
- <listitem><para>Takes a boolean argument. If
- <option>yes</option>, the systemd manager (PID 1) dumps core
- when it crashes. Otherwise, no core dump is created. Defaults
- to <option>yes</option>.</para></listitem>
+ <listitem><para>Takes a boolean argument or enables the option if specified
+ without an argument. If enabled, the systemd manager (PID 1) dumps core when
+ it crashes. Otherwise, no core dump is created. Defaults to enabled.</para>
+ </listitem>
</varlistentry>
<varlistentry>
- <term><varname>systemd.crash_chvt=</varname></term>
+ <term><varname>systemd.crash_chvt</varname></term>
- <listitem><para>Takes a positive integer, or a boolean
- argument. If a positive integer (in the range 1–63) is
- specified, the system manager (PID 1) will activate the specified
- virtual terminal (VT) when it crashes. Defaults to
- <constant>no</constant>, meaning that no such switch is
- attempted. If set to <constant>yes</constant>, the VT the
- kernel messages are written to is selected.</para></listitem>
+ <listitem><para>Takes a positive integer, or a boolean argument. Can be also
+ specified without an argument, with the same effect as a positive boolean. If
+ a positive integer (in the range 1–63) is specified, the system manager (PID
+ 1) will activate the specified virtual terminal (VT) when it
+ crashes. Defaults to disabled, meaning that no such switch is attempted. If
+ set to enabled, the VT the kernel messages are written to is selected.
+ </para></listitem>
</varlistentry>
<varlistentry>
- <term><varname>systemd.crash_shell=</varname></term>
+ <term><varname>systemd.crash_shell</varname></term>
- <listitem><para>Takes a boolean argument. If
- <option>yes</option>, the system manager (PID 1) spawns a
- shell when it crashes, after a 10s delay. Otherwise, no shell
- is spawned. Defaults to <option>no</option>, for security
- reasons, as the shell is not protected by password
+ <listitem><para>Takes a boolean argument or enables the option if specified
+ without an argument. If enabled, the system manager (PID 1) spawns a shell
+ when it crashes, after a 10s delay. Otherwise, no shell is spawned. Defaults
+ to disabled, for security reasons, as the shell is not protected by password
authentication.</para></listitem>
</varlistentry>
<varlistentry>
- <term><varname>systemd.crash_reboot=</varname></term>
+ <term><varname>systemd.crash_reboot</varname></term>
- <listitem><para>Takes a boolean argument. If
- <option>yes</option>, the system manager (PID 1) will reboot
- the machine automatically when it crashes, after a 10s delay.
- Otherwise, the system will hang indefinitely. Defaults to
- <option>no</option>, in order to avoid a reboot loop. If
- combined with <varname>systemd.crash_shell=</varname>, the
+ <listitem><para>Takes a boolean argument or enables the option if specified
+ without an argument. If enabled, the system manager (PID 1) will reboot the
+ machine automatically when it crashes, after a 10s delay. Otherwise, the
+ system will hang indefinitely. Defaults to disabled, in order to avoid a
+ reboot loop. If combined with <varname>systemd.crash_shell</varname>, the
system is rebooted after the shell exits.</para></listitem>
</varlistentry>
<varlistentry>
- <term><varname>systemd.confirm_spawn=</varname></term>
+ <term><varname>systemd.confirm_spawn</varname></term>
- <listitem><para>Takes a boolean argument. If
- <option>yes</option>, the system manager (PID 1) asks for
- confirmation when spawning processes. Defaults to
- <option>no</option>.</para></listitem>
+ <listitem><para>Takes a boolean argument or a path to the virtual console
+ where the confirmation messages should be emitted. Can be also specified
+ without an argument, with the same effect as a positive boolean. If enabled,
+ the system manager (PID 1) asks for confirmation when spawning processes
+ using <option>/dev/console</option>. If a path or a console name (such as
+ <literal>ttyS0</literal>) is provided, the virtual console pointed to by this
+ path or described by the give name will be used instead. Defaults to disabled.
+ </para></listitem>
</varlistentry>
<varlistentry>
- <term><varname>systemd.show_status=</varname></term>
+ <term><varname>systemd.show_status</varname></term>
<listitem><para>Takes a boolean argument or the constant
- <constant>auto</constant>. If <option>yes</option>, the
- systemd manager (PID 1) shows terse service status updates on
- the console during bootup. <constant>auto</constant> behaves
- like <option>false</option> until a service fails or there is
- a significant delay in boot. Defaults to
- <option>yes</option>, unless <option>quiet</option> is passed
- as kernel command line option, in which case it defaults to
- <constant>auto</constant>.</para></listitem>
+ <constant>auto</constant>. Can be also specified without an argument, with
+ the same effect as a positive boolean. If enabled, the systemd manager (PID
+ 1) shows terse service status updates on the console during bootup.
+ <constant>auto</constant> behaves like <option>false</option> until a unit
+ fails or there is a significant delay in boot. Defaults to enabled, unless
+ <option>quiet</option> is passed as kernel command line option, in which case
+ it defaults to <constant>auto</constant>. If specified overrides the system
+ manager configuration file option <option>ShowStatus=</option>, see
+ <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+ However, the process command line option <option>--show-status=</option>
+ takes precedence over both this kernel command line option and the
+ configuration file option.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>systemd.log_target=</varname></term>
<term><varname>systemd.log_level=</varname></term>
- <term><varname>systemd.log_color=</varname></term>
<term><varname>systemd.log_location=</varname></term>
+ <term><varname>systemd.log_color</varname></term>
- <listitem><para>Controls log output, with the same effect as
- the <varname>$SYSTEMD_LOG_TARGET</varname>,
+ <listitem><para>Controls log output, with the same effect as the
+ <varname>$SYSTEMD_LOG_TARGET</varname>,
<varname>$SYSTEMD_LOG_LEVEL</varname>,
- <varname>$SYSTEMD_LOG_COLOR</varname>,
- <varname>$SYSTEMD_LOG_LOCATION</varname> environment variables
- described above.</para></listitem>
+ <varname>$SYSTEMD_LOG_LOCATION</varname>,
+ <varname>$SYSTEMD_LOG_COLOR</varname> environment variables described above.
+ <varname>systemd.log_color</varname> can be specified without an argument,
+ with the same effect as a positive boolean.</para></listitem>
</varlistentry>
<varlistentry>
@@ -1003,6 +1018,41 @@
</varlistentry>
<varlistentry>
+ <term><varname>systemd.unified_cgroup_hierarchy</varname></term>
+
+ <listitem><para>When specified without an argument or with a true argument,
+ enables the usage of
+ <ulink url="https://www.kernel.org/doc/Documentation/cgroup-v2.txt">unified cgroup hierarchy</ulink>
+ (a.k.a. cgroups-v2). When specified with a false argument, fall back to
+ hybrid or full legacy cgroup hierarchy.</para>
+
+ <para>If this option is not specified, the default behaviour is determined
+ during compilation (the <option>--with-default-hierarchy=</option>
+ option). If the kernel does not support unified cgroup hierarchy, the legacy
+ hierarchy will be used even if this option is specified.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>systemd.legacy_systemd_cgroup_controller</varname></term>
+
+ <listitem><para>Takes effect if the full unified cgroup hierarchy is not used
+ (see previous option). When specified without an argument or with a true
+ argument, disables the use of "hybrid" cgroup hierarchy (i.e. a cgroups-v2
+ tree used for systemd, and
+ <ulink url="https://www.kernel.org/doc/Documentation/cgroup-v1/">legacy
+ cgroup hierarchy</ulink>, a.k.a. cgroups-v1, for other controllers), and
+ forces a full "legacy" mode. When specified with a false argument, enables
+ the use of "hybrid" hierarchy.</para>
+
+ <para>If this option is not specified, the default behaviour is determined
+ during compilation (the <option>--with-default-hierarchy=</option>
+ option). If the kernel does not support unified cgroup hierarchy, the legacy
+ hierarchy will be used even if this option is specified.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>quiet</varname></term>
<listitem><para>Turn off status output at boot, much like
@@ -1137,7 +1187,7 @@
<refsect1>
<title>See Also</title>
<para>
- The <ulink url="http://www.freedesktop.org/wiki/Software/systemd/">systemd Homepage</ulink>,
+ The <ulink url="https://www.freedesktop.org/wiki/Software/systemd/">systemd Homepage</ulink>,
<citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>locale.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
diff --git a/man/telinit.xml b/man/telinit.xml
index 02d31fbd46..bdd22a6ce8 100644
--- a/man/telinit.xml
+++ b/man/telinit.xml
@@ -114,10 +114,10 @@
<listitem><para>Change the SysV runlevel. This is translated
into an activation request for
<filename>runlevel2.target</filename>,
- <filename>runlevel3.target</filename>, ... and is equivalent
+ <filename>runlevel3.target</filename>, … and is equivalent
to <command>systemctl isolate runlevel2.target</command>,
<command>systemctl isolate runlevel3.target</command>,
- ...</para></listitem>
+ …</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/timedatectl.xml b/man/timedatectl.xml
index 415e2c799a..d8a83c8add 100644
--- a/man/timedatectl.xml
+++ b/man/timedatectl.xml
@@ -232,7 +232,7 @@ Password: ********
Status: "Using Time Server 216.239.38.15:123 (time4.google.com)."
CGroup: /system.slice/systemd-timesyncd.service
└─595 /usr/lib/systemd/systemd-timesyncd
-...</programlisting>
+…</programlisting>
</para>
</refsect1>
diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml
index e040a1636d..555e9c2d56 100644
--- a/man/tmpfiles.d.xml
+++ b/man/tmpfiles.d.xml
@@ -117,8 +117,8 @@
type, path, mode, ownership, age, and argument fields:</para>
<programlisting>#Type Path Mode UID GID Age Argument
- d /run/user 0755 root root 10d -
- L /tmp/foobar - - - - /dev/null</programlisting>
+d /run/user 0755 root root 10d -
+L /tmp/foobar - - - - /dev/null</programlisting>
<para>Fields may be enclosed within quotes and contain C-style escapes.</para>
@@ -159,7 +159,7 @@
<term><varname>d</varname></term>
<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>
+ to time based cleanup if the age argument is specified.</para></listitem>
</varlistentry>
<varlistentry>
@@ -171,9 +171,13 @@
<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>
+ <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. For this entry to be useful, at least one of the mode, uid, gid, or age arguments
+ must be specified, since otherwise this entry has no effect. If the age argument is
+ <literal>0</literal>, contents of the directory will be unconditionally deleted every time
+ <command>systemd-tmpfiles --clean</command> is run. This can be useful when combined with
+ <varname>!</varname>, see the examples.</para></listitem>
</varlistentry>
<varlistentry>
@@ -680,6 +684,18 @@ e /var/chache/dnf/ - - - 30d
<filename>/var/chache/dnf/</filename> will be removed after they have not been
accessed in 30 days.</para>
</example>
+
+ <example>
+ <title>Empty the contents of a cache directory on boot</title>
+
+ <programlisting># /usr/lib/tmpfiles.d/krb5rcache.conf
+e! /var/cache/krb5rcache - - - 0
+</programlisting>
+
+ <para>Any files and subdirectories in <filename>/var/cache/krb5rcache/</filename>
+ will be removed on boot. The directory will not be created.
+ </para>
+ </example>
</refsect1>
<refsect1>
diff --git a/mkosi.build b/mkosi.build
index 94a6667e42..872841eb63 100755
--- a/mkosi.build
+++ b/mkosi.build
@@ -22,4 +22,14 @@
./autogen.sh c
make -j `nproc`
+
+make check
make install
+
+mkdir -p $DESTDIR/etc
+
+cat > $DESTDIR/etc/issue <<EOF
+\S (built from systemd tree)
+Kernel \r on an \m (\l)
+
+EOF
diff --git a/po/LINGUAS b/po/LINGUAS
index 287d42b047..bd283b6130 100644
--- a/po/LINGUAS
+++ b/po/LINGUAS
@@ -1,6 +1,7 @@
be
be@latin
bg
+ca
cs
da
de
diff --git a/po/ca.po b/po/ca.po
new file mode 100644
index 0000000000..30fdea0cf6
--- /dev/null
+++ b/po/ca.po
@@ -0,0 +1,525 @@
+# Catalan translation for systemd.
+# Copyright (C) 2015 systemd's COPYRIGHT HOLDER
+# This file is distributed under the same license as the systemd package.
+# Walter Garcia-Fontes <walter.garcia@upf.edu>, 2016.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: systemd master\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-11-22 16:37+0100\n"
+"PO-Revision-Date: 2016-12-29 09:02+0100\n"
+"Last-Translator: Walter Garcia-Fontes <walter.garcia@upf.edu>\n"
+"Language-Team: Català <ubuntu-l10n-ca@lists.ubuntu.com>\n"
+"Language: ca\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 1.8.7.1\n"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:1
+msgid "Send passphrase back to system"
+msgstr "Retornar la contrasenya al sistema"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:2
+msgid ""
+"Authentication is required to send the entered passphrase back to the system."
+msgstr "Es requereix autenticació per retornar la contrasenya entrada al sistema."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:3
+msgid "Manage system services or other units"
+msgstr "Administrar serveis del sistema o d'altres unitats."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:4
+msgid "Authentication is required to manage system services or other units."
+msgstr "Es requereix autenticació per administrar els serveis de sistemes o d'altres unitats."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:5
+msgid "Manage system service or unit files"
+msgstr "Gestiona un servei de sistema o fitxers d'unitat"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:6
+msgid "Authentication is required to manage system service or unit files."
+msgstr "Cal autenticació per gestionar un servei de sistema o fitxers d'unitat."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:7
+msgid "Set or unset system and service manager environment variables"
+msgstr "Administrar variables de entorno del sistema y del gestor de servicios"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:8
+msgid ""
+"Authentication is required to set or unset system and service manager "
+"environment variables."
+msgstr "Cal autenticació per establir o cancel·lar variables d'entorn de sistema o del gestor de serveis."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:9
+msgid "Reload the systemd state"
+msgstr "Recarrega l'estat del systemd"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:10
+msgid "Authentication is required to reload the systemd state."
+msgstr "Cal autenticació per establir el nom de l'ordinador local."
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:1
+msgid "Set host name"
+msgstr "Estableix el nom de l'ordinador"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:2
+msgid "Authentication is required to set the local host name."
+msgstr "Cal autenticació per establir el nom de l'ordinador local."
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:3
+msgid "Set static host name"
+msgstr "Estableix el nom estàtic de l'ordinador"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:4
+msgid ""
+"Authentication is required to set the statically configured local host name, "
+"as well as the pretty host name."
+msgstr "Cal autenticació per establir el nom configurat estàticament de l'ordinador local, així com el nom de l'ordinador de nivell superior."
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:5
+msgid "Set machine information"
+msgstr "Estableix la informació de l'ordinador"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:6
+msgid "Authentication is required to set local machine information."
+msgstr "Cal autenticació per establir la informació de l'ordinador local."
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:1
+msgid "Import a VM or container image"
+msgstr "Importa una màquina virtual o una imatge de contenidor"
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:2
+msgid "Authentication is required to import a VM or container image"
+msgstr "Cal autenticació per importar una màquina virtual o una imatge de contenidor"
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:3
+msgid "Export a VM or container image"
+msgstr "Exporta una màquina virtual o una imatge de contenidor"
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:4
+msgid "Authentication is required to export a VM or container image"
+msgstr "Cal autenticació per exportar una màquina virtual o una imatge de contenidor"
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:5
+msgid "Download a VM or container image"
+msgstr "Descarrega una màquina virtual o una imatge de contenidor"
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:6
+msgid "Authentication is required to download a VM or container image"
+msgstr "Cal autenticació per descarregar una màquina virtual o una imatge de contenidor"
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:1
+msgid "Set system locale"
+msgstr "Estableix la regió del sistema"
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:2
+msgid "Authentication is required to set the system locale."
+msgstr "Cal autenticació per establir la regió del sistema."
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:3
+msgid "Set system keyboard settings"
+msgstr "Estableix la configuració del teclat del sistema."
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:4
+msgid "Authentication is required to set the system keyboard settings."
+msgstr "Cal autenticació per establir la configuració del teclat del sistema."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:1
+msgid "Allow applications to inhibit system shutdown"
+msgstr "Permet a les aplicacions inhibir l'apagada del sistema"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:2
+msgid ""
+"Authentication is required for an application to inhibit system shutdown."
+msgstr "Cal autenticació perquè una aplicació inhibeixi l'apagada del sistema."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:3
+msgid "Allow applications to delay system shutdown"
+msgstr "Permet a les aplicacions endarrerir l'apagada del sistema"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:4
+msgid "Authentication is required for an application to delay system shutdown."
+msgstr "Cal autenticació perquè una aplicació endarrereixi l'apagada del sistema."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:5
+msgid "Allow applications to inhibit system sleep"
+msgstr "Permet a les aplicacions inhibir la hibernació del sistema"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:6
+msgid "Authentication is required for an application to inhibit system sleep."
+msgstr "Cal autenticació perquè una aplicació inhibeixi la hibernació del sistema."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:7
+msgid "Allow applications to delay system sleep"
+msgstr "Permet a les aplicacions endarrerir la hibernació del sistema"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:8
+msgid "Authentication is required for an application to delay system sleep."
+msgstr "Cal autenticació perquè una aplicació endarrereixi la hibernació del sistema."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:9
+msgid "Allow applications to inhibit automatic system suspend"
+msgstr "Permet a les aplicacions inhibir la suspensió automàtica del sistema"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:10
+msgid ""
+"Authentication is required for an application to inhibit automatic system "
+"suspend."
+msgstr "Cal autenticació perquè una aplicació inhibeixi la suspensió automàtica del sistema."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:11
+msgid "Allow applications to inhibit system handling of the power key"
+msgstr "Permet a les aplicacions inhibir la gestió de la tecla d'encesa per part del sistema"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:12
+msgid ""
+"Authentication is required for an application to inhibit system handling of "
+"the power key."
+msgstr "Cal autenticació perquè una aplicació inhibeixi la gestió de la tecla d'encesa per part del sistema."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:13
+msgid "Allow applications to inhibit system handling of the suspend key"
+msgstr "Permet a les aplicacions inhibir la tecla de suspensió per part del sistema"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:14
+msgid ""
+"Authentication is required for an application to inhibit system handling of "
+"the suspend key."
+msgstr "Cal autenticació perquè una aplicació inhibeixi la gestió de la tecla de suspensió per part del sistema."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:15
+msgid "Allow applications to inhibit system handling of the hibernate key"
+msgstr "Permet a les aplicacions inhibir la gestió de la tecla d'hibernació per part del sistema"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:16
+msgid ""
+"Authentication is required for an application to inhibit system handling of "
+"the hibernate key."
+msgstr "Cal autenticació perquè una aplicació inhibeixi la gestió de la tecla d'hibernació per part del sistema."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:17
+msgid "Allow applications to inhibit system handling of the lid switch"
+msgstr "Permet a les aplicacions la gestió del tancament de la tapa per part del sistema"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:18
+msgid ""
+"Authentication is required for an application to inhibit system handling of "
+"the lid switch."
+msgstr "Cal autenticació perquè una aplicació inhibeixi la gestió del tancament de la tapa per part del sistema."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:19
+msgid "Allow non-logged-in users to run programs"
+msgstr "Permet l'execució de programes als usuaris sense inici de sessió"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:20
+msgid "Authentication is required to run programs as a non-logged-in user."
+msgstr "Cal autenticació per a la execució de programes per part d'usuaris sense inici de sessió"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:21
+msgid "Allow attaching devices to seats"
+msgstr "Permet l'annexió de dispositius als llocs de treball"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:22
+msgid "Authentication is required for attaching a device to a seat."
+msgstr "Cal autenticació per annexar un dispositiu a un lloc de treball."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:23
+msgid "Flush device to seat attachments"
+msgstr "Allibera les annexions de dispositius a llocs de treball"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:24
+msgid ""
+"Authentication is required for resetting how devices are attached to seats."
+msgstr "Cal autenticació per restablir les annexions dels dispositius als llocs de treball."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:25
+msgid "Power off the system"
+msgstr "Apaga el sistema"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:26
+msgid "Authentication is required for powering off the system."
+msgstr "Cal autenticació per apagar el sistema"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:27
+msgid "Power off the system while other users are logged in"
+msgstr "Apaga el sistema mentre que altres usuaris tenen sessió iniciada"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:28
+msgid ""
+"Authentication is required for powering off the system while other users are "
+"logged in."
+msgstr "Cal autenticació per apagar el sistema mentre que altres usuaris tenen sessió iniciada."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:29
+msgid "Power off the system while an application asked to inhibit it"
+msgstr "Apaga el sistema mentre que una aplicació ha demanat inhibir-lo"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:30
+msgid ""
+"Authentication is required for powering off the system while an application "
+"asked to inhibit it."
+msgstr "Cal autenticació per apagar el sistema mentre que una aplicació ha demanat inhibir-lo."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:31
+msgid "Reboot the system"
+msgstr "Reinicia el sistema"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:32
+msgid "Authentication is required for rebooting the system."
+msgstr "Cal autenticació per reiniciar el sistema."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:33
+msgid "Reboot the system while other users are logged in"
+msgstr "Reinicia el sistema mentre hi ha usuaris amb sessió iniciada"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:34
+msgid ""
+"Authentication is required for rebooting the system while other users are "
+"logged in."
+msgstr "Cal autenticació per reiniciar el sistema mentre hi ha usuaris amb sessió iniciada."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:35
+msgid "Reboot the system while an application asked to inhibit it"
+msgstr "Reinicia el sistema malgrat hi ha una aplicació que ho impedeix"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:36
+msgid ""
+"Authentication is required for rebooting the system while an application "
+"asked to inhibit it."
+msgstr "Cal autenticació per reiniciar el sistema malgrat hi ha una aplicació que ho impedeix."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:37
+msgid "Suspend the system"
+msgstr "Suspèn el sistema"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:38
+msgid "Authentication is required for suspending the system."
+msgstr "Cal autenticació per suspendre el sistema"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:39
+msgid "Suspend the system while other users are logged in"
+msgstr "Suspèn el sistema mentre hi ha altres usuaris amb sessió iniciada"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:40
+msgid ""
+"Authentication is required for suspending the system while other users are "
+"logged in."
+msgstr "Cal autenticació per reiniciar el sistema mentre hi ha usuaris amb sessió iniciada."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:41
+msgid "Suspend the system while an application asked to inhibit it"
+msgstr "Suspèn el sistema mentre una aplicació ha demanat d'inhibir-lo"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:42
+msgid ""
+"Authentication is required for suspending the system while an application "
+"asked to inhibit it."
+msgstr "Cal autenticació per suspendre el sistema mentre una aplicació ha demanat d'inhibir-lo."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:43
+msgid "Hibernate the system"
+msgstr "Hiberna el sistema"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:44
+msgid "Authentication is required for hibernating the system."
+msgstr "Cal autenticació per hibernar el sistema."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:45
+msgid "Hibernate the system while other users are logged in"
+msgstr "Hiberna el sistema mentre hi ha altres usuaris amb sessió iniciada"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:46
+msgid ""
+"Authentication is required for hibernating the system while other users are "
+"logged in."
+msgstr "Cal autenticació per hibernar el sistema mentre hi ha altres usuaris amb sessió iniciada."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:47
+msgid "Hibernate the system while an application asked to inhibit it"
+msgstr "Hiberna el sistema mentre una aplicació ha demanat inhibir-ho"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:48
+msgid ""
+"Authentication is required for hibernating the system while an application "
+"asked to inhibit it."
+msgstr "Cal autenticació per hibernar el sistema mentre una aplicació ha demanat inhibir-ho."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:49
+msgid "Manage active sessions, users and seats"
+msgstr "Gestiona les sessions, usuaris i llocs de treball actius"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:50
+msgid ""
+"Authentication is required for managing active sessions, users and seats."
+msgstr "Cal autenticació per administrar les sessions, usuaris i llocs de treball actius."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:51
+msgid "Lock or unlock active sessions"
+msgstr "Bloqueja o desbloqueja les sessions actives"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:52
+msgid "Authentication is required to lock or unlock active sessions."
+msgstr "Cal autenticació per bloquejar o desbloquejar les sessions actives."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:53
+msgid "Allow indication to the firmware to boot to setup interface"
+msgstr "Permet una indicació al microprogramari per iniciar a la interfície de configuració"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:54
+msgid ""
+"Authentication is required to indicate to the firmware to boot to setup "
+"interface."
+msgstr "Cal autenticació per indicar al microprogramari que iniciï a la interfície de configuració."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:55
+msgid "Set a wall message"
+msgstr "Estableix un missatge de mur"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:56
+msgid "Authentication is required to set a wall message"
+msgstr "Cal autenticació per establir un text de mur"
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:1
+msgid "Log into a local container"
+msgstr "Inicia sessió a un contenidor local"
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:2
+msgid "Authentication is required to log into a local container."
+msgstr "Cal autenticació per iniciar sessió a un contenidor local."
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:3
+msgid "Log into the local host"
+msgstr "Inicia sessió a l'ordinador local"
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:4
+msgid "Authentication is required to log into the local host."
+msgstr "Cal autenticació per iniciar sessió a l'ordinador local."
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:5
+msgid "Acquire a shell in a local container"
+msgstr "Adquireix un intèrpret d'ordres a un contenidor local"
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:6
+msgid "Authentication is required to acquire a shell in a local container."
+msgstr "Cal autenticació per adquirir un intèrpret d'ordres a un contenidor local."
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:7
+msgid "Acquire a shell on the local host"
+msgstr "Adquireix un intèrpret d'ordres a l'ordinador local"
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:8
+msgid "Authentication is required to acquire a shell on the local host."
+msgstr "Cal autenticació per adquirir un intèrpret d'ordres a l'ordinador local."
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:9
+msgid "Acquire a pseudo TTY in a local container"
+msgstr "Adquireix un pseudo-terminal al contenidor local"
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:10
+msgid ""
+"Authentication is required to acquire a pseudo TTY in a local container."
+msgstr "Cal autenticació per adquirir una pseudo-terminal al contenidor local."
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:11
+msgid "Acquire a pseudo TTY on the local host"
+msgstr "Adquireix una pseudo-terminal a l'ordinador local"
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:12
+msgid "Authentication is required to acquire a pseudo TTY on the local host."
+msgstr "Cal autenticació per adquirir una pseudo-terminal a l'ordinador local."
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:13
+msgid "Manage local virtual machines and containers"
+msgstr "Gestiona les màquines virtuals i els contenidors locals "
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:14
+msgid ""
+"Authentication is required to manage local virtual machines and containers."
+msgstr "Cal autenticació per gestionar les màquines virtuals i els contenidors locals."
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:15
+msgid "Manage local virtual machine and container images"
+msgstr "Gestiona les imatges locals de màquines virtuals i contenidors"
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:16
+msgid ""
+"Authentication is required to manage local virtual machine and container "
+"images."
+msgstr "Cal autenticació per gestionar les imatges locals de màquines virtuals i contenidors."
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:1
+msgid "Set system time"
+msgstr "Estableix la data i l'hora del sistema"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:2
+msgid "Authentication is required to set the system time."
+msgstr "Cal autenticació per establir la data i l'hora del sistema."
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:3
+msgid "Set system timezone"
+msgstr "Estableix la zona horària del sistema"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:4
+msgid "Authentication is required to set the system timezone."
+msgstr "Cal autenticació per establir la zona horària del sistema."
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:5
+msgid "Set RTC to local timezone or UTC"
+msgstr "Estableix el rellotge del sistema a la zona horària local o a UTC"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:6
+msgid ""
+"Authentication is required to control whether the RTC stores the local or "
+"UTC time."
+msgstr "Cal autenticació per controlar si el rellotge del sistema emmagatzema la data i l'hora locals o UTC."
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:7
+msgid "Turn network time synchronization on or off"
+msgstr "Activa o desactiva la sincronització de data i hora de xarxa"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:8
+msgid ""
+"Authentication is required to control whether network time synchronization "
+"shall be enabled."
+msgstr "Cal autenticació per controlar si s'ha d'activar la sincronització de data i hora de xarxa."
+
+#: ../src/core/dbus-unit.c:428
+msgid "Authentication is required to start '$(unit)'."
+msgstr "Cal autenticació per iniciar «$(unit)»."
+
+#: ../src/core/dbus-unit.c:429
+msgid "Authentication is required to stop '$(unit)'."
+msgstr "Cal autenticació per aturar «$(unit)»."
+
+#: ../src/core/dbus-unit.c:430
+msgid "Authentication is required to reload '$(unit)'."
+msgstr "Cal autenticació per tornar a carregar «$(unit)»."
+
+#: ../src/core/dbus-unit.c:431 ../src/core/dbus-unit.c:432
+msgid "Authentication is required to restart '$(unit)'."
+msgstr "Cal autenticació per tornar a reiniciar «$(unit)»."
+
+#: ../src/core/dbus-unit.c:535
+msgid "Authentication is required to kill '$(unit)'."
+msgstr "Cal autenticació per matar a «$(unit)»."
+
+#: ../src/core/dbus-unit.c:565
+msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
+msgstr "Cal autenticació per reiniciar l'estat «fallat» de «$(unit)»."
+
+#: ../src/core/dbus-unit.c:597
+msgid "Authentication is required to set properties on '$(unit)'."
+msgstr "Cal autenticació per establir propietats a «$(unit)»."
+
+#~ msgid "Press Ctrl+C to cancel all filesystem checks in progress"
+#~ msgstr ""
+#~ "Presione Ctrl+C para cancelar todas las comprobaciones del sistema de "
+#~ "archivos en curso"
+
+#~ msgid "Checking in progress on %d disk (%3.1f%% complete)"
+#~ msgid_plural "Checking in progress on %d disks (%3.1f%% complete)"
+#~ msgstr[0] "Comprobando progreso en %d disco (%3.1f %% completado)"
+#~ msgstr[1] "Comprobando progreso en %d discos (%3.1f %% completado)"
diff --git a/po/cs.po b/po/cs.po
index d5f1dcafeb..014ed4266c 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -9,24 +9,24 @@ msgstr ""
"Project-Id-Version: systemd master\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-04-23 14:24+0200\n"
-"PO-Revision-Date: 2016-09-22 16:00+0200\n"
+"PO-Revision-Date: 2017-02-07 18:38+0100\n"
"Last-Translator: Daniel Rusek <mail@asciiwolf.com>\n"
"Language: cs\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
-"|| n%100>=20) ? 1 : 2);\n"
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n"
+"%100>=20) ? 1 : 2);\n"
+"Language-Team: \n"
+"X-Generator: Poedit 1.8.7.1\n"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:1
msgid "Send passphrase back to system"
msgstr "Odeslat heslo zpět do systému"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:2
-msgid ""
-"Authentication is required to send the entered passphrase back to the system."
-msgstr ""
-"Autentizace je vyžadována pro odeslání zadaného hesla do systému."
+msgid "Authentication is required to send the entered passphrase back to the system."
+msgstr "Autentizace je vyžadována pro odeslání zadaného hesla do systému."
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:3
msgid "Manage system services or other units"
@@ -35,8 +35,7 @@ msgstr "Správa systémových služeb nebo dalších jednotek"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:4
msgid "Authentication is required to manage system services or other units."
msgstr ""
-"Autentizace je vyžadována pro správu systémových služeb nebo dalších "
-"jednotek."
+"Autentizace je vyžadována pro správu systémových služeb nebo dalších jednotek."
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:5
msgid "Manage system service or unit files"
@@ -48,17 +47,15 @@ msgstr "Autentizace je vyžadována pro správu systémové služby nebo souborÅ
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:7
msgid "Set or unset system and service manager environment variables"
-msgstr ""
-"Nastavení nebo rušení proměnných správce systému a služeb"
-
+msgstr "Nastavení nebo rušení proměnných správce systému a služeb"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:8
msgid ""
-"Authentication is required to set or unset system and service manager "
-"environment variables."
+"Authentication is required to set or unset system and service manager environment "
+"variables."
msgstr ""
-"Autentizace je vyžadována pro nastavení nebo rušení proměnných správce "
-"systému a služeb."
+"Autentizace je vyžadována pro nastavení nebo rušení proměnných správce systému a "
+"služeb."
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:9
msgid "Reload the systemd state"
@@ -82,11 +79,11 @@ msgstr "Nastavení statického názvu stoje"
#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:4
msgid ""
-"Authentication is required to set the statically configured local host name, "
-"as well as the pretty host name."
+"Authentication is required to set the statically configured local host name, as "
+"well as the pretty host name."
msgstr ""
-"Autentizace je vyžadována pro nastavení staticky konfigurovaného názvu "
-"lokálního stroje, stejně tak pro změnu uživatelsky přívětivého jména."
+"Autentizace je vyžadována pro nastavení staticky konfigurovaného názvu lokálního "
+"stroje, stejně tak pro změnu uživatelsky přívětivého jména."
#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:5
msgid "Set machine information"
@@ -137,18 +134,15 @@ msgstr "Nastavení systémové konfigurace klávesnice"
#: ../src/locale/org.freedesktop.locale1.policy.in.h:4
msgid "Authentication is required to set the system keyboard settings."
-msgstr ""
-"Autentizace je vyžadována pro nastavení systémové konfigurace klávesnice."
+msgstr "Autentizace je vyžadována pro nastavení systémové konfigurace klávesnice."
#: ../src/login/org.freedesktop.login1.policy.in.h:1
msgid "Allow applications to inhibit system shutdown"
msgstr "Povolit aplikacím zakázat vypnutí systému"
#: ../src/login/org.freedesktop.login1.policy.in.h:2
-msgid ""
-"Authentication is required for an application to inhibit system shutdown."
-msgstr ""
-"Autentizace je vyžadována pro povolení aplikacím zakázat vypnutí systému."
+msgid "Authentication is required for an application to inhibit system shutdown."
+msgstr "Autentizace je vyžadována pro povolení aplikacím zakázat vypnutí systému."
#: ../src/login/org.freedesktop.login1.policy.in.h:3
msgid "Allow applications to delay system shutdown"
@@ -156,8 +150,7 @@ msgstr "Povolit aplikacím odložit vypnutí systému"
#: ../src/login/org.freedesktop.login1.policy.in.h:4
msgid "Authentication is required for an application to delay system shutdown."
-msgstr ""
-"Autentizace je vyžadována pro povolení aplikacím odložit vypnutí systému."
+msgstr "Autentizace je vyžadována pro povolení aplikacím odložit vypnutí systému."
#: ../src/login/org.freedesktop.login1.policy.in.h:5
msgid "Allow applications to inhibit system sleep"
@@ -165,8 +158,7 @@ msgstr "Povolit aplikacím zakázat uspání systému"
#: ../src/login/org.freedesktop.login1.policy.in.h:6
msgid "Authentication is required for an application to inhibit system sleep."
-msgstr ""
-"Autentizace je vyžadována pro povolení aplikacím zakázat uspání systému."
+msgstr "Autentizace je vyžadována pro povolení aplikacím zakázat uspání systému."
#: ../src/login/org.freedesktop.login1.policy.in.h:7
msgid "Allow applications to delay system sleep"
@@ -174,8 +166,7 @@ msgstr "Povolit aplikacím odložit uspání systému"
#: ../src/login/org.freedesktop.login1.policy.in.h:8
msgid "Authentication is required for an application to delay system sleep."
-msgstr ""
-"Autentizace je vyžadována pro povolení aplikacím odložit uspání systému."
+msgstr "Autentizace je vyžadována pro povolení aplikacím odložit uspání systému."
#: ../src/login/org.freedesktop.login1.policy.in.h:9
msgid "Allow applications to inhibit automatic system suspend"
@@ -183,47 +174,43 @@ msgstr "Povolit aplikacím zakázat automatické vypnutí systému"
#: ../src/login/org.freedesktop.login1.policy.in.h:10
msgid ""
-"Authentication is required for an application to inhibit automatic system "
-"suspend."
+"Authentication is required for an application to inhibit automatic system suspend."
msgstr ""
-"Autentizace je vyžadována pro povolení aplikacím zakázat automatické "
-"vypnutí systému."
+"Autentizace je vyžadována pro povolení aplikacím zakázat automatické vypnutí "
+"systému."
#: ../src/login/org.freedesktop.login1.policy.in.h:11
msgid "Allow applications to inhibit system handling of the power key"
-msgstr ""
-"Povolit aplikacím zakázat chovaní systému na stisknutí vypínacího tlaÄítka"
+msgstr "Povolit aplikacím zakázat chovaní systému na stisknutí vypínacího tlaÄítka"
#: ../src/login/org.freedesktop.login1.policy.in.h:12
msgid ""
-"Authentication is required for an application to inhibit system handling of "
-"the power key."
+"Authentication is required for an application to inhibit system handling of the "
+"power key."
msgstr ""
"Autentizace je vyžadována pro povolení aplikacím zakázat chovaní systému na "
"stisknutí vypínacího tlaÄítka."
#: ../src/login/org.freedesktop.login1.policy.in.h:13
msgid "Allow applications to inhibit system handling of the suspend key"
-msgstr ""
-"Povolit aplikacím zakázat chovaní systému na stisknutí uspávacího tlaÄítka"
+msgstr "Povolit aplikacím zakázat chovaní systému na stisknutí uspávacího tlaÄítka"
#: ../src/login/org.freedesktop.login1.policy.in.h:14
msgid ""
-"Authentication is required for an application to inhibit system handling of "
-"the suspend key."
+"Authentication is required for an application to inhibit system handling of the "
+"suspend key."
msgstr ""
"Autentizace je vyžadována pro povolení aplikacím zakázat chovaní systému na "
"stisknutí uspávacího tlaÄítka."
#: ../src/login/org.freedesktop.login1.policy.in.h:15
msgid "Allow applications to inhibit system handling of the hibernate key"
-msgstr ""
-"Povolit aplikacím zakázat chovaní systému na stisknutí tlaÄítka hibernace"
+msgstr "Povolit aplikacím zakázat chovaní systému na stisknutí tlaÄítka hibernace"
#: ../src/login/org.freedesktop.login1.policy.in.h:16
msgid ""
-"Authentication is required for an application to inhibit system handling of "
-"the hibernate key."
+"Authentication is required for an application to inhibit system handling of the "
+"hibernate key."
msgstr ""
"Autentizace je vyžadována pro povolení aplikacím zakázat chovaní systému na "
"stisknutí tlaÄítka hibernace."
@@ -234,8 +221,8 @@ msgstr "Povolit aplikacím zakázat chovaní systému na zavření víka"
#: ../src/login/org.freedesktop.login1.policy.in.h:18
msgid ""
-"Authentication is required for an application to inhibit system handling of "
-"the lid switch."
+"Authentication is required for an application to inhibit system handling of the "
+"lid switch."
msgstr ""
"Autentizace je vyžadována pro povolení aplikacím zakázat chovaní systému na "
"zavření víka."
@@ -255,8 +242,7 @@ msgstr "Povolit nepřihlášeným uživatelům spouštět programy"
#: ../src/login/org.freedesktop.login1.policy.in.h:22
msgid "Authentication is required to run programs as a non-logged-in user."
-msgstr ""
-"Autentizace je vyžadována ke spuštění programů jako nepřihlášený uživatel."
+msgstr "Autentizace je vyžadována ke spuštění programů jako nepřihlášený uživatel."
#: ../src/login/org.freedesktop.login1.policy.in.h:23
msgid "Allow attaching devices to seats"
@@ -271,8 +257,7 @@ msgid "Flush device to seat attachments"
msgstr "Odstranění přiřazení zařízení ke stanovištím"
#: ../src/login/org.freedesktop.login1.policy.in.h:26
-msgid ""
-"Authentication is required for resetting how devices are attached to seats."
+msgid "Authentication is required for resetting how devices are attached to seats."
msgstr ""
"Autentizace je vyžadována pro reset způsobu jak jsou zařízení přiřazována ke "
"stanovištím."
@@ -294,8 +279,8 @@ msgid ""
"Authentication is required for powering off the system while other users are "
"logged in."
msgstr ""
-"Autentizace je vyžadována pro vypnutí systému, když jsou přihlášeni "
-"další uživatelé."
+"Autentizace je vyžadována pro vypnutí systému, když jsou přihlášeni další "
+"uživatelé."
#: ../src/login/org.freedesktop.login1.policy.in.h:31
msgid "Power off the system while an application asked to inhibit it"
@@ -303,11 +288,11 @@ msgstr "Vypnout systém, i když aplikace požádala o zákaz vypnutí"
#: ../src/login/org.freedesktop.login1.policy.in.h:32
msgid ""
-"Authentication is required for powering off the system while an application "
-"asked to inhibit it."
+"Authentication is required for powering off the system while an application asked "
+"to inhibit it."
msgstr ""
-"Autentizace je vyžadována pro vypnutí systému, když aplikace požádala o "
-"zákaz vypnutí."
+"Autentizace je vyžadována pro vypnutí systému, když aplikace požádala o zákaz "
+"vypnutí."
#: ../src/login/org.freedesktop.login1.policy.in.h:33
msgid "Reboot the system"
@@ -323,11 +308,11 @@ msgstr "Restartovat systém, i když jsou přihlášeni další uživatelé"
#: ../src/login/org.freedesktop.login1.policy.in.h:36
msgid ""
-"Authentication is required for rebooting the system while other users are "
-"logged in."
+"Authentication is required for rebooting the system while other users are logged "
+"in."
msgstr ""
-"Autentizace je vyžadována pro restart systému, když jsou přihlášeni "
-"další uživatelé."
+"Autentizace je vyžadována pro restart systému, když jsou přihlášeni další "
+"uživatelé."
#: ../src/login/org.freedesktop.login1.policy.in.h:37
msgid "Reboot the system while an application asked to inhibit it"
@@ -335,11 +320,11 @@ msgstr "Restartovat systém, i když aplikace požádala o zákaz restartu"
#: ../src/login/org.freedesktop.login1.policy.in.h:38
msgid ""
-"Authentication is required for rebooting the system while an application "
-"asked to inhibit it."
+"Authentication is required for rebooting the system while an application asked to "
+"inhibit it."
msgstr ""
-"Autentizace je vyžadována pro restart systému, když aplikace požádala o "
-"zákaz restartu."
+"Autentizace je vyžadována pro restart systému, když aplikace požádala o zákaz "
+"restartu."
#: ../src/login/org.freedesktop.login1.policy.in.h:39
msgid "Suspend the system"
@@ -355,11 +340,10 @@ msgstr "Uspat systém, i když jsou přihlášeni další uživatelé"
#: ../src/login/org.freedesktop.login1.policy.in.h:42
msgid ""
-"Authentication is required for suspending the system while other users are "
-"logged in."
+"Authentication is required for suspending the system while other users are logged "
+"in."
msgstr ""
-"Autentizace je vyžadována pro uspání systému, když jsou přihlášeni "
-"další uživatelé."
+"Autentizace je vyžadována pro uspání systému, když jsou přihlášeni další uživatelé."
#: ../src/login/org.freedesktop.login1.policy.in.h:43
msgid "Suspend the system while an application asked to inhibit it"
@@ -367,11 +351,11 @@ msgstr "Uspat systém, i když aplikace požádala o zákaz uspání"
#: ../src/login/org.freedesktop.login1.policy.in.h:44
msgid ""
-"Authentication is required for suspending the system while an application "
-"asked to inhibit it."
+"Authentication is required for suspending the system while an application asked to "
+"inhibit it."
msgstr ""
-"Autentizace je vyžadována pro uspání systému, když aplikace požádala o "
-"zákaz uspání."
+"Autentizace je vyžadována pro uspání systému, když aplikace požádala o zákaz "
+"uspání."
#: ../src/login/org.freedesktop.login1.policy.in.h:45
msgid "Hibernate the system"
@@ -387,11 +371,11 @@ msgstr "Hibernovat systém, i když jsou přihlášeni další uživatelé"
#: ../src/login/org.freedesktop.login1.policy.in.h:48
msgid ""
-"Authentication is required for hibernating the system while other users are "
-"logged in."
+"Authentication is required for hibernating the system while other users are logged "
+"in."
msgstr ""
-"Autentizace je vyžadována pro hibernaci systému, když jsou přihlášeni "
-"další uživatelé."
+"Autentizace je vyžadována pro hibernaci systému, když jsou přihlášeni další "
+"uživatelé."
#: ../src/login/org.freedesktop.login1.policy.in.h:49
msgid "Hibernate the system while an application asked to inhibit it"
@@ -399,19 +383,18 @@ msgstr "Hibernace systému, i když aplikace požádala o zákaz hibernace"
#: ../src/login/org.freedesktop.login1.policy.in.h:50
msgid ""
-"Authentication is required for hibernating the system while an application "
-"asked to inhibit it."
+"Authentication is required for hibernating the system while an application asked "
+"to inhibit it."
msgstr ""
-"Autentizace je vyžadována pro hibernaci systému, když aplikace požádala o "
-"zákaz hibernace."
+"Autentizace je vyžadována pro hibernaci systému, když aplikace požádala o zákaz "
+"hibernace."
#: ../src/login/org.freedesktop.login1.policy.in.h:51
msgid "Manage active sessions, users and seats"
msgstr "Správa aktivních sezení, uživatelů a stanovišť"
#: ../src/login/org.freedesktop.login1.policy.in.h:52
-msgid ""
-"Authentication is required for managing active sessions, users and seats."
+msgid "Authentication is required for managing active sessions, users and seats."
msgstr ""
"Autentizace je vyžadována pro správu aktivních sezení, uživatelů a stanovišť."
@@ -429,8 +412,7 @@ msgstr "Povolit indikaci firmwaru bootovat instalaÄní prostÅ™edí"
#: ../src/login/org.freedesktop.login1.policy.in.h:56
msgid ""
-"Authentication is required to indicate to the firmware to boot to setup "
-"interface."
+"Authentication is required to indicate to the firmware to boot to setup interface."
msgstr ""
"Autentizace je vyžadována k povolení indikace firmwaru bootovat instalaÄní "
"prostředí."
@@ -480,8 +462,7 @@ msgid "Acquire a pseudo TTY in a local container"
msgstr "Získání Pseudo TTY v lokálním kontejneru"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:10
-msgid ""
-"Authentication is required to acquire a pseudo TTY in a local container."
+msgid "Authentication is required to acquire a pseudo TTY in a local container."
msgstr "Autentizace je vyžadována pro získání pseudo TTY v lokálním kontejneru."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:11
@@ -497,8 +478,7 @@ msgid "Manage local virtual machines and containers"
msgstr "Spravovat lokální virtuální stroje a kontejnery"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:14
-msgid ""
-"Authentication is required to manage local virtual machines and containers."
+msgid "Authentication is required to manage local virtual machines and containers."
msgstr ""
"Autentizace je vyžadována pro správu lokálních virtuálních strojů a kontejnerů."
@@ -508,10 +488,8 @@ msgstr "Spravovat lokální obrazy virtuálních strojů a kontejnerů"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:16
msgid ""
-"Authentication is required to manage local virtual machine and container "
-"images."
-msgstr ""
-"Autentizace je vyžadována ke správě obrazů virtuálních strojů a kontejnerů."
+"Authentication is required to manage local virtual machine and container images."
+msgstr "Autentizace je vyžadována ke správě obrazů virtuálních strojů a kontejnerů."
#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:1
msgid "Set system time"
@@ -535,11 +513,10 @@ msgstr "Nastavit RTC na lokální Äasovou zónu nebo UTC"
#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:6
msgid ""
-"Authentication is required to control whether the RTC stores the local or "
-"UTC time."
+"Authentication is required to control whether the RTC stores the local or UTC time."
msgstr ""
-"Autentizace je vyžadována pro kontrolu jestli RTC ukládá lokální Äasovou "
-"zónu nebo UTC Äas."
+"Autentizace je vyžadována pro kontrolu jestli RTC ukládá lokální Äasovou zónu nebo "
+"UTC Äas."
#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:7
msgid "Turn network time synchronization on or off"
@@ -547,36 +524,34 @@ msgstr "Zapnout nebo vypnout synchronizaci s Äasem ze sítÄ›"
#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:8
msgid ""
-"Authentication is required to control whether network time synchronization "
-"shall be enabled."
+"Authentication is required to control whether network time synchronization shall "
+"be enabled."
msgstr "Autentizace je vyžadována pro kontrolu synchronizace Äasu ze sítÄ›."
-#: ../src/core/dbus-unit.c:450
+#: ../src/core/dbus-unit.c:459
msgid "Authentication is required to start '$(unit)'."
msgstr "Autentizace je vyžadována pro spuÅ¡tÄ›ní „$(unit)â€."
-#: ../src/core/dbus-unit.c:451
+#: ../src/core/dbus-unit.c:460
msgid "Authentication is required to stop '$(unit)'."
msgstr "Autentizace je vyžadována pro vypnutí „$(unit)â€."
-#: ../src/core/dbus-unit.c:452
+#: ../src/core/dbus-unit.c:461
msgid "Authentication is required to reload '$(unit)'."
msgstr "Autentizace je vyžadována pro znovu naÄtení „$(unit)â€."
-#: ../src/core/dbus-unit.c:453 ../src/core/dbus-unit.c:454
+#: ../src/core/dbus-unit.c:462 ../src/core/dbus-unit.c:463
msgid "Authentication is required to restart '$(unit)'."
msgstr "Autentizace je vyžadována pro restart „$(unit)â€."
-#: ../src/core/dbus-unit.c:560
+#: ../src/core/dbus-unit.c:570
msgid "Authentication is required to kill '$(unit)'."
msgstr "Autentizace je vyžadována pro ukonÄení „$(unit)â€."
-#: ../src/core/dbus-unit.c:590
+#: ../src/core/dbus-unit.c:601
msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
-msgstr ""
-"Autentizace je vyžadována pro resetování chybného stavu "
-"„$(unit)â€."
+msgstr "Autentizace je vyžadována pro resetování chybného stavu „$(unit)â€."
-#: ../src/core/dbus-unit.c:622
+#: ../src/core/dbus-unit.c:634
msgid "Authentication is required to set properties on '$(unit)'."
msgstr "Autentizace je vyžadována pro nastavení vlastností na „$(unit)â€."
diff --git a/po/hr.po b/po/hr.po
index a0aff4331f..e98e88aeb7 100644
--- a/po/hr.po
+++ b/po/hr.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: systemd master\n"
"Report-Msgid-Bugs-To: https://github.com/systemd/systemd/issues\n"
-"POT-Creation-Date: 2016-27-04 11:57+0100\n"
+"POT-Creation-Date: 2016-04-27 11:57+0100\n"
"PO-Revision-Date: 2016-04-27 12:11+0200\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
diff --git a/po/id.po b/po/id.po
index 72eb94c7ec..72eb94c7ec 100755..100644
--- a/po/id.po
+++ b/po/id.po
diff --git a/rules/50-udev-default.rules b/rules/50-udev-default.rules
index e9eeb8518e..3347c8cd89 100644
--- a/rules/50-udev-default.rules
+++ b/rules/50-udev-default.rules
@@ -74,4 +74,6 @@ KERNEL=="tun", MODE="0666", OPTIONS+="static_node=net/tun"
KERNEL=="fuse", MODE="0666", OPTIONS+="static_node=fuse"
+SUBSYSTEM=="ptp", ATTR{clock_name}=="KVM virtual PTP", SYMLINK += "ptp_kvm"
+
LABEL="default_end"
diff --git a/rules/60-block.rules b/rules/60-block.rules
index 42c75974a5..343fc06f85 100644
--- a/rules/60-block.rules
+++ b/rules/60-block.rules
@@ -8,4 +8,4 @@ ACTION=="add", SUBSYSTEM=="module", KERNEL=="block", ATTR{parameters/events_dfl_
ACTION=="change", SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", TEST=="block", ATTR{block/*/uevent}="change"
# watch metadata changes, caused by tools closing the device node which was opened for writing
-ACTION!="remove", SUBSYSTEM=="block", KERNEL=="loop*|nvme*|sd*|vd*|xvd*|pmem*", OPTIONS+="watch"
+ACTION!="remove", SUBSYSTEM=="block", KERNEL=="loop*|nvme*|sd*|vd*|xvd*|pmem*|mmcblk*", OPTIONS+="watch"
diff --git a/rules/60-cdrom_id.rules b/rules/60-cdrom_id.rules
index 5c3b52ebb9..f91d8cb456 100644
--- a/rules/60-cdrom_id.rules
+++ b/rules/60-cdrom_id.rules
@@ -8,6 +8,10 @@ ENV{DEVTYPE}!="disk", GOTO="cdrom_end"
# unconditionally tag device as CDROM
KERNEL=="sr[0-9]*", ENV{ID_CDROM}="1"
+# stop automatically any mount units bound to the device if the media eject
+# button is pressed.
+ENV{ID_CDROM}=="1", ENV{SYSTEMD_MOUNT_DEVICE_BOUND}="1"
+
# media eject button pressed
ENV{DISK_EJECT_REQUEST}=="?*", RUN+="cdrom_id --eject-media $devnode", GOTO="cdrom_end"
diff --git a/rules/60-drm.rules b/rules/60-drm.rules
index 1ed3e445f2..f7f3435d50 100644
--- a/rules/60-drm.rules
+++ b/rules/60-drm.rules
@@ -1,3 +1,8 @@
# do not edit this file, it will be overwritten on update
ACTION!="remove", SUBSYSTEM=="drm", SUBSYSTEMS=="pci|usb|platform", IMPORT{builtin}="path_id"
+
+# by-path
+ENV{ID_PATH}=="?*", KERNEL=="card*", SYMLINK+="dri/by-path/$env{ID_PATH}-card"
+ENV{ID_PATH}=="?*", KERNEL=="controlD*", SYMLINK+="dri/by-path/$env{ID_PATH}-control"
+ENV{ID_PATH}=="?*", KERNEL=="renderD*", SYMLINK+="dri/by-path/$env{ID_PATH}-render"
diff --git a/rules/60-evdev.rules b/rules/60-evdev.rules
index ade7e7f646..f5d5ba6a5f 100644
--- a/rules/60-evdev.rules
+++ b/rules/60-evdev.rules
@@ -12,6 +12,10 @@ ENV{ID_INPUT_KEY}=="?*", DRIVERS=="atkbd", \
IMPORT{builtin}="hwdb 'evdev:atkbd:$attr{[dmi/id]modalias}'", \
RUN{builtin}+="keyboard", GOTO="evdev_end"
+# device matching the input device name + properties + the machine's DMI data
+KERNELS=="input*", IMPORT{builtin}="hwdb 'evdev:name:$attr{name}:phys:$attr{phys}:ev:$attr{capabilities/ev}:$attr{[dmi/id]modalias}'", \
+ RUN{builtin}+="keyboard", GOTO="evdev_end"
+
# device matching the input device name and the machine's DMI data
KERNELS=="input*", IMPORT{builtin}="hwdb 'evdev:name:$attr{name}:$attr{[dmi/id]modalias}'", \
RUN{builtin}+="keyboard", GOTO="evdev_end"
diff --git a/rules/60-persistent-storage.rules b/rules/60-persistent-storage.rules
index c13d05cdb1..d2745f65f4 100644
--- a/rules/60-persistent-storage.rules
+++ b/rules/60-persistent-storage.rules
@@ -7,7 +7,7 @@ ACTION=="remove", GOTO="persistent_storage_end"
ENV{UDEV_DISABLE_PERSISTENT_STORAGE_RULES_FLAG}=="1", GOTO="persistent_storage_end"
SUBSYSTEM!="block", GOTO="persistent_storage_end"
-KERNEL!="loop*|mmcblk*[0-9]|msblk*[0-9]|mspblk*[0-9]|nvme*|sd*|sr*|vd*|xvd*|bcache*|cciss*|dasd*|ubd*|scm*|pmem*", GOTO="persistent_storage_end"
+KERNEL!="loop*|mmcblk*[0-9]|msblk*[0-9]|mspblk*[0-9]|nvme*|sd*|sr*|vd*|xvd*|bcache*|cciss*|dasd*|ubd*|scm*|pmem*|nbd*", GOTO="persistent_storage_end"
# ignore partitions that span the entire disk
TEST=="whole_disk", GOTO="persistent_storage_end"
@@ -20,6 +20,7 @@ KERNEL=="nvme*[0-9]n*[0-9]", ATTR{wwid}=="?*", SYMLINK+="disk/by-id/nvme-$attr{w
KERNEL=="nvme*[0-9]n*[0-9]p*[0-9]", ENV{DEVTYPE}=="partition", ATTRS{wwid}=="?*", SYMLINK+="disk/by-id/nvme-$attr{wwid}-part%n"
KERNEL=="nvme*[0-9]n*[0-9]", ENV{DEVTYPE}=="disk", ATTRS{serial}=="?*", ENV{ID_SERIAL_SHORT}="$attr{serial}"
+KERNEL=="nvme*[0-9]n*[0-9]", ENV{DEVTYPE}=="disk", ATTRS{wwid}=="?*", ENV{ID_WWN}="$attr{wwid}"
KERNEL=="nvme*[0-9]n*[0-9]", ENV{DEVTYPE}=="disk", ATTRS{model}=="?*", ENV{ID_SERIAL_SHORT}=="?*", ENV{ID_SERIAL}="$attr{model}_$env{ID_SERIAL_SHORT}", SYMLINK+="disk/by-id/nvme-$env{ID_SERIAL}"
KERNEL=="nvme*[0-9]n*[0-9]p*[0-9]", ENV{DEVTYPE}=="partition", ATTRS{serial}=="?*", ENV{ID_SERIAL_SHORT}="$attr{serial}"
@@ -54,7 +55,7 @@ KERNEL=="sd*[0-9]", ATTRS{ieee1394_id}=="?*", SYMLINK+="disk/by-id/ieee1394-$att
# MMC
KERNEL=="mmcblk[0-9]", SUBSYSTEMS=="mmc", ATTRS{name}=="?*", ATTRS{serial}=="?*", \
ENV{ID_NAME}="$attr{name}", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}"
-KERNEL=="mmcblk[0-9]p[0-9]", ENV{ID_NAME}=="?*", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}-part%n"
+KERNEL=="mmcblk[0-9]p[0-9]*", ENV{ID_NAME}=="?*", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}-part%n"
# Memstick
KERNEL=="msblk[0-9]|mspblk[0-9]", SUBSYSTEMS=="memstick", ATTRS{name}=="?*", ATTRS{serial}=="?*", \
@@ -63,9 +64,14 @@ KERNEL=="msblk[0-9]p[0-9]|mspblk[0-9]p[0-9]", ENV{ID_NAME}=="?*", ENV{ID_SERIAL}
# by-path
ENV{DEVTYPE}=="disk", DEVPATH!="*/virtual/*", IMPORT{builtin}="path_id"
-ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}"
+KERNEL=="mmcblk[0-9]boot[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-boot%n"
+KERNEL!="mmcblk[0-9]boot[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}"
ENV{DEVTYPE}=="partition", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n"
+# legacy virtio-pci by-path links (deprecated)
+KERNEL=="vd*[!0-9]", ENV{ID_PATH}=="pci-*", SYMLINK+="disk/by-path/virtio-$env{ID_PATH}"
+KERNEL=="vd*[0-9]", ENV{ID_PATH}=="pci-*", SYMLINK+="disk/by-path/virtio-$env{ID_PATH}-part%n"
+
# probe filesystem metadata of optical drives which have a media inserted
KERNEL=="sr*", ENV{DISK_EJECT_REQUEST}!="?*", ENV{ID_CDROM_MEDIA_TRACK_COUNT_DATA}=="?*", ENV{ID_CDROM_MEDIA_SESSION_LAST_OFFSET}=="?*", \
IMPORT{builtin}="blkid --offset=$env{ID_CDROM_MEDIA_SESSION_LAST_OFFSET}"
@@ -88,7 +94,4 @@ ENV{DEVTYPE}=="partition", ENV{ID_WWN_WITH_EXTENSION}=="?*", SYMLINK+="disk/by-i
ENV{ID_PART_ENTRY_UUID}=="?*", SYMLINK+="disk/by-partuuid/$env{ID_PART_ENTRY_UUID}"
ENV{ID_PART_ENTRY_SCHEME}=="gpt", ENV{ID_PART_ENTRY_NAME}=="?*", SYMLINK+="disk/by-partlabel/$env{ID_PART_ENTRY_NAME}"
-# add symlink to GPT root disk
-ENV{ID_PART_ENTRY_SCHEME}=="gpt", ENV{ID_PART_GPT_AUTO_ROOT}=="1", SYMLINK+="gpt-auto-root"
-
LABEL="persistent_storage_end"
diff --git a/rules/60-sensor.rules b/rules/60-sensor.rules
new file mode 100644
index 0000000000..82e44f8843
--- /dev/null
+++ b/rules/60-sensor.rules
@@ -0,0 +1,10 @@
+# do not edit this file, it will be overwritten on update
+
+ACTION=="remove", GOTO="sensor_end"
+
+# device matching the sensor's name and the machine's DMI data for IIO devices
+SUBSYSTEM=="iio", KERNEL=="iio*", SUBSYSTEMS=="usb|i2c", \
+ IMPORT{builtin}="hwdb 'sensor:modalias:$attr{modalias}:$attr{[dmi/id]modalias}'", \
+ GOTO="sensor_end"
+
+LABEL="sensor_end"
diff --git a/rules/78-sound-card.rules b/rules/78-sound-card.rules
index 04740e8b97..f2fc277396 100644
--- a/rules/78-sound-card.rules
+++ b/rules/78-sound-card.rules
@@ -48,6 +48,13 @@ SUBSYSTEMS=="firewire", ATTRS{guid}=="?*", \
SUBSYSTEMS=="firewire", GOTO="skip_pci"
SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}"
+SUBSYSTEMS=="pci", GOTO="skip_pci"
+
+# If we reach here, the device nor any of its parents are USB/PCI/firewire bus devices.
+# If we now find a parent that is a platform device, assume that we're working with
+# an internal sound card.
+SUBSYSTEMS=="platform", ENV{SOUND_FORM_FACTOR}="internal", GOTO="sound_end"
+
LABEL="skip_pci"
# Define ID_ID if ID_BUS and ID_SERIAL are set. This will work for both
diff --git a/rules/99-systemd.rules.in b/rules/99-systemd.rules.in
index ca52cf165b..edd1faa17a 100644
--- a/rules/99-systemd.rules.in
+++ b/rules/99-systemd.rules.in
@@ -10,6 +10,8 @@ ACTION=="remove", GOTO="systemd_end"
SUBSYSTEM=="tty", KERNEL=="tty[a-zA-Z]*|hvc*|xvc*|hvsi*|ttysclp*|sclp_line*|3270/tty[0-9]*", TAG+="systemd"
KERNEL=="vport*", TAG+="systemd"
+SUBSYSTEM=="ubi", TAG+="systemd"
+
SUBSYSTEM=="block", TAG+="systemd"
SUBSYSTEM=="block", ACTION=="add", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", ENV{SYSTEMD_READY}="0"
@@ -17,6 +19,11 @@ SUBSYSTEM=="block", ACTION=="add", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", E
# we are probably still calling mke2fs or mkswap on it.
SUBSYSTEM=="block", ENV{DM_UUID}=="CRYPT-*", ENV{ID_PART_TABLE_TYPE}=="", ENV{ID_FS_USAGE}=="", ENV{SYSTEMD_READY}="0"
+# add symlink to GPT root disk
+SUBSYSTEM=="block", ENV{ID_PART_GPT_AUTO_ROOT}=="1", ENV{ID_FS_TYPE}!="crypto_LUKS", SYMLINK+="gpt-auto-root"
+SUBSYSTEM=="block", ENV{ID_PART_GPT_AUTO_ROOT}=="1", ENV{ID_FS_TYPE}=="crypto_LUKS", SYMLINK+="gpt-auto-root-luks"
+SUBSYSTEM=="block", ENV{DM_UUID}=="CRYPT-*", ENV{DM_NAME}=="root", SYMLINK+="gpt-auto-root"
+
# Ignore raid devices that are not yet assembled and started
SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", KERNEL=="md*", TEST!="md/array_state", ENV{SYSTEMD_READY}="0"
SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", KERNEL=="md*", ATTR{md/array_state}=="|clear|inactive", ENV{SYSTEMD_READY}="0"
diff --git a/shell-completion/bash/coredumpctl b/shell-completion/bash/coredumpctl
index 6091677506..87fe473e09 100644
--- a/shell-completion/bash/coredumpctl
+++ b/shell-completion/bash/coredumpctl
@@ -37,7 +37,8 @@ __journal_fields=(MESSAGE{,_ID} PRIORITY CODE_{FILE,LINE,FUNC}
_coredumpctl() {
local i verb comps
local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
- local OPTS='-h --help --version --no-pager --no-legend -o --output -F --field -1'
+ local OPTS='-h --help --version --no-pager --no-legend -o --output -F --field -1
+ -r --reverse -S --since -U --until'
local -A VERBS=(
[LIST]='list'
diff --git a/shell-completion/bash/hostnamectl b/shell-completion/bash/hostnamectl
index 6a252188ea..7cf8b6f631 100644
--- a/shell-completion/bash/hostnamectl
+++ b/shell-completion/bash/hostnamectl
@@ -52,7 +52,7 @@ _hostnamectl() {
if [[ -z $verb ]]; then
comps=${VERBS[*]}
elif __contains_word "$verb" ${VERBS[CHASSIS]}; then
- comps='desktop laptop server tablet handset watch embedded vm container'
+ comps='desktop laptop convertible server tablet handset watch embedded vm container'
elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[ICONS]} ${VERBS[NAME]}; then
comps=''
fi
diff --git a/shell-completion/bash/journalctl b/shell-completion/bash/journalctl
index a999a10df1..c90a114497 100644
--- a/shell-completion/bash/journalctl
+++ b/shell-completion/bash/journalctl
@@ -42,10 +42,10 @@ _journalctl() {
--version --list-catalog --update-catalog --list-boots
--show-cursor --dmesg -k --pager-end -e -r --reverse
--utc -x --catalog --no-full --force --dump-catalog
- --flush --rotate --sync'
+ --flush --rotate --sync --no-hostname'
[ARG]='-b --boot --this-boot -D --directory --file -F --field
-M --machine -o --output -u --unit --user-unit -p --priority
- --vacuum-size --vacuum-time'
+ --vacuum-size --vacuum-time --vacuum-files'
[ARGUNKNOWN]='-c --cursor --interval -n --lines -S --since -U --until
--after-cursor --verify-key -t --identifier
--root'
@@ -82,6 +82,9 @@ _journalctl() {
--user-unit)
comps=$(journalctl -F '_SYSTEMD_USER_UNIT' 2>/dev/null)
;;
+ --identifier|-t)
+ comps=$(journalctl -F 'SYSLOG_IDENTIFIER' 2>/dev/null)
+ ;;
*)
return 0
;;
diff --git a/shell-completion/bash/systemctl.in b/shell-completion/bash/systemctl.in
index dcf71a1f51..3e553c1e6c 100644
--- a/shell-completion/bash/systemctl.in
+++ b/shell-completion/bash/systemctl.in
@@ -19,7 +19,7 @@
__systemctl() {
local mode=$1; shift 1
- systemctl $mode --full --no-legend "$@"
+ systemctl $mode --full --no-legend "$@" 2>/dev/null
}
__systemd_properties() {
@@ -124,9 +124,9 @@ _systemctl () {
local -A OPTS=(
[STANDALONE]='--all -a --reverse --after --before --defaults --force -f --full -l --global
- --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall
+ --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall --now
--quiet -q --privileged -P --system --user --version --runtime --recursive -r --firmware-setup
- --show-types -i --ignore-inhibitors --plain'
+ --show-types -i --ignore-inhibitors --plain --failed'
[ARG]='--host -H --kill-who --property -p --signal -s --type -t --state --job-mode --root
--preset-mode -n --lines -o --output -M --machine'
)
@@ -189,7 +189,7 @@ _systemctl () {
fi
local -A VERBS=(
- [ALL_UNITS]='is-active is-failed is-enabled status show cat mask preset help list-dependencies edit set-property'
+ [ALL_UNITS]='is-active is-failed is-enabled status show cat mask preset help list-dependencies edit set-property revert'
[ENABLED_UNITS]='disable'
[DISABLED_UNITS]='enable'
[REENABLABLE_UNITS]='reenable'
diff --git a/shell-completion/bash/systemd-analyze b/shell-completion/bash/systemd-analyze
index 7a5f46ba1d..92ff13d316 100644
--- a/shell-completion/bash/systemd-analyze
+++ b/shell-completion/bash/systemd-analyze
@@ -45,6 +45,7 @@ _systemd_analyze() {
[DOT]='dot'
[LOG_LEVEL]='set-log-level'
[VERIFY]='verify'
+ [SECCOMP_FILTER]='syscall-filter'
)
_init_completion || return
@@ -100,6 +101,11 @@ _systemd_analyze() {
comps='debug info notice warning err crit alert emerg'
fi
+ elif __contains_word "$verb" ${VERBS[SECCOMP_FILTER]}; then
+ if [[ $cur = -* ]]; then
+ comps='--help --version'
+ fi
+
elif __contains_word "$verb" ${VERBS[VERIFY]}; then
if [[ $cur = -* ]]; then
comps='--help --version --system --user --man'
diff --git a/shell-completion/zsh/_coredumpctl b/shell-completion/zsh/_coredumpctl
index e4c04a697f..e469bca958 100644
--- a/shell-completion/zsh/_coredumpctl
+++ b/shell-completion/zsh/_coredumpctl
@@ -32,6 +32,9 @@ _arguments \
{-o+,--output=}'[Write output to FILE]:output file:_files' \
{-F+,--field=}'[Show field in list output]:field' \
'-1[Show information about most recent entry only]' \
+ {-S,--since}'[Print entries since the specified date]' \
+ {-U,--until}'[Print entries until the specified date]' \
+ {-r,--reverse}'[Show the newest entries first]' \
'--no-pager[Do not pipe output into a pager]' \
'--no-legend[Do not print the column headers]' \
{-h,--help}'[Show this help]' \
diff --git a/shell-completion/zsh/_hostnamectl b/shell-completion/zsh/_hostnamectl
index 7528e0649d..8c4a354af2 100644
--- a/shell-completion/zsh/_hostnamectl
+++ b/shell-completion/zsh/_hostnamectl
@@ -18,7 +18,7 @@ _hostnamectl_set-icon-name() {
_hostnamectl_set-chassis() {
if (( CURRENT <= 3 )); then
- _chassis=( desktop laptop server tablet handset watch embedded vm container )
+ _chassis=( desktop laptop convertible server tablet handset watch embedded vm container )
_describe chassis _chassis
else
_message "no more options"
diff --git a/shell-completion/zsh/_journalctl b/shell-completion/zsh/_journalctl
index ef67fcf2a0..4a78a2e946 100644
--- a/shell-completion/zsh/_journalctl
+++ b/shell-completion/zsh/_journalctl
@@ -107,8 +107,8 @@ _arguments -s \
'--user[Show messages from user services]' \
'(--directory -D -M --machine --root --file)'{-M+,--machine=}'[Operate on local container]:machines:_sd_machines' \
'(--directory -D -M --machine --root --file)'{-D+,--directory=}'[Show journal files from directory]:directories:_directories' \
- '(--directory -D -M --machine --root --file)''--root=[Operate on catalog hierarchy under specified directory]:directories:_directories' \
- '(--directory -D -M --machine --root)--file=[Operate on specified journal files]:file:_files' \
+ '(--directory -D -M --machine --root --file)--root=[Operate on catalog hierarchy under specified directory]:directories:_directories' \
+ '(--directory -D -M --machine --root)*--file=[Operate on specified journal files]:file:_files' \
'--new-id128[Generate a new 128 Bit ID]' \
'--header[Show journal header information]' \
'--disk-usage[Show total disk usage]' \
diff --git a/shell-completion/zsh/_systemctl.in b/shell-completion/zsh/_systemctl.in
index 03a1c930b0..aad700b739 100644
--- a/shell-completion/zsh/_systemctl.in
+++ b/shell-completion/zsh/_systemctl.in
@@ -29,6 +29,8 @@
"list-unit-files:List installed unit files"
"enable:Enable one or more unit files"
"disable:Disable one or more unit files"
+ "add-wants:Add Wants= dependencies to a unit"
+ "add-requires:Add Requires= dependencies to a unit"
"reenable:Reenable one or more unit files"
"preset:Enable/disable one or more unit files based on preset configuration"
"set-default:Set the default target"
@@ -58,6 +60,7 @@
"kexec:Shut down and reboot the system with kexec"
"exit:Ask for user instance termination"
"switch-root:Change root directory"
+ "revert:Revert unit files to their vendor versions"
)
if (( CURRENT == 1 )); then
@@ -91,18 +94,18 @@
__systemctl()
{
- systemctl $_sys_service_mgr --full --no-legend --no-pager "$@"
+ systemctl $_sys_service_mgr --full --no-legend --no-pager "$@" 2>/dev/null
}
# Fills the unit list
_systemctl_all_units()
{
- if ( [[ ${+_sys_all_units} -eq 0 ]] || _cache_invalid SYS_ALL_UNITS ) &&
- ! _retrieve_cache SYS_ALL_UNITS;
+ if ( [[ ${+_sys_all_units} -eq 0 ]] || _cache_invalid SYS_ALL_UNITS$_sys_service_mgr ) ||
+ ! _retrieve_cache SYS_ALL_UNITS$_sys_service_mgr;
then
_sys_all_units=( ${${(f)"$(__systemctl list-units --all)"}%% *} )
- _store_cache SYS_ALL_UNITS _sys_all_units
+ _store_cache SYS_ALL_UNITS$_sys_service_mgr _sys_all_units
fi
}
@@ -111,14 +114,14 @@ _systemctl_really_all_units()
{
local -a all_unit_files;
local -a really_all_units;
- if ( [[ ${+_sys_really_all_units} -eq 0 ]] || _cache_invalid SYS_REALLY_ALL_UNITS ) &&
- ! _retrieve_cache SYS_REALLY_ALL_UNITS;
+ if ( [[ ${+_sys_really_all_units} -eq 0 ]] || _cache_invalid SYS_REALLY_ALL_UNITS$_sys_service_mgr ) ||
+ ! _retrieve_cache SYS_REALLY_ALL_UNITS$_sys_service_mgr;
then
all_unit_files=( ${${(f)"$(__systemctl list-unit-files)"}%% *} )
_systemctl_all_units
really_all_units=($_sys_all_units $all_unit_files)
_sys_really_all_units=(${(u)really_all_units})
- _store_cache SYS_REALLY_ALL_UNITS _sys_really_all_units
+ _store_cache SYS_REALLY_ALL_UNITS$_sys_service_mgr _sys_really_all_units
fi
}
@@ -157,7 +160,7 @@ _systemctl_unit_state() { typeset -gA _sys_unit_state; _sys_unit_state=( $(__sys
local fun
# Completion functions for ALL_UNITS
-for fun in is-active is-failed is-enabled status show cat mask preset help list-dependencies edit ; do
+for fun in is-active is-failed is-enabled status show cat mask preset help list-dependencies edit revert add-wants add-requires ; do
(( $+functions[_systemctl_$fun] )) || _systemctl_$fun()
{
_systemctl_really_all_units
@@ -330,13 +333,13 @@ _unit_types() {
}
_unit_properties() {
- if ( [[ ${+_sys_all_properties} -eq 0 ]] || _cache_invalid SYS_ALL_PROPERTIES ) &&
- ! _retrieve_cache SYS_ALL_PROPERTIES;
+ if ( [[ ${+_sys_all_properties} -eq 0 ]] || _cache_invalid SYS_ALL_PROPERTIES$_sys_service_mgr ) ||
+ ! _retrieve_cache SYS_ALL_PROPERTIES$_sys_service_mgr;
then
_sys_all_properties=( ${${(M)${(f)"$(__systemctl show --all;
@rootlibexecdir@/systemd --dump-configuration-items)"}##[[:alnum:]]##=*}%%=*}
)
- _store_cache SYS_ALL_PROPRTIES _sys_all_properties
+ _store_cache SYS_ALL_PROPERTIES$_sys_service_mgr _sys_all_properties
fi
_values -s , "${_sys_all_properties[@]}"
}
@@ -386,4 +389,5 @@ _arguments -s \
{-o+,--output=}'[Change journal output mode]:modes:_sd_outputmodes' \
'--firmware-setup[Tell the firmware to show the setup menu on next boot]' \
'--plain[When used with list-dependencies, print output as a list]' \
+ '--failed[Show failed units]' \
'*::systemctl command:_systemctl_command'
diff --git a/shell-completion/zsh/_systemd-analyze b/shell-completion/zsh/_systemd-analyze
index efafddc686..0e670034c1 100644
--- a/shell-completion/zsh/_systemd-analyze
+++ b/shell-completion/zsh/_systemd-analyze
@@ -21,6 +21,7 @@ _systemd_analyze_command(){
'dot:Dump dependency graph (in dot(1) format)'
'dump:Dump server status'
'set-log-level:Set systemd log threshold'
+ 'syscall-filter:List syscalls in seccomp filter'
'verify:Check unit files for correctness'
)
diff --git a/shell-completion/zsh/_systemd-run b/shell-completion/zsh/_systemd-run
index da9f73a6d0..5c3e65c223 100644
--- a/shell-completion/zsh/_systemd-run
+++ b/shell-completion/zsh/_systemd-run
@@ -51,10 +51,10 @@ _arguments \
'--nice=[Nice level]:nice level' \
'--setenv=[Set environment]:NAME=VALUE' \
'--on-active=[Run after SEC seconds]:SEC' \
- '--on-boot=[Run after SEC seconds from machine was booted up]:SEC' \
- '--on-statup=[Run after SEC seconds from systemd was first started]:SEC' \
- '--on-unit-active=[Run after SEC seconds from the last activation]:SEC' \
- '--on-unit-inactive=[Run after SEC seconds from the last deactivation]:SEC' \
+ '--on-boot=[Run SEC seconds after machine was booted up]:SEC' \
+ '--on-startup=[Run SEC seconds after systemd was first started]:SEC' \
+ '--on-unit-active=[Run SEC seconds after the last activation]:SEC' \
+ '--on-unit-inactive=[Run SEC seconds after the last deactivation]:SEC' \
'--on-calendar=[Realtime timer]:SPEC' \
'--timer-property=[Set timer unit property]:NAME=VALUE' \
'--wait=[Wait until service stopped again]' \
diff --git a/src/activate/activate.c b/src/activate/activate.c
index a0cfc22000..6ebd820410 100644
--- a/src/activate/activate.c
+++ b/src/activate/activate.c
@@ -339,7 +339,7 @@ static void sigchld_hdl(int sig) {
static int install_chld_handler(void) {
static const struct sigaction act = {
- .sa_flags = SA_NOCLDSTOP,
+ .sa_flags = SA_NOCLDSTOP|SA_RESTART,
.sa_handler = sigchld_hdl,
};
diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c
index 66830695f3..36b01500ca 100644
--- a/src/analyze/analyze.c
+++ b/src/analyze/analyze.c
@@ -36,6 +36,9 @@
#include "log.h"
#include "pager.h"
#include "parse-util.h"
+#ifdef HAVE_SECCOMP
+#include "seccomp-util.h"
+#endif
#include "special.h"
#include "strv.h"
#include "strxcpyx.h"
@@ -458,6 +461,7 @@ static int acquire_host_info(sd_bus *bus, struct host_info **hi) {
"org.freedesktop.hostname1",
"/org/freedesktop/hostname1",
hostname_map,
+ &error,
host);
if (r < 0)
log_debug_errno(r, "Failed to get host information from systemd-hostnamed: %s", bus_error_message(&error, r));
@@ -466,6 +470,7 @@ static int acquire_host_info(sd_bus *bus, struct host_info **hi) {
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
manager_map,
+ &error,
host);
if (r < 0)
return log_error_errno(r, "Failed to get host information from systemd: %s", bus_error_message(&error, r));
@@ -1275,36 +1280,94 @@ static int set_log_target(sd_bus *bus, char **args) {
return 0;
}
+#ifdef HAVE_SECCOMP
+static void dump_syscall_filter(const SyscallFilterSet *set) {
+ const char *syscall;
+
+ printf("%s\n", set->name);
+ printf(" # %s\n", set->help);
+ NULSTR_FOREACH(syscall, set->value)
+ printf(" %s\n", syscall);
+}
+
+static int dump_syscall_filters(char** names) {
+ bool first = true;
+
+ pager_open(arg_no_pager, false);
+
+ if (strv_isempty(names)) {
+ int i;
+
+ for (i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) {
+ if (!first)
+ puts("");
+ dump_syscall_filter(syscall_filter_sets + i);
+ first = false;
+ }
+ } else {
+ char **name;
+
+ STRV_FOREACH(name, names) {
+ const SyscallFilterSet *set;
+
+ if (!first)
+ puts("");
+
+ set = syscall_filter_set_find(*name);
+ if (!set) {
+ /* make sure the error appears below normal output */
+ fflush(stdout);
+
+ log_error("Filter set \"%s\" not found.", *name);
+ return -ENOENT;
+ }
+
+ dump_syscall_filter(set);
+ first = false;
+ }
+ }
+
+ return 0;
+}
+
+#else
+static int dump_syscall_filters(char** names) {
+ log_error("Not compiled with syscall filters, sorry.");
+ return -EOPNOTSUPP;
+}
+#endif
+
static void help(void) {
pager_open(arg_no_pager, false);
printf("%s [OPTIONS...] {COMMAND} ...\n\n"
"Profile systemd, show unit dependencies, check unit files.\n\n"
- " -h --help Show this help\n"
- " --version Show package version\n"
- " --no-pager Do not pipe output into a pager\n"
- " --system Operate on system systemd instance\n"
- " --user Operate on user systemd instance\n"
- " -H --host=[USER@]HOST Operate on remote host\n"
- " -M --machine=CONTAINER Operate on local container\n"
- " --order Show only order in the graph\n"
- " --require Show only requirement in the graph\n"
- " --from-pattern=GLOB Show only origins in the graph\n"
- " --to-pattern=GLOB Show only destinations in the graph\n"
- " --fuzz=SECONDS Also print also services which finished SECONDS\n"
- " earlier than the latest in the branch\n"
- " --man[=BOOL] Do [not] check for existence of man pages\n\n"
+ " -h --help Show this help\n"
+ " --version Show package version\n"
+ " --no-pager Do not pipe output into a pager\n"
+ " --system Operate on system systemd instance\n"
+ " --user Operate on user systemd instance\n"
+ " -H --host=[USER@]HOST Operate on remote host\n"
+ " -M --machine=CONTAINER Operate on local container\n"
+ " --order Show only order in the graph\n"
+ " --require Show only requirement in the graph\n"
+ " --from-pattern=GLOB Show only origins in the graph\n"
+ " --to-pattern=GLOB Show only destinations in the graph\n"
+ " --fuzz=SECONDS Also print also services which finished SECONDS\n"
+ " earlier than the latest in the branch\n"
+ " --man[=BOOL] Do [not] check for existence of man pages\n\n"
"Commands:\n"
- " time Print time spent in the kernel\n"
- " blame Print list of running units ordered by time to init\n"
- " critical-chain Print a tree of the time critical chain of units\n"
- " plot Output SVG graphic showing service initialization\n"
- " dot Output dependency graph in dot(1) format\n"
- " set-log-level LEVEL Set logging threshold for manager\n"
- " set-log-target TARGET Set logging target for manager\n"
- " dump Output state serialization of service manager\n"
- " verify FILE... Check unit files for correctness\n"
+ " time Print time spent in the kernel\n"
+ " blame Print list of running units ordered by time to init\n"
+ " critical-chain Print a tree of the time critical chain of units\n"
+ " plot Output SVG graphic showing service initialization\n"
+ " dot Output dependency graph in man:dot(1) format\n"
+ " set-log-level LEVEL Set logging threshold for manager\n"
+ " set-log-target TARGET Set logging target for manager\n"
+ " dump Output state serialization of service manager\n"
+ " syscall-filter [NAME...] Print list of syscalls in seccomp filter\n"
+ " verify FILE... Check unit files for correctness\n"
, program_invocation_short_name);
/* When updating this list, including descriptions, apply
@@ -1471,6 +1534,8 @@ int main(int argc, char *argv[]) {
r = set_log_level(bus, argv+optind+1);
else if (streq(argv[optind], "set-log-target"))
r = set_log_target(bus, argv+optind+1);
+ else if (streq(argv[optind], "syscall-filter"))
+ r = dump_syscall_filters(argv+optind+1);
else
log_error("Unknown operation '%s'.", argv[optind]);
}
diff --git a/src/backlight/backlight.c b/src/backlight/backlight.c
index 7c59f60d5f..c909b5bb51 100644
--- a/src/backlight/backlight.c
+++ b/src/backlight/backlight.c
@@ -357,9 +357,9 @@ int main(int argc, char *argv[]) {
return EXIT_FAILURE;
}
- saved = strjoin("/var/lib/systemd/backlight/", escaped_path_id, ":", escaped_ss, ":", escaped_sysname, NULL);
+ saved = strjoin("/var/lib/systemd/backlight/", escaped_path_id, ":", escaped_ss, ":", escaped_sysname);
} else
- saved = strjoin("/var/lib/systemd/backlight/", escaped_ss, ":", escaped_sysname, NULL);
+ saved = strjoin("/var/lib/systemd/backlight/", escaped_ss, ":", escaped_sysname);
if (!saved) {
log_oom();
diff --git a/src/basic/MurmurHash2.c b/src/basic/MurmurHash2.c
index 9020793930..a282a21201 100644
--- a/src/basic/MurmurHash2.c
+++ b/src/basic/MurmurHash2.c
@@ -69,9 +69,9 @@ uint32_t MurmurHash2 ( const void * key, int len, uint32_t seed )
switch(len)
{
- case 3: h ^= data[2] << 16;
- case 2: h ^= data[1] << 8;
- case 1: h ^= data[0];
+ case 3: h ^= data[2] << 16; /* fall through */
+ case 2: h ^= data[1] << 8; /* fall through */
+ case 1: h ^= data[0]; /* fall through */
h *= m;
};
diff --git a/src/basic/architecture.c b/src/basic/architecture.c
index b74dc0db78..5a3dc08a4a 100644
--- a/src/basic/architecture.c
+++ b/src/basic/architecture.c
@@ -123,7 +123,8 @@ int uname_architecture(void) {
{ "crisv32", ARCHITECTURE_CRIS },
#elif defined(__nios2__)
{ "nios2", ARCHITECTURE_NIOS2 },
-#elif defined(__riscv__)
+#elif defined(__riscv__) || defined(__riscv)
+ /* __riscv__ is obsolete, remove in 2018 */
{ "riscv32", ARCHITECTURE_RISCV32 },
{ "riscv64", ARCHITECTURE_RISCV64 },
# if __SIZEOF_POINTER__ == 4
diff --git a/src/basic/architecture.h b/src/basic/architecture.h
index 5a77c31932..46883719d1 100644
--- a/src/basic/architecture.h
+++ b/src/basic/architecture.h
@@ -124,13 +124,21 @@ int uname_architecture(void);
#elif defined(__sparc__)
# define native_architecture() ARCHITECTURE_SPARC
# define LIB_ARCH_TUPLE "sparc-linux-gnu"
-#elif defined(__mips64__)
+#elif defined(__mips64) && defined(__LP64__)
# if __BYTE_ORDER == __BIG_ENDIAN
# define native_architecture() ARCHITECTURE_MIPS64
-# error "Missing LIB_ARCH_TUPLE for MIPS64"
+# define LIB_ARCH_TUPLE "mips64-linux-gnuabi64"
# else
# define native_architecture() ARCHITECTURE_MIPS64_LE
-# error "Missing LIB_ARCH_TUPLE for MIPS64_LE"
+# define LIB_ARCH_TUPLE "mips64el-linux-gnuabi64"
+# endif
+#elif defined(__mips64)
+# if __BYTE_ORDER == __BIG_ENDIAN
+# define native_architecture() ARCHITECTURE_MIPS64
+# define LIB_ARCH_TUPLE "mips64-linux-gnuabin32"
+# else
+# define native_architecture() ARCHITECTURE_MIPS64_LE
+# define LIB_ARCH_TUPLE "mips64el-linux-gnuabin32"
# endif
#elif defined(__mips__)
# if __BYTE_ORDER == __BIG_ENDIAN
@@ -150,6 +158,7 @@ int uname_architecture(void);
# else
# define native_architecture() ARCHITECTURE_ARM64
# define LIB_ARCH_TUPLE "aarch64-linux-gnu"
+# define SECONDARY_ARCHITECTURE ARCHITECTURE_ARM
# endif
#elif defined(__arm__)
# if __BYTE_ORDER == __BIG_ENDIAN
@@ -186,14 +195,15 @@ int uname_architecture(void);
# define LIB_ARCH_TUPLE "m68k-linux-gnu"
#elif defined(__tilegx__)
# define native_architecture() ARCHITECTURE_TILEGX
-# error "Missing LIB_ARCH_TUPLE for TILEGX"
+# define LIB_ARCH_TUPLE "tilegx-linux-gnu"
#elif defined(__cris__)
# define native_architecture() ARCHITECTURE_CRIS
# error "Missing LIB_ARCH_TUPLE for CRIS"
#elif defined(__nios2__)
# define native_architecture() ARCHITECTURE_NIOS2
# define LIB_ARCH_TUPLE "nios2-linux-gnu"
-#elif defined(__riscv__)
+#elif defined(__riscv__) || defined(__riscv)
+ /* __riscv__ is obsolete, remove in 2018 */
# if __SIZEOF_POINTER__ == 4
# define native_architecture() ARCHITECTURE_RISCV32
# define LIB_ARCH_TUPLE "riscv32-linux-gnu"
diff --git a/src/basic/btrfs-util.c b/src/basic/btrfs-util.c
index 359d85f2e8..5505499312 100644
--- a/src/basic/btrfs-util.c
+++ b/src/basic/btrfs-util.c
@@ -20,6 +20,7 @@
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
+#include <linux/fs.h>
#include <linux/loop.h>
#include <stddef.h>
#include <stdio.h>
@@ -38,6 +39,7 @@
#include "alloc-util.h"
#include "btrfs-ctree.h"
#include "btrfs-util.h"
+#include "chattr-util.h"
#include "copy.h"
#include "fd-util.h"
#include "fileio.h"
@@ -45,6 +47,7 @@
#include "macro.h"
#include "missing.h"
#include "path-util.h"
+#include "rm-rf.h"
#include "selinux-util.h"
#include "smack-util.h"
#include "sparse-endian.h"
@@ -1642,7 +1645,7 @@ static int subvol_snapshot_children(int old_fd, int new_fd, const char *subvolum
if (old_child_fd < 0)
return -errno;
- np = strjoin(subvolume, "/", ino_args.name, NULL);
+ np = strjoin(subvolume, "/", ino_args.name);
if (!np)
return -ENOMEM;
@@ -1718,28 +1721,46 @@ int btrfs_subvol_snapshot_fd(int old_fd, const char *new_path, BtrfsSnapshotFlag
if (r < 0)
return r;
if (r == 0) {
+ bool plain_directory = false;
+
+ /* If the source isn't a proper subvolume, fail unless fallback is requested */
if (!(flags & BTRFS_SNAPSHOT_FALLBACK_COPY))
return -EISDIR;
r = btrfs_subvol_make(new_path);
- if (r < 0)
- return r;
+ if (r == -ENOTTY && (flags & BTRFS_SNAPSHOT_FALLBACK_DIRECTORY)) {
+ /* If the destination doesn't support subvolumes, then use a plain directory, if that's requested. */
+ if (mkdir(new_path, 0755) < 0)
+ return r;
- r = copy_directory_fd(old_fd, new_path, true);
- if (r < 0) {
- (void) btrfs_subvol_remove(new_path, BTRFS_REMOVE_QUOTA);
+ plain_directory = true;
+ } else if (r < 0)
return r;
- }
+
+ r = copy_directory_fd(old_fd, new_path, COPY_MERGE|COPY_REFLINK);
+ if (r < 0)
+ goto fallback_fail;
if (flags & BTRFS_SNAPSHOT_READ_ONLY) {
- r = btrfs_subvol_set_read_only(new_path, true);
- if (r < 0) {
- (void) btrfs_subvol_remove(new_path, BTRFS_REMOVE_QUOTA);
- return r;
+
+ if (plain_directory) {
+ /* Plain directories have no recursive read-only flag, but something pretty close to
+ * it: the IMMUTABLE bit. Let's use this here, if this is requested. */
+
+ if (flags & BTRFS_SNAPSHOT_FALLBACK_IMMUTABLE)
+ (void) chattr_path(new_path, FS_IMMUTABLE_FL, FS_IMMUTABLE_FL);
+ } else {
+ r = btrfs_subvol_set_read_only(new_path, true);
+ if (r < 0)
+ goto fallback_fail;
}
}
return 0;
+
+ fallback_fail:
+ (void) rm_rf(new_path, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
+ return r;
}
r = extract_subvolume_name(new_path, &subvolume);
diff --git a/src/basic/btrfs-util.h b/src/basic/btrfs-util.h
index 1d852d502c..04a2e1274b 100644
--- a/src/basic/btrfs-util.h
+++ b/src/basic/btrfs-util.h
@@ -45,10 +45,12 @@ typedef struct BtrfsQuotaInfo {
} BtrfsQuotaInfo;
typedef enum BtrfsSnapshotFlags {
- BTRFS_SNAPSHOT_FALLBACK_COPY = 1,
+ BTRFS_SNAPSHOT_FALLBACK_COPY = 1, /* If the source isn't a subvolume, reflink everything */
BTRFS_SNAPSHOT_READ_ONLY = 2,
BTRFS_SNAPSHOT_RECURSIVE = 4,
BTRFS_SNAPSHOT_QUOTA = 8,
+ BTRFS_SNAPSHOT_FALLBACK_DIRECTORY = 16, /* If the destination doesn't support subvolumes, reflink/copy instead */
+ BTRFS_SNAPSHOT_FALLBACK_IMMUTABLE = 32, /* When we can't create a subvolume, use the FS_IMMUTABLE attribute for indicating read-only */
} BtrfsSnapshotFlags;
typedef enum BtrfsRemoveFlags {
diff --git a/src/basic/build.h b/src/basic/build.h
index 633c2aaccb..91312bd2a3 100644
--- a/src/basic/build.h
+++ b/src/basic/build.h
@@ -133,6 +133,8 @@
#define _IDN_FEATURE_ "-IDN"
#endif
+#define _CGROUP_HIEARCHY_ "default-hierarchy=" DEFAULT_HIERARCHY_NAME
+
#define SYSTEMD_FEATURES \
_PAM_FEATURE_ " " \
_AUDIT_FEATURE_ " " \
@@ -152,4 +154,5 @@
_BLKID_FEATURE_ " " \
_ELFUTILS_FEATURE_ " " \
_KMOD_FEATURE_ " " \
- _IDN_FEATURE_
+ _IDN_FEATURE_ " " \
+ _CGROUP_HIEARCHY_
diff --git a/src/basic/calendarspec.c b/src/basic/calendarspec.c
index fda293fcb9..2323eb8555 100644
--- a/src/basic/calendarspec.c
+++ b/src/basic/calendarspec.c
@@ -18,7 +18,9 @@
***/
#include <alloca.h>
+#include <ctype.h>
#include <errno.h>
+#include <limits.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
@@ -32,9 +34,9 @@
#include "parse-util.h"
#include "string-util.h"
-/* Longest valid date/time range is 1970..2199 */
-#define MAX_RANGE_LEN 230
-#define BITS_WEEKDAYS 127
+#define BITS_WEEKDAYS 127
+#define MIN_YEAR 1970
+#define MAX_YEAR 2199
static void free_chain(CalendarComponent *c) {
CalendarComponent *n;
@@ -64,9 +66,14 @@ void calendar_spec_free(CalendarSpec *c) {
static int component_compare(const void *_a, const void *_b) {
CalendarComponent * const *a = _a, * const *b = _b;
- if ((*a)->value < (*b)->value)
+ if ((*a)->start < (*b)->start)
return -1;
- if ((*a)->value > (*b)->value)
+ if ((*a)->start > (*b)->start)
+ return 1;
+
+ if ((*a)->stop < (*b)->stop)
+ return -1;
+ if ((*a)->stop > (*b)->stop)
return 1;
if ((*a)->repeat < (*b)->repeat)
@@ -77,15 +84,24 @@ static int component_compare(const void *_a, const void *_b) {
return 0;
}
-static void sort_chain(CalendarComponent **c) {
+static void normalize_chain(CalendarComponent **c) {
unsigned n = 0, k;
CalendarComponent **b, *i, **j, *next;
assert(c);
- for (i = *c; i; i = i->next)
+ for (i = *c; i; i = i->next) {
n++;
+ /*
+ * While we're counting the chain, also normalize `stop`
+ * so the length of the range is a multiple of `repeat`
+ */
+ if (i->stop > i->start && i->repeat > 0)
+ i->stop -= (i->stop - i->start) % i->repeat;
+
+ }
+
if (n <= 1)
return;
@@ -100,8 +116,7 @@ static void sort_chain(CalendarComponent **c) {
/* Drop non-unique entries */
for (k = n-1; k > 0; k--) {
- if (b[k-1]->value == next->value &&
- b[k-1]->repeat == next->repeat) {
+ if (component_compare(&b[k-1], &next) == 0) {
free(b[k-1]);
continue;
}
@@ -117,15 +132,19 @@ static void fix_year(CalendarComponent *c) {
/* Turns 12 → 2012, 89 → 1989 */
while (c) {
- CalendarComponent *n = c->next;
+ if (c->start >= 0 && c->start < 70)
+ c->start += 2000;
- if (c->value >= 0 && c->value < 70)
- c->value += 2000;
+ if (c->stop >= 0 && c->stop < 70)
+ c->stop += 2000;
- if (c->value >= 70 && c->value < 100)
- c->value += 1900;
+ if (c->start >= 70 && c->start < 100)
+ c->start += 1900;
- c = n;
+ if (c->stop >= 70 && c->stop < 100)
+ c->stop += 1900;
+
+ c = c->next;
}
}
@@ -135,30 +154,54 @@ int calendar_spec_normalize(CalendarSpec *c) {
if (c->weekdays_bits <= 0 || c->weekdays_bits >= BITS_WEEKDAYS)
c->weekdays_bits = -1;
+ if (c->end_of_month && !c->day)
+ c->end_of_month = false;
+
fix_year(c->year);
- sort_chain(&c->year);
- sort_chain(&c->month);
- sort_chain(&c->day);
- sort_chain(&c->hour);
- sort_chain(&c->minute);
- sort_chain(&c->microsecond);
+ normalize_chain(&c->year);
+ normalize_chain(&c->month);
+ normalize_chain(&c->day);
+ normalize_chain(&c->hour);
+ normalize_chain(&c->minute);
+ normalize_chain(&c->microsecond);
return 0;
}
-_pure_ static bool chain_valid(CalendarComponent *c, int from, int to) {
+_pure_ static bool chain_valid(CalendarComponent *c, int from, int to, bool end_of_month) {
if (!c)
return true;
- if (c->value < from || c->value > to)
- return false;
+ /* Forbid dates more than 28 days from the end of the month */
+ if (end_of_month)
+ to -= 3;
- if (c->value + c->repeat > to)
+ if (c->start < from || c->start > to)
return false;
+ /*
+ * c->repeat must be short enough so at least one repetition may
+ * occur before the end of the interval. For dates scheduled
+ * relative to the end of the month, c->start and c->stop
+ * correspond to the Nth last day of the month.
+ */
+ if (c->stop >= 0) {
+ if (c->stop < from || c ->stop > to)
+ return false;
+
+ if (c->start + c->repeat > c->stop)
+ return false;
+ } else {
+ if (end_of_month && c->start - c->repeat < from)
+ return false;
+
+ if (!end_of_month && c->start + c->repeat > to)
+ return false;
+ }
+
if (c->next)
- return chain_valid(c->next, from, to);
+ return chain_valid(c->next, from, to, end_of_month);
return true;
}
@@ -169,22 +212,22 @@ _pure_ bool calendar_spec_valid(CalendarSpec *c) {
if (c->weekdays_bits > BITS_WEEKDAYS)
return false;
- if (!chain_valid(c->year, 1970, 2199))
+ if (!chain_valid(c->year, MIN_YEAR, MAX_YEAR, false))
return false;
- if (!chain_valid(c->month, 1, 12))
+ if (!chain_valid(c->month, 1, 12, false))
return false;
- if (!chain_valid(c->day, 1, 31))
+ if (!chain_valid(c->day, 1, 31, c->end_of_month))
return false;
- if (!chain_valid(c->hour, 0, 23))
+ if (!chain_valid(c->hour, 0, 23, false))
return false;
- if (!chain_valid(c->minute, 0, 59))
+ if (!chain_valid(c->minute, 0, 59, false))
return false;
- if (!chain_valid(c->microsecond, 0, 60*USEC_PER_SEC-1))
+ if (!chain_valid(c->microsecond, 0, 60*USEC_PER_SEC-1, false))
return false;
return true;
@@ -240,6 +283,8 @@ static void format_weekdays(FILE *f, const CalendarSpec *c) {
}
static void format_chain(FILE *f, int space, const CalendarComponent *c, bool usec) {
+ int d = usec ? (int) USEC_PER_SEC : 1;
+
assert(f);
if (!c) {
@@ -247,23 +292,27 @@ static void format_chain(FILE *f, int space, const CalendarComponent *c, bool us
return;
}
- assert(c->value >= 0);
- if (!usec)
- fprintf(f, "%0*i", space, c->value);
- else if (c->value % USEC_PER_SEC == 0)
- fprintf(f, "%0*i", space, (int) (c->value / USEC_PER_SEC));
- else
- fprintf(f, "%0*i.%06i", space, (int) (c->value / USEC_PER_SEC), (int) (c->value % USEC_PER_SEC));
-
- if (c->repeat > 0) {
- if (!usec)
- fprintf(f, "/%i", c->repeat);
- else if (c->repeat % USEC_PER_SEC == 0)
- fprintf(f, "/%i", (int) (c->repeat / USEC_PER_SEC));
- else
- fprintf(f, "/%i.%06i", (int) (c->repeat / USEC_PER_SEC), (int) (c->repeat % USEC_PER_SEC));
+ if (usec && c->start == 0 && c->repeat == USEC_PER_SEC && !c->next) {
+ fputc('*', f);
+ return;
}
+ assert(c->start >= 0);
+
+ fprintf(f, "%0*i", space, c->start / d);
+ if (c->start % d > 0)
+ fprintf(f, ".%06i", c->start % d);
+
+ if (c->stop > 0)
+ fprintf(f, "..%0*i", space, c->stop / d);
+ if (c->stop % d > 0)
+ fprintf(f, ".%06i", c->stop % d);
+
+ if (c->repeat > 0 && !(c->stop > 0 && c->repeat == d))
+ fprintf(f, "/%i", c->repeat / d);
+ if (c->repeat % d > 0)
+ fprintf(f, ".%06i", c->repeat % d);
+
if (c->next) {
fputc(',', f);
format_chain(f, space, c->next, usec);
@@ -291,7 +340,7 @@ int calendar_spec_to_string(const CalendarSpec *c, char **p) {
format_chain(f, 4, c->year, false);
fputc('-', f);
format_chain(f, 2, c->month, false);
- fputc('-', f);
+ fputc(c->end_of_month ? '~' : '-', f);
format_chain(f, 2, c->day, false);
fputc(' ', f);
format_chain(f, 2, c->hour, false);
@@ -358,9 +407,6 @@ static int parse_weekdays(const char **p, CalendarSpec *c) {
for (;;) {
unsigned i;
- if (!first && **p == ' ')
- return 0;
-
for (i = 0; i < ELEMENTSOF(day_nr); i++) {
size_t skip;
@@ -416,7 +462,7 @@ static int parse_weekdays(const char **p, CalendarSpec *c) {
return -EINVAL;
l = day_nr[i].nr;
- *p += 1;
+ *p += 2;
/* Support ranges with "-" for backwards compatibility */
} else if (**p == '-') {
@@ -424,28 +470,38 @@ static int parse_weekdays(const char **p, CalendarSpec *c) {
return -EINVAL;
l = day_nr[i].nr;
- } else
+ *p += 1;
+
+ } else if (**p == ',') {
l = -1;
+ *p += 1;
+ }
+
+ /* Allow a trailing comma but not an open range */
+ if (**p == 0 || **p == ' ') {
+ *p += strspn(*p, " ");
+ return l < 0 ? 0 : -EINVAL;
+ }
- *p += 1;
first = false;
}
}
-static int parse_component_decimal(const char **p, bool usec, unsigned long *res) {
+static int parse_component_decimal(const char **p, bool usec, int *res) {
unsigned long value;
const char *e = NULL;
char *ee = NULL;
int r;
+ if (!isdigit(**p))
+ return -EINVAL;
+
errno = 0;
value = strtoul(*p, &ee, 10);
if (errno > 0)
return -errno;
if (ee == *p)
return -EINVAL;
- if ((unsigned long) (int) value != value)
- return -ERANGE;
e = ee;
if (usec) {
@@ -453,7 +509,9 @@ static int parse_component_decimal(const char **p, bool usec, unsigned long *res
return -ERANGE;
value *= USEC_PER_SEC;
- if (*e == '.') {
+
+ /* One "." is a decimal point, but ".." is a range separator */
+ if (e[0] == '.' && e[1] != '.') {
unsigned add;
e++;
@@ -467,6 +525,9 @@ static int parse_component_decimal(const char **p, bool usec, unsigned long *res
}
}
+ if (value > INT_MAX)
+ return -ERANGE;
+
*p = e;
*res = value;
@@ -482,7 +543,8 @@ static int const_chain(int value, CalendarComponent **c) {
if (!cc)
return -ENOMEM;
- cc->value = value;
+ cc->start = value;
+ cc->stop = -1;
cc->repeat = 0;
cc->next = *c;
@@ -492,9 +554,8 @@ static int const_chain(int value, CalendarComponent **c) {
}
static int prepend_component(const char **p, bool usec, CalendarComponent **c) {
- unsigned long i, value, range_end, range_inc, repeat = 0;
+ int r, start, stop = -1, repeat = 0;
CalendarComponent *cc;
- int r;
const char *e;
assert(p);
@@ -502,10 +563,19 @@ static int prepend_component(const char **p, bool usec, CalendarComponent **c) {
e = *p;
- r = parse_component_decimal(&e, usec, &value);
+ r = parse_component_decimal(&e, usec, &start);
if (r < 0)
return r;
+ if (e[0] == '.' && e[1] == '.') {
+ e += 2;
+ r = parse_component_decimal(&e, usec, &stop);
+ if (r < 0)
+ return r;
+
+ repeat = usec ? USEC_PER_SEC : 1;
+ }
+
if (*e == '/') {
e++;
r = parse_component_decimal(&e, usec, &repeat);
@@ -514,40 +584,17 @@ static int prepend_component(const char **p, bool usec, CalendarComponent **c) {
if (repeat == 0)
return -ERANGE;
- } else if (e[0] == '.' && e[1] == '.') {
- e += 2;
- r = parse_component_decimal(&e, usec, &range_end);
- if (r < 0)
- return r;
-
- if (value >= range_end)
- return -EINVAL;
-
- range_inc = usec ? USEC_PER_SEC : 1;
-
- /* Don't allow impossibly large ranges... */
- if (range_end - value >= MAX_RANGE_LEN * range_inc)
- return -EINVAL;
-
- /* ...or ranges with only a single element */
- if (range_end - value < range_inc)
- return -EINVAL;
-
- for (i = value; i <= range_end; i += range_inc) {
- r = const_chain(i, c);
- if (r < 0)
- return r;
- }
}
- if (*e != 0 && *e != ' ' && *e != ',' && *e != '-' && *e != ':')
+ if (*e != 0 && *e != ' ' && *e != ',' && *e != '-' && *e != '~' && *e != ':')
return -EINVAL;
cc = new0(CalendarComponent, 1);
if (!cc)
return -ENOMEM;
- cc->value = value;
+ cc->start = start;
+ cc->stop = stop;
cc->repeat = repeat;
cc->next = *c;
@@ -620,7 +667,9 @@ static int parse_date(const char **p, CalendarSpec *c) {
return 0;
}
- if (*t != '-') {
+ if (*t == '~')
+ c->end_of_month = true;
+ else if (*t != '-') {
free_chain(first);
return -EINVAL;
}
@@ -638,9 +687,15 @@ static int parse_date(const char **p, CalendarSpec *c) {
c->month = first;
c->day = second;
return 0;
+ } else if (c->end_of_month) {
+ free_chain(first);
+ free_chain(second);
+ return -EINVAL;
}
- if (*t != '-') {
+ if (*t == '~')
+ c->end_of_month = true;
+ else if (*t != '-') {
free_chain(first);
free_chain(second);
return -EINVAL;
@@ -654,7 +709,7 @@ static int parse_date(const char **p, CalendarSpec *c) {
return r;
}
- /* Got tree parts, hence it is year, month and day */
+ /* Got three parts, hence it is year, month and day */
if (*t == ' ' || *t == 0) {
*p = t + strspn(t, " ");
c->year = first;
@@ -680,14 +735,9 @@ static int parse_calendar_time(const char **p, CalendarSpec *c) {
t = *p;
- if (*t == 0) {
- /* If no time is specified at all, but a date of some
- * kind, then this means 00:00:00 */
- if (c->day || c->weekdays_bits > 0)
- goto null_hour;
-
- goto finish;
- }
+ /* If no time is specified at all, then this means 00:00:00 */
+ if (*t == 0)
+ goto null_hour;
r = parse_chain(&t, false, &h);
if (r < 0)
@@ -704,12 +754,8 @@ static int parse_calendar_time(const char **p, CalendarSpec *c) {
goto fail;
/* Already at the end? Then it's hours and minutes, and seconds are 0 */
- if (*t == 0) {
- if (m != NULL)
- goto null_second;
-
- goto finish;
- }
+ if (*t == 0)
+ goto null_second;
if (*t != ':') {
r = -EINVAL;
@@ -765,9 +811,6 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
assert(p);
assert(spec);
- if (isempty(p))
- return -EINVAL;
-
c = new0(CalendarSpec, 1);
if (!c)
return -ENOMEM;
@@ -806,6 +849,11 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
}
}
+ if (isempty(p)) {
+ r = -EINVAL;
+ goto fail;
+ }
+
if (strcaseeq(p, "minutely")) {
r = const_chain(0, &c->microsecond);
if (r < 0)
@@ -965,9 +1013,23 @@ fail:
return r;
}
-static int find_matching_component(const CalendarComponent *c, int *val) {
- const CalendarComponent *n;
- int d = -1;
+static int find_end_of_month(struct tm *tm, bool utc, int day) {
+ struct tm t = *tm;
+
+ t.tm_mon++;
+ t.tm_mday = 1 - day;
+
+ if (mktime_or_timegm(&t, utc) < 0 ||
+ t.tm_mon != tm->tm_mon)
+ return -1;
+
+ return t.tm_mday;
+}
+
+static int find_matching_component(const CalendarSpec *spec, const CalendarComponent *c,
+ struct tm *tm, int *val) {
+ const CalendarComponent *p = c;
+ int start, stop, d = -1;
bool d_set = false;
int r;
@@ -977,27 +1039,36 @@ static int find_matching_component(const CalendarComponent *c, int *val) {
return 0;
while (c) {
- n = c->next;
+ start = c->start;
+ stop = c->stop;
+
+ if (spec->end_of_month && p == spec->day) {
+ start = find_end_of_month(tm, spec->utc, start);
+ stop = find_end_of_month(tm, spec->utc, stop);
+
+ if (stop > 0)
+ SWAP_TWO(start, stop);
+ }
- if (c->value >= *val) {
+ if (start >= *val) {
- if (!d_set || c->value < d) {
- d = c->value;
+ if (!d_set || start < d) {
+ d = start;
d_set = true;
}
} else if (c->repeat > 0) {
int k;
- k = c->value + c->repeat * ((*val - c->value + c->repeat -1) / c->repeat);
+ k = start + c->repeat * ((*val - start + c->repeat - 1) / c->repeat);
- if (!d_set || k < d) {
+ if ((!d_set || k < d) && (stop < 0 || k <= stop)) {
d = k;
d_set = true;
}
}
- c = n;
+ c = c->next;
}
if (!d_set)
@@ -1014,7 +1085,15 @@ static bool tm_out_of_bounds(const struct tm *tm, bool utc) {
t = *tm;
- if (mktime_or_timegm(&t, utc) == (time_t) -1)
+ if (mktime_or_timegm(&t, utc) < 0)
+ return true;
+
+ /*
+ * Set an upper bound on the year so impossible dates like "*-02-31"
+ * don't cause find_next() to loop forever. tm_year contains years
+ * since 1900, so adjust it accordingly.
+ */
+ if (tm->tm_year + 1900 > MAX_YEAR)
return true;
/* Did any normalization take place? If so, it was out of bounds before */
@@ -1035,7 +1114,7 @@ static bool matches_weekday(int weekdays_bits, const struct tm *tm, bool utc) {
return true;
t = *tm;
- if (mktime_or_timegm(&t, utc) == (time_t) -1)
+ if (mktime_or_timegm(&t, utc) < 0)
return false;
k = t.tm_wday == 0 ? 6 : t.tm_wday - 1;
@@ -1059,7 +1138,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
c.tm_isdst = spec->dst;
c.tm_year += 1900;
- r = find_matching_component(spec->year, &c.tm_year);
+ r = find_matching_component(spec, spec->year, &c, &c.tm_year);
c.tm_year -= 1900;
if (r > 0) {
@@ -1073,7 +1152,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
return -ENOENT;
c.tm_mon += 1;
- r = find_matching_component(spec->month, &c.tm_mon);
+ r = find_matching_component(spec, spec->month, &c, &c.tm_mon);
c.tm_mon -= 1;
if (r > 0) {
@@ -1088,7 +1167,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
continue;
}
- r = find_matching_component(spec->day, &c.tm_mday);
+ r = find_matching_component(spec, spec->day, &c, &c.tm_mday);
if (r > 0)
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
@@ -1104,7 +1183,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
continue;
}
- r = find_matching_component(spec->hour, &c.tm_hour);
+ r = find_matching_component(spec, spec->hour, &c, &c.tm_hour);
if (r > 0)
c.tm_min = c.tm_sec = tm_usec = 0;
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
@@ -1113,7 +1192,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
continue;
}
- r = find_matching_component(spec->minute, &c.tm_min);
+ r = find_matching_component(spec, spec->minute, &c, &c.tm_min);
if (r > 0)
c.tm_sec = tm_usec = 0;
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
@@ -1123,7 +1202,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
}
c.tm_sec = c.tm_sec * USEC_PER_SEC + tm_usec;
- r = find_matching_component(spec->microsecond, &c.tm_sec);
+ r = find_matching_component(spec, spec->microsecond, &c, &c.tm_sec);
tm_usec = c.tm_sec % USEC_PER_SEC;
c.tm_sec /= USEC_PER_SEC;
@@ -1148,6 +1227,9 @@ int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *next)
assert(spec);
assert(next);
+ if (usec > USEC_TIMESTAMP_FORMATTABLE_MAX)
+ return -EINVAL;
+
usec++;
t = (time_t) (usec / USEC_PER_SEC);
assert_se(localtime_or_gmtime_r(&t, &tm, spec->utc));
@@ -1158,7 +1240,7 @@ int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *next)
return r;
t = mktime_or_timegm(&tm, spec->utc);
- if (t == (time_t) -1)
+ if (t < 0)
return -EINVAL;
*next = (usec_t) t * USEC_PER_SEC + tm_usec;
diff --git a/src/basic/calendarspec.h b/src/basic/calendarspec.h
index c6087228fd..3d8798de0b 100644
--- a/src/basic/calendarspec.h
+++ b/src/basic/calendarspec.h
@@ -28,7 +28,8 @@
#include "util.h"
typedef struct CalendarComponent {
- int value;
+ int start;
+ int stop;
int repeat;
struct CalendarComponent *next;
@@ -36,6 +37,7 @@ typedef struct CalendarComponent {
typedef struct CalendarSpec {
int weekdays_bits;
+ bool end_of_month;
bool utc;
int dst;
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
index 624626c867..540435c4fb 100644
--- a/src/basic/cgroup-util.c
+++ b/src/basic/cgroup-util.c
@@ -38,7 +38,7 @@
#include "extract-word.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "fs-util.h"
#include "log.h"
#include "login-util.h"
@@ -182,8 +182,7 @@ int cg_read_subgroup(DIR *d, char **fn) {
if (de->d_type != DT_DIR)
continue;
- if (streq(de->d_name, ".") ||
- streq(de->d_name, ".."))
+ if (dot_or_dot_dot(de->d_name))
continue;
b = strdup(de->d_name);
@@ -209,6 +208,18 @@ int cg_rmdir(const char *controller, const char *path) {
if (r < 0 && errno != ENOENT)
return -errno;
+ r = cg_hybrid_unified();
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 0;
+
+ if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
+ r = cg_rmdir(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path);
+ if (r < 0)
+ log_warning_errno(r, "Failed to remove compat systemd cgroup %s: %m", path);
+ }
+
return 0;
}
@@ -345,7 +356,7 @@ int cg_kill_recursive(
while ((r = cg_read_subgroup(d, &fn)) > 0) {
_cleanup_free_ char *p = NULL;
- p = strjoin(path, "/", fn, NULL);
+ p = strjoin(path, "/", fn);
free(fn);
if (!p)
return -ENOMEM;
@@ -479,7 +490,7 @@ int cg_migrate_recursive(
while ((r = cg_read_subgroup(d, &fn)) > 0) {
_cleanup_free_ char *p = NULL;
- p = strjoin(pfrom, "/", fn, NULL);
+ p = strjoin(pfrom, "/", fn);
free(fn);
if (!p)
return -ENOMEM;
@@ -543,6 +554,13 @@ static const char *controller_to_dirname(const char *controller) {
* just cuts off the name= prefixed used for named
* hierarchies, if it is specified. */
+ if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
+ if (cg_hybrid_unified() > 0)
+ controller = SYSTEMD_CGROUP_CONTROLLER_HYBRID;
+ else
+ controller = SYSTEMD_CGROUP_CONTROLLER_LEGACY;
+ }
+
e = startswith(controller, "name=");
if (e)
return e;
@@ -562,11 +580,11 @@ static int join_path_legacy(const char *controller, const char *path, const char
if (isempty(path) && isempty(suffix))
t = strappend("/sys/fs/cgroup/", dn);
else if (isempty(path))
- t = strjoin("/sys/fs/cgroup/", dn, "/", suffix, NULL);
+ t = strjoin("/sys/fs/cgroup/", dn, "/", suffix);
else if (isempty(suffix))
- t = strjoin("/sys/fs/cgroup/", dn, "/", path, NULL);
+ t = strjoin("/sys/fs/cgroup/", dn, "/", path);
else
- t = strjoin("/sys/fs/cgroup/", dn, "/", path, "/", suffix, NULL);
+ t = strjoin("/sys/fs/cgroup/", dn, "/", path, "/", suffix);
if (!t)
return -ENOMEM;
@@ -586,7 +604,7 @@ static int join_path_unified(const char *path, const char *suffix, char **fs) {
else if (isempty(suffix))
t = strappend("/sys/fs/cgroup/", path);
else
- t = strjoin("/sys/fs/cgroup/", path, "/", suffix, NULL);
+ t = strjoin("/sys/fs/cgroup/", path, "/", suffix);
if (!t)
return -ENOMEM;
@@ -595,7 +613,7 @@ static int join_path_unified(const char *path, const char *suffix, char **fs) {
}
int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs) {
- int unified, r;
+ int r;
assert(fs);
@@ -613,7 +631,7 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch
else if (!path)
t = strdup(suffix);
else
- t = strjoin(path, "/", suffix, NULL);
+ t = strjoin(path, "/", suffix);
if (!t)
return -ENOMEM;
@@ -624,11 +642,10 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch
if (!cg_controller_is_valid(controller))
return -EINVAL;
- unified = cg_all_unified();
- if (unified < 0)
- return unified;
-
- if (unified > 0)
+ r = cg_all_unified();
+ if (r < 0)
+ return r;
+ if (r > 0)
r = join_path_unified(path, suffix, fs);
else
r = join_path_legacy(controller, path, suffix, fs);
@@ -640,7 +657,7 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch
}
static int controller_is_accessible(const char *controller) {
- int unified;
+ int r;
assert(controller);
@@ -652,10 +669,10 @@ static int controller_is_accessible(const char *controller) {
if (!cg_controller_is_valid(controller))
return -EINVAL;
- unified = cg_all_unified();
- if (unified < 0)
- return unified;
- if (unified > 0) {
+ r = cg_all_unified();
+ if (r < 0)
+ return r;
+ if (r > 0) {
/* We don't support named hierarchies if we are using
* the unified hierarchy. */
@@ -709,7 +726,7 @@ static int trim_cb(const char *path, const struct stat *sb, int typeflag, struct
int cg_trim(const char *controller, const char *path, bool delete_root) {
_cleanup_free_ char *fs = NULL;
- int r = 0;
+ int r = 0, q;
assert(path);
@@ -732,6 +749,15 @@ int cg_trim(const char *controller, const char *path, bool delete_root) {
return -errno;
}
+ q = cg_hybrid_unified();
+ if (q < 0)
+ return q;
+ if (q > 0 && streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
+ q = cg_trim(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path, delete_root);
+ if (q < 0)
+ log_warning_errno(q, "Failed to trim compat systemd cgroup %s: %m", path);
+ }
+
return r;
}
@@ -755,6 +781,16 @@ int cg_create(const char *controller, const char *path) {
return -errno;
}
+ r = cg_hybrid_unified();
+ if (r < 0)
+ return r;
+
+ if (r > 0 && streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
+ r = cg_create(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path);
+ if (r < 0)
+ log_warning_errno(r, "Failed to create compat systemd cgroup %s: %m", path);
+ }
+
return 1;
}
@@ -792,7 +828,21 @@ int cg_attach(const char *controller, const char *path, pid_t pid) {
xsprintf(c, PID_FMT "\n", pid);
- return write_string_file(fs, c, 0);
+ r = write_string_file(fs, c, 0);
+ if (r < 0)
+ return r;
+
+ r = cg_hybrid_unified();
+ if (r < 0)
+ return r;
+
+ if (r > 0 && streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
+ r = cg_attach(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path, pid);
+ if (r < 0)
+ log_warning_errno(r, "Failed to attach %d to compat systemd cgroup %s: %m", pid, path);
+ }
+
+ return 0;
}
int cg_attach_fallback(const char *controller, const char *path, pid_t pid) {
@@ -841,7 +891,20 @@ int cg_set_group_access(
if (r < 0)
return r;
- return chmod_and_chown(fs, mode, uid, gid);
+ r = chmod_and_chown(fs, mode, uid, gid);
+ if (r < 0)
+ return r;
+
+ r = cg_hybrid_unified();
+ if (r < 0)
+ return r;
+ if (r > 0 && streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
+ r = cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path, mode, uid, gid);
+ if (r < 0)
+ log_warning_errno(r, "Failed to set group access on compat systemd cgroup %s: %m", path);
+ }
+
+ return 0;
}
int cg_set_task_access(
@@ -852,7 +915,7 @@ int cg_set_task_access(
gid_t gid) {
_cleanup_free_ char *fs = NULL, *procs = NULL;
- int r, unified;
+ int r;
assert(path);
@@ -870,16 +933,24 @@ int cg_set_task_access(
if (r < 0)
return r;
- unified = cg_unified(controller);
- if (unified < 0)
- return unified;
- if (unified)
- return 0;
+ r = cg_unified_controller(controller);
+ if (r < 0)
+ return r;
+ if (r == 0) {
+ /* Compatibility, Always keep values for "tasks" in sync with
+ * "cgroup.procs" */
+ if (cg_get_path(controller, path, "tasks", &procs) >= 0)
+ (void) chmod_and_chown(procs, mode, uid, gid);
+ }
- /* Compatibility, Always keep values for "tasks" in sync with
- * "cgroup.procs" */
- if (cg_get_path(controller, path, "tasks", &procs) >= 0)
- (void) chmod_and_chown(procs, mode, uid, gid);
+ r = cg_hybrid_unified();
+ if (r < 0)
+ return r;
+ if (r > 0 && streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
+ r = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path, mode, uid, gid);
+ if (r < 0)
+ log_warning_errno(r, "Failed to set task access on compat systemd cgroup %s: %m", path);
+ }
return 0;
}
@@ -924,15 +995,14 @@ int cg_get_xattr(const char *controller, const char *path, const char *name, voi
/**
* Returns the cgroup path of the process under the hierarchy specified by @controller:
*
- * controller : whichever hierarchy has @controller bound to it (with the special case that
- * SYSTEMD_CGROUP_CONTROLLER selects whichever hierarchy systemd is using, even if it is the
- * v2 (unified) hierarchy and thus the SYSTEMD_CGROUP_CONTROLLER doesn't actually exist)
+ * controller : whichever hierarchy has @controller bound to it (with a special case for the
+ * SYSTEMD_CGROUP_CONTROLLER ("_systemd") pseudo-controller)
*
* controller == NULL : equivalent to SYSTEMD_CGROUP_CONTROLLER
*/
int cg_pid_get_path(const char *controller, pid_t pid, char **path) {
_cleanup_fclose_ FILE *f = NULL;
- const char *fs;
+ const char *fs, *controller_str = NULL;
int unified;
assert(path);
@@ -944,22 +1014,28 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) {
} else
controller = SYSTEMD_CGROUP_CONTROLLER;
- unified = cg_unified(controller);
+ unified = cg_unified_controller(controller);
if (unified < 0)
return unified;
+ if (unified == 0) {
+ if (streq(controller, SYSTEMD_CGROUP_CONTROLLER))
+ controller_str = SYSTEMD_CGROUP_CONTROLLER_LEGACY;
+ else
+ controller_str = controller;
+ }
fs = procfs_file_alloca(pid, "cgroup");
f = fopen(fs, "re");
if (!f)
return errno == ENOENT ? -ESRCH : -errno;
- return cg_pid_get_path_internal(unified ? NULL : controller, f, path);
+ return cg_pid_get_path_internal(controller_str, f, path);
}
/**
* NB: The meaning of @controller is different here than for cg_pid_get_path():
*
- * controller : the cgroup v1 hierarchy with this controller bound to it
+ * controller : the cgroup v1 hierarchy with @controller bound to it
* controller == NULL : the cgroup v2 (unified) hierarchy
*/
int cg_pid_get_path_internal(const char *controller, FILE *f, char **path) {
@@ -1029,14 +1105,14 @@ int cg_pid_get_path_internal(const char *controller, FILE *f, char **path) {
int cg_install_release_agent(const char *controller, const char *agent) {
_cleanup_free_ char *fs = NULL, *contents = NULL;
const char *sc;
- int r, unified;
+ int r;
assert(agent);
- unified = cg_unified(controller);
- if (unified < 0)
- return unified;
- if (unified) /* doesn't apply to unified hierarchy */
+ r = cg_unified_controller(controller);
+ if (r < 0)
+ return r;
+ if (r > 0) /* doesn't apply to unified hierarchy */
return -EOPNOTSUPP;
r = cg_get_path(controller, NULL, "release_agent", &fs);
@@ -1082,12 +1158,12 @@ int cg_install_release_agent(const char *controller, const char *agent) {
int cg_uninstall_release_agent(const char *controller) {
_cleanup_free_ char *fs = NULL;
- int r, unified;
+ int r;
- unified = cg_unified(controller);
- if (unified < 0)
- return unified;
- if (unified) /* Doesn't apply to unified hierarchy */
+ r = cg_unified_controller(controller);
+ if (r < 0)
+ return r;
+ if (r > 0) /* Doesn't apply to unified hierarchy */
return -EOPNOTSUPP;
r = cg_get_path(controller, NULL, "notify_on_release", &fs);
@@ -1132,7 +1208,7 @@ int cg_is_empty(const char *controller, const char *path) {
}
int cg_is_empty_recursive(const char *controller, const char *path) {
- int unified, r;
+ int r;
assert(path);
@@ -1140,11 +1216,10 @@ int cg_is_empty_recursive(const char *controller, const char *path) {
if (controller && (isempty(path) || path_equal(path, "/")))
return false;
- unified = cg_unified(controller);
- if (unified < 0)
- return unified;
-
- if (unified > 0) {
+ r = cg_unified_controller(controller);
+ if (r < 0)
+ return r;
+ if (r > 0) {
_cleanup_free_ char *t = NULL;
/* On the unified hierarchy we can check empty state
@@ -1172,7 +1247,7 @@ int cg_is_empty_recursive(const char *controller, const char *path) {
while ((r = cg_read_subgroup(d, &fn)) > 0) {
_cleanup_free_ char *p = NULL;
- p = strjoin(path, "/", fn, NULL);
+ p = strjoin(path, "/", fn);
free(fn);
if (!p)
return -ENOMEM;
@@ -1861,6 +1936,9 @@ bool cg_controller_is_valid(const char *p) {
if (!p)
return false;
+ if (streq(p, SYSTEMD_CGROUP_CONTROLLER))
+ return true;
+
s = startswith(p, "name=");
if (s)
p = s;
@@ -2014,7 +2092,7 @@ int cg_get_keyed_attribute(const char *controller, const char *path, const char
int cg_create_everywhere(CGroupMask supported, CGroupMask mask, const char *path) {
CGroupController c;
- int r, unified;
+ int r;
/* This one will create a cgroup in our private tree, but also
* duplicate it in the trees specified in mask, and remove it
@@ -2026,10 +2104,10 @@ int cg_create_everywhere(CGroupMask supported, CGroupMask mask, const char *path
return r;
/* If we are in the unified hierarchy, we are done now */
- unified = cg_all_unified();
- if (unified < 0)
- return unified;
- if (unified > 0)
+ r = cg_all_unified();
+ if (r < 0)
+ return r;
+ if (r > 0)
return 0;
/* Otherwise, do the same in the other hierarchies */
@@ -2050,16 +2128,16 @@ int cg_create_everywhere(CGroupMask supported, CGroupMask mask, const char *path
int cg_attach_everywhere(CGroupMask supported, const char *path, pid_t pid, cg_migrate_callback_t path_callback, void *userdata) {
CGroupController c;
- int r, unified;
+ int r;
r = cg_attach(SYSTEMD_CGROUP_CONTROLLER, path, pid);
if (r < 0)
return r;
- unified = cg_all_unified();
- if (unified < 0)
- return unified;
- if (unified > 0)
+ r = cg_all_unified();
+ if (r < 0)
+ return r;
+ if (r > 0)
return 0;
for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
@@ -2100,7 +2178,7 @@ int cg_attach_many_everywhere(CGroupMask supported, const char *path, Set* pids,
int cg_migrate_everywhere(CGroupMask supported, const char *from, const char *to, cg_migrate_callback_t to_callback, void *userdata) {
CGroupController c;
- int r = 0, unified;
+ int r = 0, q;
if (!path_equal(from, to)) {
r = cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, from, SYSTEMD_CGROUP_CONTROLLER, to, CGROUP_REMOVE);
@@ -2108,10 +2186,10 @@ int cg_migrate_everywhere(CGroupMask supported, const char *from, const char *to
return r;
}
- unified = cg_all_unified();
- if (unified < 0)
- return unified;
- if (unified > 0)
+ q = cg_all_unified();
+ if (q < 0)
+ return q;
+ if (q > 0)
return r;
for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
@@ -2135,16 +2213,16 @@ int cg_migrate_everywhere(CGroupMask supported, const char *from, const char *to
int cg_trim_everywhere(CGroupMask supported, const char *path, bool delete_root) {
CGroupController c;
- int r, unified;
+ int r, q;
r = cg_trim(SYSTEMD_CGROUP_CONTROLLER, path, delete_root);
if (r < 0)
return r;
- unified = cg_all_unified();
- if (unified < 0)
- return unified;
- if (unified > 0)
+ q = cg_all_unified();
+ if (q < 0)
+ return q;
+ if (q > 0)
return r;
for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
@@ -2161,16 +2239,16 @@ int cg_trim_everywhere(CGroupMask supported, const char *path, bool delete_root)
int cg_mask_supported(CGroupMask *ret) {
CGroupMask mask = 0;
- int r, unified;
+ int r;
/* Determines the mask of supported cgroup controllers. Only
* includes controllers we can make sense of and that are
* actually accessible. */
- unified = cg_all_unified();
- if (unified < 0)
- return unified;
- if (unified > 0) {
+ r = cg_all_unified();
+ if (r < 0)
+ return r;
+ if (r > 0) {
_cleanup_free_ char *root = NULL, *controllers = NULL, *path = NULL;
const char *c;
@@ -2290,7 +2368,7 @@ int cg_kernel_controllers(Set *controllers) {
static thread_local CGroupUnified unified_cache = CGROUP_UNIFIED_UNKNOWN;
-static int cg_update_unified(void) {
+static int cg_unified_update(void) {
struct statfs fs;
@@ -2308,65 +2386,97 @@ static int cg_update_unified(void) {
if (F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC))
unified_cache = CGROUP_UNIFIED_ALL;
else if (F_TYPE_EQUAL(fs.f_type, TMPFS_MAGIC)) {
- if (statfs("/sys/fs/cgroup/systemd/", &fs) < 0)
- return -errno;
-
- unified_cache = F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC) ?
- CGROUP_UNIFIED_SYSTEMD : CGROUP_UNIFIED_NONE;
+ if (statfs("/sys/fs/cgroup/unified/", &fs) == 0 &&
+ F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC)) {
+ unified_cache = CGROUP_UNIFIED_SYSTEMD233;
+ } else if (statfs("/sys/fs/cgroup/systemd/", &fs) == 0 &&
+ F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC)) {
+ unified_cache = CGROUP_UNIFIED_SYSTEMD232;
+ } else {
+ if (statfs("/sys/fs/cgroup/systemd/", &fs) < 0)
+ return -errno;
+ if (!F_TYPE_EQUAL(fs.f_type, CGROUP_SUPER_MAGIC))
+ return -ENOMEDIUM;
+ unified_cache = CGROUP_UNIFIED_NONE;
+ }
} else
return -ENOMEDIUM;
return 0;
}
-int cg_unified(const char *controller) {
-
+int cg_unified_controller(const char *controller) {
int r;
- r = cg_update_unified();
+ r = cg_unified_update();
if (r < 0)
return r;
- if (streq_ptr(controller, SYSTEMD_CGROUP_CONTROLLER))
- return unified_cache >= CGROUP_UNIFIED_SYSTEMD;
- else
- return unified_cache >= CGROUP_UNIFIED_ALL;
+ switch (unified_cache) {
+ default:
+ case CGROUP_UNIFIED_UNKNOWN:
+ assert_not_reached("unknown cgroup version");
+ case CGROUP_UNIFIED_NONE:
+ return false;
+ case CGROUP_UNIFIED_SYSTEMD232:
+ case CGROUP_UNIFIED_SYSTEMD233:
+ return streq_ptr(controller, SYSTEMD_CGROUP_CONTROLLER);
+ case CGROUP_UNIFIED_ALL:
+ return true;
+ }
}
int cg_all_unified(void) {
+ int r;
+
+ r = cg_unified_update();
+ if (r < 0)
+ return r;
- return cg_unified(NULL);
+ return unified_cache >= CGROUP_UNIFIED_ALL;
}
-int cg_version(CGroupUnified *ver) {
+int cg_hybrid_unified(void) {
int r;
- r = cg_update_unified();
+ r = cg_unified_update();
if (r < 0)
return r;
- *ver = unified_cache;
- return 0;
+ return unified_cache == CGROUP_UNIFIED_SYSTEMD233;
}
-void cg_unified_flush(void) {
+int cg_unified_flush(void) {
unified_cache = CGROUP_UNIFIED_UNKNOWN;
+
+ return cg_unified_update();
+}
+
+int cg_version(CGroupUnified *ver) {
+ int r;
+
+ r = cg_unified_update();
+ if (r < 0)
+ return r;
+
+ *ver = unified_cache;
+ return 0;
}
int cg_enable_everywhere(CGroupMask supported, CGroupMask mask, const char *p) {
_cleanup_free_ char *fs = NULL;
CGroupController c;
- int r, unified;
+ int r;
assert(p);
if (supported == 0)
return 0;
- unified = cg_all_unified();
- if (unified < 0)
- return unified;
- if (!unified) /* on the legacy hiearchy there's no joining of controllers defined */
+ r = cg_all_unified();
+ if (r < 0)
+ return r;
+ if (r == 0) /* on the legacy hiearchy there's no joining of controllers defined */
return 0;
r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, p, "cgroup.subtree_control", &fs);
@@ -2398,82 +2508,69 @@ int cg_enable_everywhere(CGroupMask supported, CGroupMask mask, const char *p) {
bool cg_is_unified_wanted(void) {
static thread_local int wanted = -1;
- int r, unified;
-
- /* If the hierarchy is already mounted, then follow whatever
- * was chosen for it. */
- unified = cg_all_unified();
- if (unified >= 0)
- return unified;
+ int r;
+ bool b;
+ const bool is_default = DEFAULT_HIERARCHY == CGROUP_UNIFIED_ALL;
- /* Otherwise, let's see what the kernel command line has to
- * say. Since checking that is expensive, let's cache the
- * result. */
+ /* If we have a cached value, return that. */
if (wanted >= 0)
return wanted;
- r = get_proc_cmdline_key("systemd.unified_cgroup_hierarchy", NULL);
- if (r > 0)
- return (wanted = true);
- else {
- _cleanup_free_ char *value = NULL;
+ /* If the hierarchy is already mounted, then follow whatever
+ * was chosen for it. */
+ if (cg_unified_flush() >= 0)
+ return (wanted = unified_cache >= CGROUP_UNIFIED_ALL);
- r = get_proc_cmdline_key("systemd.unified_cgroup_hierarchy=", &value);
- if (r < 0)
- return false;
- if (r == 0)
- return (wanted = false);
+ /* Otherwise, let's see what the kernel command line has to say.
+ * Since checking is expensive, cache a non-error result. */
+ r = proc_cmdline_get_bool("systemd.unified_cgroup_hierarchy", &b);
- return (wanted = parse_boolean(value) > 0);
- }
+ return (wanted = r > 0 ? b : is_default);
}
bool cg_is_legacy_wanted(void) {
- return !cg_is_unified_wanted();
-}
-
-bool cg_is_unified_systemd_controller_wanted(void) {
static thread_local int wanted = -1;
- int r, unified;
- /* If the unified hierarchy is requested in full, no need to
- * bother with this. */
- if (cg_is_unified_wanted())
- return 0;
-
- /* If the hierarchy is already mounted, then follow whatever
- * was chosen for it. */
- unified = cg_unified(SYSTEMD_CGROUP_CONTROLLER);
- if (unified >= 0)
- return unified;
-
- /* Otherwise, let's see what the kernel command line has to
- * say. Since checking that is expensive, let's cache the
- * result. */
+ /* If we have a cached value, return that. */
if (wanted >= 0)
return wanted;
- r = get_proc_cmdline_key("systemd.legacy_systemd_cgroup_controller", NULL);
- if (r > 0)
- wanted = false;
- else {
- _cleanup_free_ char *value = NULL;
+ /* Check if we have cgroups2 already mounted. */
+ if (cg_unified_flush() >= 0 &&
+ unified_cache == CGROUP_UNIFIED_ALL)
+ return (wanted = false);
- r = get_proc_cmdline_key("systemd.legacy_systemd_cgroup_controller=", &value);
- if (r < 0)
- return false;
+ /* Otherwise, assume that at least partial legacy is wanted,
+ * since cgroups2 should already be mounted at this point. */
+ return (wanted = true);
+}
- if (r == 0)
- wanted = false;
- else
- wanted = parse_boolean(value) <= 0;
- }
+bool cg_is_hybrid_wanted(void) {
+ static thread_local int wanted = -1;
+ int r;
+ bool b;
+ const bool is_default = DEFAULT_HIERARCHY >= CGROUP_UNIFIED_SYSTEMD232;
+ /* We default to true if the default is "hybrid", obviously,
+ * but also when the default is "unified", because if we get
+ * called, it means that unified hierarchy was not mounted. */
- return wanted;
-}
+ /* If we have a cached value, return that. */
+ if (wanted >= 0)
+ return wanted;
+
+ /* If the hierarchy is already mounted, then follow whatever
+ * was chosen for it. */
+ if (cg_unified_flush() >= 0 &&
+ unified_cache == CGROUP_UNIFIED_ALL)
+ return (wanted = false);
+
+ /* Otherwise, let's see what the kernel command line has to say.
+ * Since checking is expensive, cache a non-error result. */
+ r = proc_cmdline_get_bool("systemd.legacy_systemd_cgroup_controller", &b);
-bool cg_is_legacy_systemd_controller_wanted(void) {
- return cg_is_legacy_wanted() && !cg_is_unified_systemd_controller_wanted();
+ /* The meaning of the kernel option is reversed wrt. to the return value
+ * of this function, hence the negation. */
+ return (wanted = r > 0 ? !b : is_default);
}
int cg_weight_parse(const char *s, uint64_t *ret) {
diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h
index 3406e0b4fb..3cf11788e7 100644
--- a/src/basic/cgroup-util.h
+++ b/src/basic/cgroup-util.h
@@ -121,8 +121,9 @@ typedef enum CGroupUnified {
CGROUP_UNIFIED_INHERIT = -2, /* special case only used by nspawn */
CGROUP_UNIFIED_UNKNOWN = -1,
CGROUP_UNIFIED_NONE = 0, /* Both systemd and controllers on legacy */
- CGROUP_UNIFIED_SYSTEMD = 1, /* Only systemd on unified */
- CGROUP_UNIFIED_ALL = 2, /* Both systemd and controllers on unified */
+ CGROUP_UNIFIED_SYSTEMD232 = 1, /* Only systemd on unified, as done by SD232 */
+ CGROUP_UNIFIED_SYSTEMD233 = 2, /* Only systemd on unified, as done by SD233+ */
+ CGROUP_UNIFIED_ALL = 3, /* Both systemd and controllers on unified */
} CGroupUnified;
/*
@@ -243,14 +244,14 @@ int cg_kernel_controllers(Set *controllers);
bool cg_ns_supported(void);
int cg_all_unified(void);
-int cg_unified(const char *controller);
+int cg_hybrid_unified(void);
+int cg_unified_controller(const char *controller);
+int cg_unified_flush(void);
int cg_version(CGroupUnified *ver);
-void cg_unified_flush(void);
bool cg_is_unified_wanted(void);
bool cg_is_legacy_wanted(void);
-bool cg_is_unified_systemd_controller_wanted(void);
-bool cg_is_legacy_systemd_controller_wanted(void);
+bool cg_is_hybrid_wanted(void);
const char* cgroup_controller_to_string(CGroupController c) _const_;
CGroupController cgroup_controller_from_string(const char *s) _pure_;
diff --git a/src/basic/conf-files.c b/src/basic/conf-files.c
index c781610e14..b8f0f5d03d 100644
--- a/src/basic/conf-files.c
+++ b/src/basic/conf-files.c
@@ -43,7 +43,6 @@ static int files_add(Hashmap *h, const char *root, const char *path, const char
int r;
assert(path);
- assert(suffix);
dirpath = prefix_roota(root, path);
@@ -60,7 +59,7 @@ static int files_add(Hashmap *h, const char *root, const char *path, const char
if (!dirent_is_file_with_suffix(de, suffix))
continue;
- p = strjoin(dirpath, "/", de->d_name, NULL);
+ p = strjoin(dirpath, "/", de->d_name);
if (!p)
return -ENOMEM;
@@ -94,7 +93,6 @@ static int conf_files_list_strv_internal(char ***strv, const char *suffix, const
int r;
assert(strv);
- assert(suffix);
/* This alters the dirs string array */
if (!path_strv_resolve_uniq(dirs, root))
@@ -126,7 +124,6 @@ int conf_files_list_strv(char ***strv, const char *suffix, const char *root, con
_cleanup_strv_free_ char **copy = NULL;
assert(strv);
- assert(suffix);
copy = strv_copy((char**) dirs);
if (!copy)
@@ -140,7 +137,6 @@ int conf_files_list(char ***strv, const char *suffix, const char *root, const ch
va_list ap;
assert(strv);
- assert(suffix);
va_start(ap, dir);
dirs = strv_new_ap(dir, ap);
@@ -156,7 +152,6 @@ int conf_files_list_nulstr(char ***strv, const char *suffix, const char *root, c
_cleanup_strv_free_ char **dirs = NULL;
assert(strv);
- assert(suffix);
dirs = strv_split_nulstr(d);
if (!dirs)
diff --git a/src/basic/copy.c b/src/basic/copy.c
index 9883f5fa31..e120b9eb4e 100644
--- a/src/basic/copy.c
+++ b/src/basic/copy.c
@@ -45,6 +45,7 @@
#include "strv.h"
#include "time-util.h"
#include "umask-util.h"
+#include "user-util.h"
#include "xattr-util.h"
#define COPY_BUFFER_SIZE (16*1024u)
@@ -68,7 +69,7 @@ static ssize_t try_copy_file_range(int fd_in, loff_t *off_in,
return -errno;
}
-int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
+int copy_bytes(int fdf, int fdt, uint64_t max_bytes, CopyFlags copy_flags) {
bool try_cfr = true, try_sendfile = true, try_splice = true;
int r;
size_t m = SSIZE_MAX; /* that is the maximum that sendfile and c_f_r accept */
@@ -77,7 +78,7 @@ int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
assert(fdt >= 0);
/* Try btrfs reflinks first. */
- if (try_reflink &&
+ if ((copy_flags & COPY_REFLINK) &&
max_bytes == (uint64_t) -1 &&
lseek(fdf, 0, SEEK_CUR) == 0 &&
lseek(fdt, 0, SEEK_CUR) == 0) {
@@ -176,7 +177,16 @@ int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
return 0; /* return 0 if we hit EOF earlier than the size limit */
}
-static int fd_copy_symlink(int df, const char *from, const struct stat *st, int dt, const char *to) {
+static int fd_copy_symlink(
+ int df,
+ const char *from,
+ const struct stat *st,
+ int dt,
+ const char *to,
+ uid_t override_uid,
+ gid_t override_gid,
+ CopyFlags copy_flags) {
+
_cleanup_free_ char *target = NULL;
int r;
@@ -191,13 +201,25 @@ static int fd_copy_symlink(int df, const char *from, const struct stat *st, int
if (symlinkat(target, dt, to) < 0)
return -errno;
- if (fchownat(dt, to, st->st_uid, st->st_gid, AT_SYMLINK_NOFOLLOW) < 0)
+ if (fchownat(dt, to,
+ uid_is_valid(override_uid) ? override_uid : st->st_uid,
+ gid_is_valid(override_gid) ? override_gid : st->st_gid,
+ AT_SYMLINK_NOFOLLOW) < 0)
return -errno;
return 0;
}
-static int fd_copy_regular(int df, const char *from, const struct stat *st, int dt, const char *to) {
+static int fd_copy_regular(
+ int df,
+ const char *from,
+ const struct stat *st,
+ int dt,
+ const char *to,
+ uid_t override_uid,
+ gid_t override_gid,
+ CopyFlags copy_flags) {
+
_cleanup_close_ int fdf = -1, fdt = -1;
struct timespec ts[2];
int r, q;
@@ -214,13 +236,15 @@ static int fd_copy_regular(int df, const char *from, const struct stat *st, int
if (fdt < 0)
return -errno;
- r = copy_bytes(fdf, fdt, (uint64_t) -1, true);
+ r = copy_bytes(fdf, fdt, (uint64_t) -1, copy_flags);
if (r < 0) {
unlinkat(dt, to, 0);
return r;
}
- if (fchown(fdt, st->st_uid, st->st_gid) < 0)
+ if (fchown(fdt,
+ uid_is_valid(override_uid) ? override_uid : st->st_uid,
+ gid_is_valid(override_gid) ? override_gid : st->st_gid) < 0)
r = -errno;
if (fchmod(fdt, st->st_mode & 07777) < 0)
@@ -229,7 +253,6 @@ static int fd_copy_regular(int df, const char *from, const struct stat *st, int
ts[0] = st->st_atim;
ts[1] = st->st_mtim;
(void) futimens(fdt, ts);
-
(void) copy_xattr(fdf, fdt);
q = close(fdt);
@@ -243,7 +266,15 @@ static int fd_copy_regular(int df, const char *from, const struct stat *st, int
return r;
}
-static int fd_copy_fifo(int df, const char *from, const struct stat *st, int dt, const char *to) {
+static int fd_copy_fifo(
+ int df,
+ const char *from,
+ const struct stat *st,
+ int dt,
+ const char *to,
+ uid_t override_uid,
+ gid_t override_gid,
+ CopyFlags copy_flags) {
int r;
assert(from);
@@ -254,7 +285,10 @@ static int fd_copy_fifo(int df, const char *from, const struct stat *st, int dt,
if (r < 0)
return -errno;
- if (fchownat(dt, to, st->st_uid, st->st_gid, AT_SYMLINK_NOFOLLOW) < 0)
+ if (fchownat(dt, to,
+ uid_is_valid(override_uid) ? override_uid : st->st_uid,
+ gid_is_valid(override_gid) ? override_gid : st->st_gid,
+ AT_SYMLINK_NOFOLLOW) < 0)
r = -errno;
if (fchmodat(dt, to, st->st_mode & 07777, 0) < 0)
@@ -263,7 +297,15 @@ static int fd_copy_fifo(int df, const char *from, const struct stat *st, int dt,
return r;
}
-static int fd_copy_node(int df, const char *from, const struct stat *st, int dt, const char *to) {
+static int fd_copy_node(
+ int df,
+ const char *from,
+ const struct stat *st,
+ int dt,
+ const char *to,
+ uid_t override_uid,
+ gid_t override_gid,
+ CopyFlags copy_flags) {
int r;
assert(from);
@@ -274,7 +316,10 @@ static int fd_copy_node(int df, const char *from, const struct stat *st, int dt,
if (r < 0)
return -errno;
- if (fchownat(dt, to, st->st_uid, st->st_gid, AT_SYMLINK_NOFOLLOW) < 0)
+ if (fchownat(dt, to,
+ uid_is_valid(override_uid) ? override_uid : st->st_uid,
+ gid_is_valid(override_gid) ? override_gid : st->st_gid,
+ AT_SYMLINK_NOFOLLOW) < 0)
r = -errno;
if (fchmodat(dt, to, st->st_mode & 07777, 0) < 0)
@@ -290,7 +335,9 @@ static int fd_copy_directory(
int dt,
const char *to,
dev_t original_device,
- bool merge) {
+ uid_t override_uid,
+ gid_t override_gid,
+ CopyFlags copy_flags) {
_cleanup_close_ int fdf = -1, fdt = -1;
_cleanup_closedir_ DIR *d = NULL;
@@ -316,7 +363,7 @@ static int fd_copy_directory(
r = mkdirat(dt, to, st->st_mode & 07777);
if (r >= 0)
created = true;
- else if (errno == EEXIST && merge)
+ else if (errno == EEXIST && (copy_flags & COPY_MERGE))
created = false;
else
return -errno;
@@ -331,7 +378,7 @@ static int fd_copy_directory(
struct stat buf;
int q;
- if (STR_IN_SET(de->d_name, ".", ".."))
+ if (dot_or_dot_dot(de->d_name))
continue;
if (fstatat(dirfd(d), de->d_name, &buf, AT_SYMLINK_NOFOLLOW) < 0) {
@@ -343,19 +390,19 @@ static int fd_copy_directory(
continue;
if (S_ISREG(buf.st_mode))
- q = fd_copy_regular(dirfd(d), de->d_name, &buf, fdt, de->d_name);
+ q = fd_copy_regular(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags);
else if (S_ISDIR(buf.st_mode))
- q = fd_copy_directory(dirfd(d), de->d_name, &buf, fdt, de->d_name, original_device, merge);
+ q = fd_copy_directory(dirfd(d), de->d_name, &buf, fdt, de->d_name, original_device, override_uid, override_gid, copy_flags);
else if (S_ISLNK(buf.st_mode))
- q = fd_copy_symlink(dirfd(d), de->d_name, &buf, fdt, de->d_name);
+ q = fd_copy_symlink(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags);
else if (S_ISFIFO(buf.st_mode))
- q = fd_copy_fifo(dirfd(d), de->d_name, &buf, fdt, de->d_name);
+ q = fd_copy_fifo(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags);
else if (S_ISBLK(buf.st_mode) || S_ISCHR(buf.st_mode) || S_ISSOCK(buf.st_mode))
- q = fd_copy_node(dirfd(d), de->d_name, &buf, fdt, de->d_name);
+ q = fd_copy_node(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags);
else
q = -EOPNOTSUPP;
- if (q == -EEXIST && merge)
+ if (q == -EEXIST && (copy_flags & COPY_MERGE))
q = 0;
if (q < 0)
@@ -368,7 +415,9 @@ static int fd_copy_directory(
st->st_mtim
};
- if (fchown(fdt, st->st_uid, st->st_gid) < 0)
+ if (fchown(fdt,
+ uid_is_valid(override_uid) ? override_uid : st->st_uid,
+ gid_is_valid(override_gid) ? override_gid : st->st_gid) < 0)
r = -errno;
if (fchmod(fdt, st->st_mode & 07777) < 0)
@@ -381,7 +430,7 @@ static int fd_copy_directory(
return r;
}
-int copy_tree_at(int fdf, const char *from, int fdt, const char *to, bool merge) {
+int copy_tree_at(int fdf, const char *from, int fdt, const char *to, uid_t override_uid, gid_t override_gid, CopyFlags copy_flags) {
struct stat st;
assert(from);
@@ -391,24 +440,24 @@ int copy_tree_at(int fdf, const char *from, int fdt, const char *to, bool merge)
return -errno;
if (S_ISREG(st.st_mode))
- return fd_copy_regular(fdf, from, &st, fdt, to);
+ return fd_copy_regular(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags);
else if (S_ISDIR(st.st_mode))
- return fd_copy_directory(fdf, from, &st, fdt, to, st.st_dev, merge);
+ return fd_copy_directory(fdf, from, &st, fdt, to, st.st_dev, override_uid, override_gid, copy_flags);
else if (S_ISLNK(st.st_mode))
- return fd_copy_symlink(fdf, from, &st, fdt, to);
+ return fd_copy_symlink(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags);
else if (S_ISFIFO(st.st_mode))
- return fd_copy_fifo(fdf, from, &st, fdt, to);
+ return fd_copy_fifo(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags);
else if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode) || S_ISSOCK(st.st_mode))
- return fd_copy_node(fdf, from, &st, fdt, to);
+ return fd_copy_node(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags);
else
return -EOPNOTSUPP;
}
-int copy_tree(const char *from, const char *to, bool merge) {
- return copy_tree_at(AT_FDCWD, from, AT_FDCWD, to, merge);
+int copy_tree(const char *from, const char *to, uid_t override_uid, gid_t override_gid, CopyFlags copy_flags) {
+ return copy_tree_at(AT_FDCWD, from, AT_FDCWD, to, override_uid, override_gid, copy_flags);
}
-int copy_directory_fd(int dirfd, const char *to, bool merge) {
+int copy_directory_fd(int dirfd, const char *to, CopyFlags copy_flags) {
struct stat st;
assert(dirfd >= 0);
@@ -420,10 +469,10 @@ int copy_directory_fd(int dirfd, const char *to, bool merge) {
if (!S_ISDIR(st.st_mode))
return -ENOTDIR;
- return fd_copy_directory(dirfd, NULL, &st, AT_FDCWD, to, st.st_dev, merge);
+ return fd_copy_directory(dirfd, NULL, &st, AT_FDCWD, to, st.st_dev, UID_INVALID, GID_INVALID, copy_flags);
}
-int copy_directory(const char *from, const char *to, bool merge) {
+int copy_directory(const char *from, const char *to, CopyFlags copy_flags) {
struct stat st;
assert(from);
@@ -435,10 +484,10 @@ int copy_directory(const char *from, const char *to, bool merge) {
if (!S_ISDIR(st.st_mode))
return -ENOTDIR;
- return fd_copy_directory(AT_FDCWD, from, &st, AT_FDCWD, to, st.st_dev, merge);
+ return fd_copy_directory(AT_FDCWD, from, &st, AT_FDCWD, to, st.st_dev, UID_INVALID, GID_INVALID, copy_flags);
}
-int copy_file_fd(const char *from, int fdt, bool try_reflink) {
+int copy_file_fd(const char *from, int fdt, CopyFlags copy_flags) {
_cleanup_close_ int fdf = -1;
int r;
@@ -449,7 +498,7 @@ int copy_file_fd(const char *from, int fdt, bool try_reflink) {
if (fdf < 0)
return -errno;
- r = copy_bytes(fdf, fdt, (uint64_t) -1, try_reflink);
+ r = copy_bytes(fdf, fdt, (uint64_t) -1, copy_flags);
(void) copy_times(fdf, fdt);
(void) copy_xattr(fdf, fdt);
@@ -457,7 +506,7 @@ int copy_file_fd(const char *from, int fdt, bool try_reflink) {
return r;
}
-int copy_file(const char *from, const char *to, int flags, mode_t mode, unsigned chattr_flags) {
+int copy_file(const char *from, const char *to, int flags, mode_t mode, unsigned chattr_flags, CopyFlags copy_flags) {
int fdt = -1, r;
assert(from);
@@ -472,7 +521,7 @@ int copy_file(const char *from, const char *to, int flags, mode_t mode, unsigned
if (chattr_flags != 0)
(void) chattr_fd(fdt, chattr_flags, (unsigned) -1);
- r = copy_file_fd(from, fdt, true);
+ r = copy_file_fd(from, fdt, copy_flags);
if (r < 0) {
close(fdt);
unlink(to);
@@ -487,7 +536,7 @@ int copy_file(const char *from, const char *to, int flags, mode_t mode, unsigned
return 0;
}
-int copy_file_atomic(const char *from, const char *to, mode_t mode, bool replace, unsigned chattr_flags) {
+int copy_file_atomic(const char *from, const char *to, mode_t mode, unsigned chattr_flags, CopyFlags copy_flags) {
_cleanup_free_ char *t = NULL;
int r;
@@ -498,18 +547,18 @@ int copy_file_atomic(const char *from, const char *to, mode_t mode, bool replace
if (r < 0)
return r;
- r = copy_file(from, t, O_NOFOLLOW|O_EXCL, mode, chattr_flags);
+ r = copy_file(from, t, O_NOFOLLOW|O_EXCL, mode, chattr_flags, copy_flags);
if (r < 0)
return r;
- if (replace) {
+ if (copy_flags & COPY_REPLACE) {
r = renameat(AT_FDCWD, t, AT_FDCWD, to);
if (r < 0)
r = -errno;
} else
r = rename_noreplace(AT_FDCWD, t, AT_FDCWD, to);
if (r < 0) {
- (void) unlink_noerrno(t);
+ (void) unlink(t);
return r;
}
diff --git a/src/basic/copy.h b/src/basic/copy.h
index b5d08ebafe..4f3e11423e 100644
--- a/src/basic/copy.h
+++ b/src/basic/copy.h
@@ -24,13 +24,19 @@
#include <stdint.h>
#include <sys/types.h>
-int copy_file_fd(const char *from, int to, bool try_reflink);
-int copy_file(const char *from, const char *to, int flags, mode_t mode, unsigned chattr_flags);
-int copy_file_atomic(const char *from, const char *to, mode_t mode, bool replace, unsigned chattr_flags);
-int copy_tree(const char *from, const char *to, bool merge);
-int copy_tree_at(int fdf, const char *from, int fdt, const char *to, bool merge);
-int copy_directory_fd(int dirfd, const char *to, bool merge);
-int copy_directory(const char *from, const char *to, bool merge);
-int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink);
+typedef enum CopyFlags {
+ COPY_REFLINK = 0x1, /* try to reflink */
+ COPY_MERGE = 0x2, /* merge existing trees with our new one to copy */
+ COPY_REPLACE = 0x4, /* replace an existing file if there's one */
+} CopyFlags;
+
+int copy_file_fd(const char *from, int to, CopyFlags copy_flags);
+int copy_file(const char *from, const char *to, int open_flags, mode_t mode, unsigned chattr_flags, CopyFlags copy_flags);
+int copy_file_atomic(const char *from, const char *to, mode_t mode, unsigned chattr_flags, CopyFlags copy_flags);
+int copy_tree(const char *from, const char *to, uid_t override_uid, gid_t override_gid, CopyFlags copy_flags);
+int copy_tree_at(int fdf, const char *from, int fdt, const char *to, uid_t override_uid, gid_t override_gid, CopyFlags copy_flags);
+int copy_directory_fd(int dirfd, const char *to, CopyFlags copy_flags);
+int copy_directory(const char *from, const char *to, CopyFlags copy_flags);
+int copy_bytes(int fdf, int fdt, uint64_t max_bytes, CopyFlags copy_flags);
int copy_times(int fdf, int fdt);
int copy_xattr(int fdf, int fdt);
diff --git a/src/basic/def.h b/src/basic/def.h
index 2266eff650..200ea973c1 100644
--- a/src/basic/def.h
+++ b/src/basic/def.h
@@ -36,7 +36,9 @@
/* The default value for the net.unix.max_dgram_qlen sysctl */
#define DEFAULT_UNIX_MAX_DGRAM_QLEN 512UL
-#define SYSTEMD_CGROUP_CONTROLLER "name=systemd"
+#define SYSTEMD_CGROUP_CONTROLLER_LEGACY "name=systemd"
+#define SYSTEMD_CGROUP_CONTROLLER_HYBRID "name=unified"
+#define SYSTEMD_CGROUP_CONTROLLER "_systemd"
#define SIGNALS_CRASH_HANDLER SIGSEGV,SIGILL,SIGFPE,SIGBUS,SIGQUIT,SIGABRT
#define SIGNALS_IGNORE SIGPIPE
@@ -73,18 +75,18 @@
#define NOTIFY_BUFFER_MAX PIPE_BUF
#ifdef HAVE_SPLIT_USR
-#define _CONF_PATHS_SPLIT_USR(n) "/lib/" n "\0"
+# define _CONF_PATHS_SPLIT_USR(n) "/lib/" n "\0"
#else
-#define _CONF_PATHS_SPLIT_USR(n)
+# define _CONF_PATHS_SPLIT_USR(n)
#endif
/* Return a nulstr for a standard cascade of configuration paths,
* suitable to pass to conf_files_list_nulstr() or config_parse_many_nulstr()
* to implement drop-in directories for extending configuration
* files. */
-#define CONF_PATHS_NULSTR(n) \
- "/etc/" n "\0" \
- "/run/" n "\0" \
- "/usr/local/lib/" n "\0" \
- "/usr/lib/" n "\0" \
+#define CONF_PATHS_NULSTR(n) \
+ "/etc/" n "\0" \
+ "/run/" n "\0" \
+ "/usr/local/lib/" n "\0" \
+ "/usr/lib/" n "\0" \
_CONF_PATHS_SPLIT_USR(n)
diff --git a/src/basic/dirent-util.c b/src/basic/dirent-util.c
index 59067121b7..6b9d26773e 100644
--- a/src/basic/dirent-util.c
+++ b/src/basic/dirent-util.c
@@ -70,5 +70,8 @@ bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
if (de->d_name[0] == '.')
return false;
+ if (!suffix)
+ return true;
+
return endswith(de->d_name, suffix);
}
diff --git a/src/basic/env-util.c b/src/basic/env-util.c
index b74290d6fd..e79b441ab6 100644
--- a/src/basic/env-util.c
+++ b/src/basic/env-util.c
@@ -26,6 +26,7 @@
#include "alloc-util.h"
#include "env-util.h"
+#include "escape.h"
#include "extract-word.h"
#include "macro.h"
#include "parse-util.h"
@@ -247,7 +248,7 @@ fail:
return NULL;
}
-_pure_ static bool env_match(const char *t, const char *pattern) {
+static bool env_match(const char *t, const char *pattern) {
assert(t);
assert(pattern);
@@ -273,6 +274,19 @@ _pure_ static bool env_match(const char *t, const char *pattern) {
return false;
}
+static bool env_entry_has_name(const char *entry, const char *name) {
+ const char *t;
+
+ assert(entry);
+ assert(name);
+
+ t = startswith(entry, name);
+ if (!t)
+ return false;
+
+ return *t == '=';
+}
+
char **strv_env_delete(char **x, unsigned n_lists, ...) {
size_t n, i = 0;
char **k, **r;
@@ -384,6 +398,35 @@ char **strv_env_unset_many(char **l, ...) {
return l;
}
+int strv_env_replace(char ***l, char *p) {
+ char **f;
+ const char *t, *name;
+
+ assert(p);
+
+ /* Replace first occurrence of the env var or add a new one in the
+ * string list. Drop other occurences. Edits in-place. Does not copy p.
+ * p must be a valid key=value assignment.
+ */
+
+ t = strchr(p, '=');
+ assert(t);
+
+ name = strndupa(p, t - p);
+
+ for (f = *l; f && *f; f++)
+ if (env_entry_has_name(*f, name)) {
+ free_and_replace(*f, p);
+ strv_env_unset(f + 1, *f);
+ return 0;
+ }
+
+ /* We didn't find a match, we need to append p or create a new strv */
+ if (strv_push(l, p) < 0)
+ return -ENOMEM;
+ return 1;
+}
+
char **strv_env_set(char **x, const char *p) {
char **k, **r;
@@ -411,7 +454,7 @@ fail:
return NULL;
}
-char *strv_env_get_n(char **l, const char *name, size_t k) {
+char *strv_env_get_n(char **l, const char *name, size_t k, unsigned flags) {
char **i;
assert(name);
@@ -419,18 +462,25 @@ char *strv_env_get_n(char **l, const char *name, size_t k) {
if (k <= 0)
return NULL;
- STRV_FOREACH(i, l)
+ STRV_FOREACH_BACKWARDS(i, l)
if (strneq(*i, name, k) &&
(*i)[k] == '=')
return *i + k + 1;
+ if (flags & REPLACE_ENV_USE_ENVIRONMENT) {
+ const char *t;
+
+ t = strndupa(name, k);
+ return getenv(t);
+ };
+
return NULL;
}
char *strv_env_get(char **l, const char *name) {
assert(name);
- return strv_env_get_n(l, name, strlen(name));
+ return strv_env_get_n(l, name, strlen(name), 0);
}
char **strv_env_clean_with_callback(char **e, void (*invalid_callback)(const char *p, void *userdata), void *userdata) {
@@ -469,19 +519,26 @@ char **strv_env_clean_with_callback(char **e, void (*invalid_callback)(const cha
return e;
}
-char *replace_env(const char *format, char **env) {
+char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) {
enum {
WORD,
CURLY,
- VARIABLE
+ VARIABLE,
+ VARIABLE_RAW,
+ TEST,
+ DEFAULT_VALUE,
+ ALTERNATE_VALUE,
} state = WORD;
- const char *e, *word = format;
- char *r = NULL, *k;
+ const char *e, *word = format, *test_value;
+ char *k;
+ _cleanup_free_ char *r = NULL;
+ size_t i, len;
+ int nest = 0;
assert(format);
- for (e = format; *e; e ++) {
+ for (e = format, i = 0; *e && i < n; e ++, i ++) {
switch (state) {
@@ -494,24 +551,36 @@ char *replace_env(const char *format, char **env) {
if (*e == '{') {
k = strnappend(r, word, e-word-1);
if (!k)
- goto fail;
+ return NULL;
free(r);
r = k;
word = e-1;
state = VARIABLE;
-
+ nest++;
} else if (*e == '$') {
k = strnappend(r, word, e-word);
if (!k)
- goto fail;
+ return NULL;
free(r);
r = k;
word = e+1;
state = WORD;
+
+ } else if (flags & REPLACE_ENV_ALLOW_BRACELESS && strchr(VALID_CHARS_ENV_NAME, *e)) {
+ k = strnappend(r, word, e-word-1);
+ if (!k)
+ return NULL;
+
+ free(r);
+ r = k;
+
+ word = e-1;
+ state = VARIABLE_RAW;
+
} else
state = WORD;
break;
@@ -520,11 +589,68 @@ char *replace_env(const char *format, char **env) {
if (*e == '}') {
const char *t;
- t = strempty(strv_env_get_n(env, word+2, e-word-2));
+ t = strv_env_get_n(env, word+2, e-word-2, flags);
+
+ k = strappend(r, t);
+ if (!k)
+ return NULL;
+
+ free(r);
+ r = k;
+
+ word = e+1;
+ state = WORD;
+ } else if (*e == ':') {
+ if (!(flags & REPLACE_ENV_ALLOW_EXTENDED))
+ /* Treat this as unsupported syntax, i.e. do no replacement */
+ state = WORD;
+ else {
+ len = e-word-2;
+ state = TEST;
+ }
+ }
+ break;
+
+ case TEST:
+ if (*e == '-')
+ state = DEFAULT_VALUE;
+ else if (*e == '+')
+ state = ALTERNATE_VALUE;
+ else {
+ state = WORD;
+ break;
+ }
+
+ test_value = e+1;
+ break;
+
+ case DEFAULT_VALUE: /* fall through */
+ case ALTERNATE_VALUE:
+ assert(flags & REPLACE_ENV_ALLOW_EXTENDED);
+
+ if (*e == '{') {
+ nest++;
+ break;
+ }
+
+ if (*e != '}')
+ break;
+
+ nest--;
+ if (nest == 0) {
+ const char *t;
+ _cleanup_free_ char *v = NULL;
+
+ t = strv_env_get_n(env, word+2, len, flags);
+
+ if (t && state == ALTERNATE_VALUE)
+ t = v = replace_env_n(test_value, e-test_value, env, flags);
+ else if (!t && state == DEFAULT_VALUE)
+ t = v = replace_env_n(test_value, e-test_value, env, flags);
k = strappend(r, t);
if (!k)
- goto fail;
+ return NULL;
free(r);
r = k;
@@ -533,18 +659,39 @@ char *replace_env(const char *format, char **env) {
state = WORD;
}
break;
+
+ case VARIABLE_RAW:
+ assert(flags & REPLACE_ENV_ALLOW_BRACELESS);
+
+ if (!strchr(VALID_CHARS_ENV_NAME, *e)) {
+ const char *t;
+
+ t = strv_env_get_n(env, word+1, e-word-1, flags);
+
+ k = strappend(r, t);
+ if (!k)
+ return NULL;
+
+ free(r);
+ r = k;
+
+ word = e--;
+ i--;
+ state = WORD;
+ }
+ break;
}
}
- k = strnappend(r, word, e-word);
- if (!k)
- goto fail;
+ if (state == VARIABLE_RAW) {
+ const char *t;
- free(r);
- return k;
+ assert(flags & REPLACE_ENV_ALLOW_BRACELESS);
-fail:
- return mfree(r);
+ t = strv_env_get_n(env, word+1, e-word-1, flags);
+ return strappend(r, t);
+ } else
+ return strnappend(r, word, e-word);
}
char **replace_env_argv(char **argv, char **env) {
@@ -600,7 +747,7 @@ char **replace_env_argv(char **argv, char **env) {
}
/* If ${FOO} appears as part of a word, replace it by the variable as-is */
- ret[k] = replace_env(*i, env);
+ ret[k] = replace_env(*i, env, 0);
if (!ret[k]) {
strv_free(ret);
return NULL;
@@ -621,3 +768,41 @@ int getenv_bool(const char *p) {
return parse_boolean(e);
}
+
+int serialize_environment(FILE *f, char **environment) {
+ char **e;
+
+ STRV_FOREACH(e, environment) {
+ _cleanup_free_ char *ce;
+
+ ce = cescape(*e);
+ if (!ce)
+ return -ENOMEM;
+
+ fprintf(f, "env=%s\n", *e);
+ }
+
+ /* caller should call ferror() */
+
+ return 0;
+}
+
+int deserialize_environment(char ***environment, const char *line) {
+ char *uce = NULL;
+ int r;
+
+ assert(line);
+ assert(environment);
+
+ assert(startswith(line, "env="));
+ r = cunescape(line + 4, UNESCAPE_RELAX, &uce);
+ if (r < 0)
+ return r;
+
+ if (!env_assignment_is_valid(uce)) {
+ free(uce);
+ return -EINVAL;
+ }
+
+ return strv_env_replace(environment, uce);
+}
diff --git a/src/basic/env-util.h b/src/basic/env-util.h
index b1fef704c2..e88fa6aac0 100644
--- a/src/basic/env-util.h
+++ b/src/basic/env-util.h
@@ -21,6 +21,7 @@
#include <stdbool.h>
#include <stddef.h>
+#include <stdio.h>
#include "macro.h"
@@ -28,9 +29,19 @@ bool env_name_is_valid(const char *e);
bool env_value_is_valid(const char *e);
bool env_assignment_is_valid(const char *e);
-char *replace_env(const char *format, char **env);
+enum {
+ REPLACE_ENV_USE_ENVIRONMENT = 1u,
+ REPLACE_ENV_ALLOW_BRACELESS = 2u,
+ REPLACE_ENV_ALLOW_EXTENDED = 4u,
+};
+
+char *replace_env_n(const char *format, size_t n, char **env, unsigned flags);
char **replace_env_argv(char **argv, char **env);
+static inline char *replace_env(const char *format, char **env, unsigned flags) {
+ return replace_env_n(format, strlen(format), env, flags);
+}
+
bool strv_env_is_valid(char **e);
#define strv_env_clean(l) strv_env_clean_with_callback(l, NULL, NULL)
char **strv_env_clean_with_callback(char **l, void (*invalid_callback)(const char *p, void *userdata), void *userdata);
@@ -44,8 +55,12 @@ char **strv_env_delete(char **x, unsigned n_lists, ...); /* New copy */
char **strv_env_set(char **x, const char *p); /* New copy ... */
char **strv_env_unset(char **l, const char *p); /* In place ... */
char **strv_env_unset_many(char **l, ...) _sentinel_;
+int strv_env_replace(char ***l, char *p); /* In place ... */
-char *strv_env_get_n(char **l, const char *name, size_t k) _pure_;
+char *strv_env_get_n(char **l, const char *name, size_t k, unsigned flags) _pure_;
char *strv_env_get(char **x, const char *n) _pure_;
int getenv_bool(const char *p);
+
+int serialize_environment(FILE *f, char **environment);
+int deserialize_environment(char ***environment, const char *line);
diff --git a/src/basic/exec-util.c b/src/basic/exec-util.c
new file mode 100644
index 0000000000..aced9e8e3d
--- /dev/null
+++ b/src/basic/exec-util.c
@@ -0,0 +1,360 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dirent.h>
+#include <errno.h>
+#include <sys/prctl.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include "alloc-util.h"
+#include "conf-files.h"
+#include "env-util.h"
+#include "exec-util.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "hashmap.h"
+#include "macro.h"
+#include "process-util.h"
+#include "set.h"
+#include "signal-util.h"
+#include "stat-util.h"
+#include "string-util.h"
+#include "strv.h"
+#include "terminal-util.h"
+#include "util.h"
+
+/* Put this test here for a lack of better place */
+assert_cc(EAGAIN == EWOULDBLOCK);
+
+static int do_spawn(const char *path, char *argv[], int stdout_fd, pid_t *pid) {
+
+ pid_t _pid;
+
+ if (null_or_empty_path(path)) {
+ log_debug("%s is empty (a mask).", path);
+ return 0;
+ }
+
+ _pid = fork();
+ if (_pid < 0)
+ return log_error_errno(errno, "Failed to fork: %m");
+ if (_pid == 0) {
+ char *_argv[2];
+
+ assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
+
+ if (stdout_fd >= 0) {
+ /* If the fd happens to be in the right place, go along with that */
+ if (stdout_fd != STDOUT_FILENO &&
+ dup2(stdout_fd, STDOUT_FILENO) < 0)
+ return -errno;
+
+ fd_cloexec(STDOUT_FILENO, false);
+ }
+
+ if (!argv) {
+ _argv[0] = (char*) path;
+ _argv[1] = NULL;
+ argv = _argv;
+ } else
+ argv[0] = (char*) path;
+
+ execv(path, argv);
+ log_error_errno(errno, "Failed to execute %s: %m", path);
+ _exit(EXIT_FAILURE);
+ }
+
+ log_debug("Spawned %s as " PID_FMT ".", path, _pid);
+ *pid = _pid;
+ return 1;
+}
+
+static int do_execute(
+ char **directories,
+ usec_t timeout,
+ gather_stdout_callback_t const callbacks[_STDOUT_CONSUME_MAX],
+ void* const callback_args[_STDOUT_CONSUME_MAX],
+ int output_fd,
+ char *argv[]) {
+
+ _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
+ _cleanup_strv_free_ char **paths = NULL;
+ char **path;
+ int r;
+
+ /* We fork this all off from a child process so that we can somewhat cleanly make
+ * use of SIGALRM to set a time limit.
+ *
+ * If callbacks is nonnull, execution is serial. Otherwise, we default to parallel.
+ */
+
+ (void) reset_all_signal_handlers();
+ (void) reset_signal_mask();
+
+ assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
+
+ r = conf_files_list_strv(&paths, NULL, NULL, (const char* const*) directories);
+ if (r < 0)
+ return r;
+
+ if (!callbacks) {
+ pids = hashmap_new(NULL);
+ if (!pids)
+ return log_oom();
+ }
+
+ /* Abort execution of this process after the timout. We simply rely on SIGALRM as
+ * default action terminating the process, and turn on alarm(). */
+
+ if (timeout != USEC_INFINITY)
+ alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
+
+ STRV_FOREACH(path, paths) {
+ _cleanup_free_ char *t = NULL;
+ _cleanup_close_ int fd = -1;
+ pid_t pid;
+
+ t = strdup(*path);
+ if (!t)
+ return log_oom();
+
+ if (callbacks) {
+ fd = open_serialization_fd(basename(*path));
+ if (fd < 0)
+ return log_error_errno(fd, "Failed to open serialization file: %m");
+ }
+
+ r = do_spawn(t, argv, fd, &pid);
+ if (r <= 0)
+ continue;
+
+ if (pids) {
+ r = hashmap_put(pids, PID_TO_PTR(pid), t);
+ if (r < 0)
+ return log_oom();
+ t = NULL;
+ } else {
+ r = wait_for_terminate_and_warn(t, pid, true);
+ if (r < 0)
+ continue;
+
+ if (lseek(fd, 0, SEEK_SET) < 0)
+ return log_error_errno(errno, "Failed to seek on serialization fd: %m");
+
+ r = callbacks[STDOUT_GENERATE](fd, callback_args[STDOUT_GENERATE]);
+ fd = -1;
+ if (r < 0)
+ return log_error_errno(r, "Failed to process output from %s: %m", *path);
+ }
+ }
+
+ if (callbacks) {
+ r = callbacks[STDOUT_COLLECT](output_fd, callback_args[STDOUT_COLLECT]);
+ if (r < 0)
+ return log_error_errno(r, "Callback two failed: %m");
+ }
+
+ while (!hashmap_isempty(pids)) {
+ _cleanup_free_ char *t = NULL;
+ pid_t pid;
+
+ pid = PTR_TO_PID(hashmap_first_key(pids));
+ assert(pid > 0);
+
+ t = hashmap_remove(pids, PID_TO_PTR(pid));
+ assert(t);
+
+ wait_for_terminate_and_warn(t, pid, true);
+ }
+
+ return 0;
+}
+
+int execute_directories(
+ const char* const* directories,
+ usec_t timeout,
+ gather_stdout_callback_t const callbacks[_STDOUT_CONSUME_MAX],
+ void* const callback_args[_STDOUT_CONSUME_MAX],
+ char *argv[]) {
+
+ pid_t executor_pid;
+ char *name;
+ char **dirs = (char**) directories;
+ _cleanup_close_ int fd = -1;
+ int r;
+
+ assert(!strv_isempty(dirs));
+
+ name = basename(dirs[0]);
+ assert(!isempty(name));
+
+ if (callbacks) {
+ assert(callback_args);
+ assert(callbacks[STDOUT_GENERATE]);
+ assert(callbacks[STDOUT_COLLECT]);
+ assert(callbacks[STDOUT_CONSUME]);
+
+ fd = open_serialization_fd(name);
+ if (fd < 0)
+ return log_error_errno(fd, "Failed to open serialization file: %m");
+ }
+
+ /* Executes all binaries in the directories serially or in parallel and waits for
+ * them to finish. Optionally a timeout is applied. If a file with the same name
+ * exists in more than one directory, the earliest one wins. */
+
+ executor_pid = fork();
+ if (executor_pid < 0)
+ return log_error_errno(errno, "Failed to fork: %m");
+
+ if (executor_pid == 0) {
+ r = do_execute(dirs, timeout, callbacks, callback_args, fd, argv);
+ _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
+ }
+
+ r = wait_for_terminate_and_warn(name, executor_pid, true);
+ if (r < 0)
+ return log_error_errno(r, "Execution failed: %m");
+ if (r > 0) {
+ /* non-zero return code from child */
+ log_error("Forker process failed.");
+ return -EREMOTEIO;
+ }
+
+ if (!callbacks)
+ return 0;
+
+ if (lseek(fd, 0, SEEK_SET) < 0)
+ return log_error_errno(errno, "Failed to rewind serialization fd: %m");
+
+ r = callbacks[STDOUT_CONSUME](fd, callback_args[STDOUT_CONSUME]);
+ fd = -1;
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse returned data: %m");
+ return 0;
+}
+
+static int gather_environment_generate(int fd, void *arg) {
+ char ***env = arg, **x, **y;
+ _cleanup_fclose_ FILE *f = NULL;
+ _cleanup_strv_free_ char **new;
+ int r;
+
+ /* Read a series of VAR=value assignments from fd, use them to update the list of
+ * variables in env. Also update the exported environment.
+ *
+ * fd is always consumed, even on error.
+ */
+
+ assert(env);
+
+ f = fdopen(fd, "r");
+ if (!f) {
+ safe_close(fd);
+ return -errno;
+ }
+
+ r = load_env_file_pairs(f, NULL, NULL, &new);
+ if (r < 0)
+ return r;
+
+ STRV_FOREACH_PAIR(x, y, new) {
+ char *p;
+
+ if (!env_name_is_valid(*x)) {
+ log_warning("Invalid variable assignment \"%s=...\", ignoring.", *x);
+ continue;
+ }
+
+ p = strjoin(*x, "=", *y);
+ if (!p)
+ return -ENOMEM;
+
+ r = strv_env_replace(env, p);
+ if (r < 0)
+ return r;
+
+ if (setenv(*x, *y, true) < 0)
+ return -errno;
+ }
+
+ return r;
+}
+
+static int gather_environment_collect(int fd, void *arg) {
+ char ***env = arg;
+ _cleanup_fclose_ FILE *f = NULL;
+ int r;
+
+ /* Write out a series of env=cescape(VAR=value) assignments to fd. */
+
+ assert(env);
+
+ f = fdopen(fd, "w");
+ if (!f) {
+ safe_close(fd);
+ return -errno;
+ }
+
+ r = serialize_environment(f, *env);
+ if (r < 0)
+ return r;
+
+ if (ferror(f))
+ return errno > 0 ? -errno : -EIO;
+
+ return 0;
+}
+
+static int gather_environment_consume(int fd, void *arg) {
+ char ***env = arg;
+ _cleanup_fclose_ FILE *f = NULL;
+ char line[LINE_MAX];
+ int r = 0, k;
+
+ /* Read a series of env=cescape(VAR=value) assignments from fd into env. */
+
+ assert(env);
+
+ f = fdopen(fd, "r");
+ if (!f) {
+ safe_close(fd);
+ return -errno;
+ }
+
+ FOREACH_LINE(line, f, return -EIO) {
+ truncate_nl(line);
+
+ k = deserialize_environment(env, line);
+ if (k < 0)
+ log_error_errno(k, "Invalid line \"%s\": %m", line);
+ if (k < 0 && r == 0)
+ r = k;
+ }
+
+ return r;
+}
+
+const gather_stdout_callback_t gather_environment[] = {
+ gather_environment_generate,
+ gather_environment_collect,
+ gather_environment_consume,
+};
diff --git a/src/basic/exec-util.h b/src/basic/exec-util.h
new file mode 100644
index 0000000000..72009799b2
--- /dev/null
+++ b/src/basic/exec-util.h
@@ -0,0 +1,40 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+
+#include "time-util.h"
+
+typedef int (*gather_stdout_callback_t) (int fd, void *arg);
+
+enum {
+ STDOUT_GENERATE, /* from generators to helper process */
+ STDOUT_COLLECT, /* from helper process to main process */
+ STDOUT_CONSUME, /* process data in main process */
+ _STDOUT_CONSUME_MAX,
+};
+
+int execute_directories(
+ const char* const* directories,
+ usec_t timeout,
+ gather_stdout_callback_t const callbacks[_STDOUT_CONSUME_MAX],
+ void* const callback_args[_STDOUT_CONSUME_MAX],
+ char *argv[]);
+
+extern const gather_stdout_callback_t gather_environment[_STDOUT_CONSUME_MAX];
diff --git a/src/basic/extract-word.c b/src/basic/extract-word.c
index d6c1228463..f8cac3e911 100644
--- a/src/basic/extract-word.c
+++ b/src/basic/extract-word.c
@@ -48,7 +48,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
/* Bail early if called after last value or with no input */
if (!*p)
- goto finish_force_terminate;
+ goto finish;
c = **p;
if (!separators)
@@ -227,8 +227,8 @@ int extract_first_word_and_warn(
*p = save;
r = extract_first_word(p, ret, separators, flags|EXTRACT_CUNESCAPE_RELAX);
if (r >= 0) {
- /* It worked this time, hence it must have been an invalid escape sequence we could correct. */
- log_syntax(unit, LOG_WARNING, filename, line, EINVAL, "Invalid escape sequences in line, correcting: \"%s\"", rvalue);
+ /* It worked this time, hence it must have been an invalid escape sequence. */
+ log_syntax(unit, LOG_WARNING, filename, line, EINVAL, "Ignoring unknown escape sequences: \"%s\"", *ret);
return r;
}
diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c
index 5c820332a5..19ad20789b 100644
--- a/src/basic/fd-util.c
+++ b/src/basic/fd-util.c
@@ -24,6 +24,7 @@
#include <sys/stat.h>
#include <unistd.h>
+#include "dirent-util.h"
#include "fd-util.h"
#include "fs-util.h"
#include "macro.h"
@@ -234,12 +235,9 @@ int close_all_fds(const int except[], unsigned n_except) {
return r;
}
- while ((de = readdir(d))) {
+ FOREACH_DIRENT(de, d, return -errno) {
int fd = -1;
- if (hidden_or_backup_file(de->d_name))
- continue;
-
if (safe_atoi(de->d_name, &fd) < 0)
/* Let's better ignore this, just in case */
continue;
diff --git a/src/basic/fileio.c b/src/basic/fileio.c
index 1cfb7a98f5..7c2c2b38f5 100644
--- a/src/basic/fileio.c
+++ b/src/basic/fileio.c
@@ -30,6 +30,7 @@
#include "alloc-util.h"
#include "ctype.h"
+#include "env-util.h"
#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
@@ -553,13 +554,14 @@ static int parse_env_file_internal(
}
}
- if (state == PRE_VALUE ||
- state == VALUE ||
- state == VALUE_ESCAPE ||
- state == SINGLE_QUOTE_VALUE ||
- state == SINGLE_QUOTE_VALUE_ESCAPE ||
- state == DOUBLE_QUOTE_VALUE ||
- state == DOUBLE_QUOTE_VALUE_ESCAPE) {
+ if (IN_SET(state,
+ PRE_VALUE,
+ VALUE,
+ VALUE_ESCAPE,
+ SINGLE_QUOTE_VALUE,
+ SINGLE_QUOTE_VALUE_ESCAPE,
+ DOUBLE_QUOTE_VALUE,
+ DOUBLE_QUOTE_VALUE_ESCAPE)) {
key[n_key] = 0;
@@ -586,14 +588,9 @@ fail:
return r;
}
-static int parse_env_file_push(
+static int check_utf8ness_and_warn(
const char *filename, unsigned line,
- const char *key, char *value,
- void *userdata,
- int *n_pushed) {
-
- const char *k;
- va_list aq, *ap = userdata;
+ const char *key, char *value) {
if (!utf8_is_valid(key)) {
_cleanup_free_ char *p = NULL;
@@ -611,6 +608,23 @@ static int parse_env_file_push(
return -EINVAL;
}
+ return 0;
+}
+
+static int parse_env_file_push(
+ const char *filename, unsigned line,
+ const char *key, char *value,
+ void *userdata,
+ int *n_pushed) {
+
+ const char *k;
+ va_list aq, *ap = userdata;
+ int r;
+
+ r = check_utf8ness_and_warn(filename, line, key, value);
+ if (r < 0)
+ return r;
+
va_copy(aq, *ap);
while ((k = va_arg(aq, const char *))) {
@@ -662,27 +676,19 @@ static int load_env_file_push(
char *p;
int r;
- if (!utf8_is_valid(key)) {
- _cleanup_free_ char *t = utf8_escape_invalid(key);
-
- log_error("%s:%u: invalid UTF-8 for key '%s', ignoring.", strna(filename), line, t);
- return -EINVAL;
- }
-
- if (value && !utf8_is_valid(value)) {
- _cleanup_free_ char *t = utf8_escape_invalid(value);
-
- log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", strna(filename), line, key, t);
- return -EINVAL;
- }
+ r = check_utf8ness_and_warn(filename, line, key, value);
+ if (r < 0)
+ return r;
- p = strjoin(key, "=", strempty(value), NULL);
+ p = strjoin(key, "=", value);
if (!p)
return -ENOMEM;
- r = strv_consume(m, p);
- if (r < 0)
+ r = strv_env_replace(m, p);
+ if (r < 0) {
+ free(p);
return r;
+ }
if (n_pushed)
(*n_pushed)++;
@@ -716,19 +722,9 @@ static int load_env_file_push_pairs(
char ***m = userdata;
int r;
- if (!utf8_is_valid(key)) {
- _cleanup_free_ char *t = utf8_escape_invalid(key);
-
- log_error("%s:%u: invalid UTF-8 for key '%s', ignoring.", strna(filename), line, t);
- return -EINVAL;
- }
-
- if (value && !utf8_is_valid(value)) {
- _cleanup_free_ char *t = utf8_escape_invalid(value);
-
- log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", strna(filename), line, key, t);
- return -EINVAL;
- }
+ r = check_utf8ness_and_warn(filename, line, key, value);
+ if (r < 0)
+ return r;
r = strv_extend(m, key);
if (r < 0)
@@ -767,6 +763,52 @@ int load_env_file_pairs(FILE *f, const char *fname, const char *newline, char **
return 0;
}
+static int merge_env_file_push(
+ const char *filename, unsigned line,
+ const char *key, char *value,
+ void *userdata,
+ int *n_pushed) {
+
+ char ***env = userdata;
+ char *expanded_value;
+
+ assert(env);
+
+ if (!value) {
+ log_error("%s:%u: invalid syntax (around \"%s\"), ignoring.", strna(filename), line, key);
+ return 0;
+ }
+
+ if (!env_name_is_valid(key)) {
+ log_error("%s:%u: invalid variable name \"%s\", ignoring.", strna(filename), line, key);
+ free(value);
+ return 0;
+ }
+
+ expanded_value = replace_env(value, *env,
+ REPLACE_ENV_USE_ENVIRONMENT|
+ REPLACE_ENV_ALLOW_BRACELESS|
+ REPLACE_ENV_ALLOW_EXTENDED);
+ if (!expanded_value)
+ return -ENOMEM;
+
+ free_and_replace(value, expanded_value);
+
+ return load_env_file_push(filename, line, key, value, env, n_pushed);
+}
+
+int merge_env_file(
+ char ***env,
+ FILE *f,
+ const char *fname) {
+
+ /* NOTE: this function supports braceful and braceless variable expansions,
+ * plus "extended" substitutions, unlike other exported parsing functions.
+ */
+
+ return parse_env_file_internal(f, fname, NEWLINE, merge_env_file_push, env, NULL);
+}
+
static void write_env_var(FILE *f, const char *v) {
const char *p;
@@ -963,9 +1005,9 @@ static int search_and_fopen_internal(const char *path, const char *mode, const c
FILE *f;
if (root)
- p = strjoin(root, *i, "/", path, NULL);
+ p = strjoin(root, *i, "/", path);
else
- p = strjoin(*i, "/", path, NULL);
+ p = strjoin(*i, "/", path);
if (!p)
return -ENOMEM;
@@ -1342,6 +1384,25 @@ int open_tmpfile_linkable(const char *target, int flags, char **ret_path) {
return fd;
}
+int open_serialization_fd(const char *ident) {
+ int fd = -1;
+
+ fd = memfd_create(ident, MFD_CLOEXEC);
+ if (fd < 0) {
+ const char *path;
+
+ path = getpid() == 1 ? "/run/systemd" : "/tmp";
+ fd = open_tmpfile_unlinkable(path, O_RDWR|O_CLOEXEC);
+ if (fd < 0)
+ return fd;
+
+ log_debug("Serializing %s to %s.", ident, path);
+ } else
+ log_debug("Serializing %s to memfd.", ident);
+
+ return fd;
+}
+
int link_tmpfile(int fd, const char *path, const char *target) {
assert(fd >= 0);
@@ -1409,3 +1470,22 @@ int read_nul_string(FILE *f, char **ret) {
return 0;
}
+
+int mkdtemp_malloc(const char *template, char **ret) {
+ char *p;
+
+ assert(template);
+ assert(ret);
+
+ p = strdup(template);
+ if (!p)
+ return -ENOMEM;
+
+ if (!mkdtemp(p)) {
+ free(p);
+ return -errno;
+ }
+
+ *ret = p;
+ return 0;
+}
diff --git a/src/basic/fileio.h b/src/basic/fileio.h
index b58c83e64a..e547614cc4 100644
--- a/src/basic/fileio.h
+++ b/src/basic/fileio.h
@@ -48,6 +48,8 @@ int parse_env_file(const char *fname, const char *separator, ...) _sentinel_;
int load_env_file(FILE *f, const char *fname, const char *separator, char ***l);
int load_env_file_pairs(FILE *f, const char *fname, const char *separator, char ***l);
+int merge_env_file(char ***env, FILE *f, const char *fname);
+
int write_env_file(const char *fname, char **l);
int executable_is_script(const char *path, char **interpreter);
@@ -84,7 +86,10 @@ int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space)
int open_tmpfile_unlinkable(const char *directory, int flags);
int open_tmpfile_linkable(const char *target, int flags, char **ret_path);
+int open_serialization_fd(const char *ident);
int link_tmpfile(int fd, const char *path, const char *target);
int read_nul_string(FILE *f, char **ret);
+
+int mkdtemp_malloc(const char *template, char **ret);
diff --git a/src/basic/formats-util.h b/src/basic/format-util.h
index 39a185f59b..ae42a8f89e 100644
--- a/src/basic/formats-util.h
+++ b/src/basic/format-util.h
@@ -54,6 +54,12 @@
# error Unknown time_t size
#endif
+#if defined __x86_64__ && defined __ILP32__
+# define PRI_TIMEX PRIi64
+#else
+# define PRI_TIMEX "li"
+#endif
+
#if SIZEOF_RLIM_T == 8
# define RLIM_FMT "%" PRIu64
#elif SIZEOF_RLIM_T == 4
diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c
index 48952a1c26..8fe19ee4e4 100644
--- a/src/basic/fs-util.c
+++ b/src/basic/fs-util.c
@@ -17,7 +17,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <dirent.h>
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
@@ -224,25 +223,25 @@ int readlink_and_make_absolute(const char *p, char **r) {
return 0;
}
-int readlink_and_canonicalize(const char *p, char **r) {
+int readlink_and_canonicalize(const char *p, const char *root, char **ret) {
char *t, *s;
- int j;
+ int r;
assert(p);
- assert(r);
+ assert(ret);
- j = readlink_and_make_absolute(p, &t);
- if (j < 0)
- return j;
+ r = readlink_and_make_absolute(p, &t);
+ if (r < 0)
+ return r;
- s = canonicalize_file_name(t);
- if (s) {
+ r = chase_symlinks(t, root, 0, &s);
+ if (r < 0)
+ /* If we can't follow up, then let's return the original string, slightly cleaned up. */
+ *ret = path_kill_slashes(t);
+ else {
+ *ret = s;
free(t);
- *r = s;
- } else
- *r = t;
-
- path_kill_slashes(*r);
+ }
return 0;
}
@@ -446,6 +445,7 @@ int mkfifo_atomic(const char *path, mode_t mode) {
int get_files_in_directory(const char *path, char ***list) {
_cleanup_closedir_ DIR *d = NULL;
+ struct dirent *de;
size_t bufsize = 0, n = 0;
_cleanup_strv_free_ char **l = NULL;
@@ -459,16 +459,7 @@ int get_files_in_directory(const char *path, char ***list) {
if (!d)
return -errno;
- for (;;) {
- struct dirent *de;
-
- errno = 0;
- de = readdir(d);
- if (!de && errno > 0)
- return -errno;
- if (!de)
- break;
-
+ FOREACH_DIRENT_ALL(de, d, return -errno) {
dirent_ensure_type(d, de);
if (!dirent_is_file(de))
@@ -598,10 +589,11 @@ int inotify_add_watch_fd(int fd, int what, uint32_t mask) {
return r;
}
-int chase_symlinks(const char *path, const char *_root, char **ret) {
+int chase_symlinks(const char *path, const char *original_root, unsigned flags, char **ret) {
_cleanup_free_ char *buffer = NULL, *done = NULL, *root = NULL;
_cleanup_close_ int fd = -1;
unsigned max_follow = 32; /* how many symlinks to follow before giving up and returning ELOOP */
+ bool exists = true;
char *todo;
int r;
@@ -610,26 +602,39 @@ int chase_symlinks(const char *path, const char *_root, char **ret) {
/* This is a lot like canonicalize_file_name(), but takes an additional "root" parameter, that allows following
* symlinks relative to a root directory, instead of the root of the host.
*
- * Note that "root" matters only if we encounter an absolute symlink, it's unused otherwise. Most importantly
- * this means the path parameter passed in is not prefixed by it.
+ * Note that "root" primarily matters if we encounter an absolute symlink. It is also used when following
+ * relative symlinks to ensure they cannot be used to "escape" the root directory. The path parameter passed is
+ * assumed to be already prefixed by it, except if the CHASE_PREFIX_ROOT flag is set, in which case it is first
+ * prefixed accordingly.
*
* Algorithmically this operates on two path buffers: "done" are the components of the path we already
* processed and resolved symlinks, "." and ".." of. "todo" are the components of the path we still need to
* process. On each iteration, we move one component from "todo" to "done", processing it's special meaning
* each time. The "todo" path always starts with at least one slash, the "done" path always ends in no
* slash. We always keep an O_PATH fd to the component we are currently processing, thus keeping lookup races
- * at a minimum. */
-
- r = path_make_absolute_cwd(path, &buffer);
- if (r < 0)
- return r;
+ * at a minimum.
+ *
+ * Suggested usage: whenever you want to canonicalize a path, use this function. Pass the absolute path you got
+ * as-is: fully qualified and relative to your host's root. Optionally, specify the root parameter to tell this
+ * function what to do when encountering a symlink with an absolute path as directory: prefix it by the
+ * specified path.
+ *
+ * Note: there's also chase_symlinks_prefix() (see below), which as first step prefixes the passed path by the
+ * passed root. */
- if (_root) {
- r = path_make_absolute_cwd(_root, &root);
+ if (original_root) {
+ r = path_make_absolute_cwd(original_root, &root);
if (r < 0)
return r;
+
+ if (flags & CHASE_PREFIX_ROOT)
+ path = prefix_roota(root, path);
}
+ r = path_make_absolute_cwd(path, &buffer);
+ if (r < 0)
+ return r;
+
fd = open("/", O_CLOEXEC|O_NOFOLLOW|O_PATH);
if (fd < 0)
return -errno;
@@ -665,18 +670,20 @@ int chase_symlinks(const char *path, const char *_root, char **ret) {
_cleanup_free_ char *parent = NULL;
int fd_parent = -1;
+ /* If we already are at the top, then going up will not change anything. This is in-line with
+ * how the kernel handles this. */
if (isempty(done) || path_equal(done, "/"))
- return -EINVAL;
+ continue;
parent = dirname_malloc(done);
if (!parent)
return -ENOMEM;
- /* Don't allow this to leave the root dir */
+ /* Don't allow this to leave the root dir. */
if (root &&
path_startswith(done, root) &&
!path_startswith(parent, root))
- return -EINVAL;
+ continue;
free_and_replace(done, parent);
@@ -692,13 +699,32 @@ int chase_symlinks(const char *path, const char *_root, char **ret) {
/* Otherwise let's see what this is. */
child = openat(fd, first + n, O_CLOEXEC|O_NOFOLLOW|O_PATH);
- if (child < 0)
+ if (child < 0) {
+
+ if (errno == ENOENT &&
+ (flags & CHASE_NONEXISTENT) &&
+ (isempty(todo) || path_is_safe(todo))) {
+
+ /* If CHASE_NONEXISTENT is set, and the path does not exist, then that's OK, return
+ * what we got so far. But don't allow this if the remaining path contains "../ or "./"
+ * or something else weird. */
+
+ if (!strextend(&done, first, todo, NULL))
+ return -ENOMEM;
+
+ exists = false;
+ break;
+ }
+
return -errno;
+ }
if (fstat(child, &st) < 0)
return -errno;
if (S_ISLNK(st.st_mode)) {
+ char *joined;
+
_cleanup_free_ char *destination = NULL;
/* This is a symlink, in this case read the destination. But let's make sure we don't follow
@@ -722,9 +748,6 @@ int chase_symlinks(const char *path, const char *_root, char **ret) {
if (fd < 0)
return -errno;
- free_and_replace(buffer, destination);
-
- todo = buffer;
free(done);
/* Note that we do not revalidate the root, we take it as is. */
@@ -736,19 +759,17 @@ int chase_symlinks(const char *path, const char *_root, char **ret) {
return -ENOMEM;
}
- } else {
- char *joined;
+ }
- /* A relative destination. If so, this is what we'll prefix what's left to do with what
- * we just read, and start the loop again, but remain in the current directory. */
+ /* Prefix what's left to do with what we just read, and start the loop again,
+ * but remain in the current directory. */
- joined = strjoin("/", destination, todo, NULL);
- if (!joined)
- return -ENOMEM;
+ joined = strjoin("/", destination, todo);
+ if (!joined)
+ return -ENOMEM;
- free(buffer);
- todo = buffer = joined;
- }
+ free(buffer);
+ todo = buffer = joined;
continue;
}
@@ -775,8 +796,10 @@ int chase_symlinks(const char *path, const char *_root, char **ret) {
return -ENOMEM;
}
- *ret = done;
- done = NULL;
+ if (ret) {
+ *ret = done;
+ done = NULL;
+ }
- return 0;
+ return exists;
}
diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h
index 31df47cf1e..094acf1799 100644
--- a/src/basic/fs-util.h
+++ b/src/basic/fs-util.h
@@ -39,7 +39,7 @@ int readlinkat_malloc(int fd, const char *p, char **ret);
int readlink_malloc(const char *p, char **r);
int readlink_value(const char *p, char **ret);
int readlink_and_make_absolute(const char *p, char **r);
-int readlink_and_canonicalize(const char *p, char **r);
+int readlink_and_canonicalize(const char *p, const char *root, char **r);
int readlink_and_make_absolute_root(const char *root, const char *path, char **ret);
int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
@@ -78,4 +78,22 @@ union inotify_event_buffer {
int inotify_add_watch_fd(int fd, int what, uint32_t mask);
-int chase_symlinks(const char *path, const char *_root, char **ret);
+enum {
+ CHASE_PREFIX_ROOT = 1, /* If set, the specified path will be prefixed by the specified root before beginning the iteration */
+ CHASE_NONEXISTENT = 2, /* If set, it's OK if the path doesn't actually exist. */
+};
+
+int chase_symlinks(const char *path_with_prefix, const char *root, unsigned flags, char **ret);
+
+/* Useful for usage with _cleanup_(), removes a directory and frees the pointer */
+static inline void rmdir_and_free(char *p) {
+ (void) rmdir(p);
+ free(p);
+}
+DEFINE_TRIVIAL_CLEANUP_FUNC(char*, rmdir_and_free);
+
+static inline void unlink_and_free(char *p) {
+ (void) unlink(p);
+ free(p);
+}
+DEFINE_TRIVIAL_CLEANUP_FUNC(char*, unlink_and_free);
diff --git a/src/basic/hexdecoct.c b/src/basic/hexdecoct.c
index c5bda6c4d6..2d6e377f0a 100644
--- a/src/basic/hexdecoct.c
+++ b/src/basic/hexdecoct.c
@@ -72,10 +72,10 @@ int unhexchar(char c) {
}
char *hexmem(const void *p, size_t l) {
- char *r, *z;
const uint8_t *x;
+ char *r, *z;
- z = r = malloc(l * 2 + 1);
+ z = r = new(char, l * 2 + 1);
if (!r)
return NULL;
@@ -97,6 +97,9 @@ int unhexmem(const char *p, size_t l, void **mem, size_t *len) {
assert(len);
assert(p);
+ if (l % 2 != 0)
+ return -EINVAL;
+
z = r = malloc((l + 1) / 2 + 1);
if (!r)
return -ENOMEM;
@@ -107,12 +110,10 @@ int unhexmem(const char *p, size_t l, void **mem, size_t *len) {
a = unhexchar(x[0]);
if (a < 0)
return a;
- else if (x+1 < p + l) {
- b = unhexchar(x[1]);
- if (b < 0)
- return b;
- } else
- b = 0;
+
+ b = unhexchar(x[1]);
+ if (b < 0)
+ return b;
*(z++) = (uint8_t) a << 4 | (uint8_t) b;
}
diff --git a/src/basic/hostname-util.c b/src/basic/hostname-util.c
index e44a357287..a94037b303 100644
--- a/src/basic/hostname-util.c
+++ b/src/basic/hostname-util.c
@@ -55,7 +55,7 @@ char* gethostname_malloc(void) {
assert_se(uname(&u) >= 0);
if (isempty(u.nodename) || streq(u.nodename, "(none)"))
- return strdup(u.sysname);
+ return strdup(FALLBACK_HOSTNAME);
return strdup(u.nodename);
}
diff --git a/src/basic/in-addr-util.c b/src/basic/in-addr-util.c
index aa7ccd1afd..3927df2955 100644
--- a/src/basic/in-addr-util.c
+++ b/src/basic/in-addr-util.c
@@ -31,15 +31,9 @@
#include "util.h"
bool in4_addr_is_null(const struct in_addr *a) {
- return a->s_addr == 0;
-}
+ assert(a);
-bool in6_addr_is_null(const struct in6_addr *a) {
- return
- a->s6_addr32[0] == 0 &&
- a->s6_addr32[1] == 0 &&
- a->s6_addr32[2] == 0 &&
- a->s6_addr32[3] == 0;
+ return a->s_addr == 0;
}
int in_addr_is_null(int family, const union in_addr_union *u) {
@@ -49,16 +43,22 @@ int in_addr_is_null(int family, const union in_addr_union *u) {
return in4_addr_is_null(&u->in);
if (family == AF_INET6)
- return in6_addr_is_null(&u->in6);
+ return IN6_IS_ADDR_UNSPECIFIED(&u->in6);
return -EAFNOSUPPORT;
}
+bool in4_addr_is_link_local(const struct in_addr *a) {
+ assert(a);
+
+ return (be32toh(a->s_addr) & UINT32_C(0xFFFF0000)) == (UINT32_C(169) << 24 | UINT32_C(254) << 16);
+}
+
int in_addr_is_link_local(int family, const union in_addr_union *u) {
assert(u);
if (family == AF_INET)
- return (be32toh(u->in.s_addr) & UINT32_C(0xFFFF0000)) == (UINT32_C(169) << 24 | UINT32_C(254) << 16);
+ return in4_addr_is_link_local(&u->in);
if (family == AF_INET6)
return IN6_IS_ADDR_LINKLOCAL(&u->in6);
@@ -66,12 +66,30 @@ int in_addr_is_link_local(int family, const union in_addr_union *u) {
return -EAFNOSUPPORT;
}
+int in_addr_is_multicast(int family, const union in_addr_union *u) {
+ assert(u);
+
+ if (family == AF_INET)
+ return IN_MULTICAST(be32toh(u->in.s_addr));
+
+ if (family == AF_INET6)
+ return IN6_IS_ADDR_MULTICAST(&u->in6);
+
+ return -EAFNOSUPPORT;
+}
+
+bool in4_addr_is_localhost(const struct in_addr *a) {
+ assert(a);
+
+ /* All of 127.x.x.x is localhost. */
+ return (be32toh(a->s_addr) & UINT32_C(0xFF000000)) == UINT32_C(127) << 24;
+}
+
int in_addr_is_localhost(int family, const union in_addr_union *u) {
assert(u);
if (family == AF_INET)
- /* All of 127.x.x.x is localhost. */
- return (be32toh(u->in.s_addr) & UINT32_C(0xFF000000)) == UINT32_C(127) << 24;
+ return in4_addr_is_localhost(&u->in);
if (family == AF_INET6)
return IN6_IS_ADDR_LOOPBACK(&u->in6);
@@ -277,15 +295,14 @@ fallback:
}
int in_addr_from_string(int family, const char *s, union in_addr_union *ret) {
-
+ union in_addr_union buffer;
assert(s);
- assert(ret);
if (!IN_SET(family, AF_INET, AF_INET6))
return -EAFNOSUPPORT;
errno = 0;
- if (inet_pton(family, s, ret) <= 0)
+ if (inet_pton(family, s, ret ?: &buffer) <= 0)
return errno > 0 ? -errno : -EINVAL;
return 0;
@@ -295,18 +312,18 @@ int in_addr_from_string_auto(const char *s, int *family, union in_addr_union *re
int r;
assert(s);
- assert(family);
- assert(ret);
r = in_addr_from_string(AF_INET, s, ret);
if (r >= 0) {
- *family = AF_INET;
+ if (family)
+ *family = AF_INET;
return 0;
}
r = in_addr_from_string(AF_INET6, s, ret);
if (r >= 0) {
- *family = AF_INET6;
+ if (family)
+ *family = AF_INET6;
return 0;
}
diff --git a/src/basic/in-addr-util.h b/src/basic/in-addr-util.h
index d60064aef8..51a5aa67e4 100644
--- a/src/basic/in-addr-util.h
+++ b/src/basic/in-addr-util.h
@@ -37,11 +37,16 @@ struct in_addr_data {
};
bool in4_addr_is_null(const struct in_addr *a);
-bool in6_addr_is_null(const struct in6_addr *a);
-
int in_addr_is_null(int family, const union in_addr_union *u);
+
+int in_addr_is_multicast(int family, const union in_addr_union *u);
+
+bool in4_addr_is_link_local(const struct in_addr *a);
int in_addr_is_link_local(int family, const union in_addr_union *u);
+
+bool in4_addr_is_localhost(const struct in_addr *a);
int in_addr_is_localhost(int family, const union in_addr_union *u);
+
int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b);
int in_addr_prefix_intersect(int family, const union in_addr_union *a, unsigned aprefixlen, const union in_addr_union *b, unsigned bprefixlen);
int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen);
diff --git a/src/basic/journal-importer.c b/src/basic/journal-importer.c
new file mode 100644
index 0000000000..7d72effdea
--- /dev/null
+++ b/src/basic/journal-importer.c
@@ -0,0 +1,483 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+
+#include "alloc-util.h"
+#include "journal-importer.h"
+#include "fd-util.h"
+#include "parse-util.h"
+#include "string-util.h"
+#include "unaligned.h"
+
+enum {
+ IMPORTER_STATE_LINE = 0, /* waiting to read, or reading line */
+ IMPORTER_STATE_DATA_START, /* reading binary data header */
+ IMPORTER_STATE_DATA, /* reading binary data */
+ IMPORTER_STATE_DATA_FINISH, /* expecting newline */
+ IMPORTER_STATE_EOF, /* done */
+};
+
+static int iovw_put(struct iovec_wrapper *iovw, void* data, size_t len) {
+ if (!GREEDY_REALLOC(iovw->iovec, iovw->size_bytes, iovw->count + 1))
+ return log_oom();
+
+ iovw->iovec[iovw->count++] = (struct iovec) {data, len};
+ return 0;
+}
+
+static void iovw_free_contents(struct iovec_wrapper *iovw) {
+ iovw->iovec = mfree(iovw->iovec);
+ iovw->size_bytes = iovw->count = 0;
+}
+
+static void iovw_rebase(struct iovec_wrapper *iovw, char *old, char *new) {
+ size_t i;
+
+ for (i = 0; i < iovw->count; i++)
+ iovw->iovec[i].iov_base = (char*) iovw->iovec[i].iov_base - old + new;
+}
+
+size_t iovw_size(struct iovec_wrapper *iovw) {
+ size_t n = 0, i;
+
+ for (i = 0; i < iovw->count; i++)
+ n += iovw->iovec[i].iov_len;
+
+ return n;
+}
+
+void journal_importer_cleanup(JournalImporter *imp) {
+ if (imp->fd >= 0 && !imp->passive_fd) {
+ log_debug("Closing %s (fd=%d)", imp->name ?: "importer", imp->fd);
+ safe_close(imp->fd);
+ }
+
+ free(imp->name);
+ free(imp->buf);
+ iovw_free_contents(&imp->iovw);
+}
+
+static char* realloc_buffer(JournalImporter *imp, size_t size) {
+ char *b, *old = imp->buf;
+
+ b = GREEDY_REALLOC(imp->buf, imp->size, size);
+ if (!b)
+ return NULL;
+
+ iovw_rebase(&imp->iovw, old, imp->buf);
+
+ return b;
+}
+
+static int get_line(JournalImporter *imp, char **line, size_t *size) {
+ ssize_t n;
+ char *c = NULL;
+
+ assert(imp);
+ assert(imp->state == IMPORTER_STATE_LINE);
+ assert(imp->offset <= imp->filled);
+ assert(imp->filled <= imp->size);
+ assert(imp->buf == NULL || imp->size > 0);
+ assert(imp->fd >= 0);
+
+ for (;;) {
+ if (imp->buf) {
+ size_t start = MAX(imp->scanned, imp->offset);
+
+ c = memchr(imp->buf + start, '\n',
+ imp->filled - start);
+ if (c != NULL)
+ break;
+ }
+
+ imp->scanned = imp->filled;
+ if (imp->scanned >= DATA_SIZE_MAX) {
+ log_error("Entry is bigger than %u bytes.", DATA_SIZE_MAX);
+ return -E2BIG;
+ }
+
+ if (imp->passive_fd)
+ /* we have to wait for some data to come to us */
+ return -EAGAIN;
+
+ /* We know that imp->filled is at most DATA_SIZE_MAX, so if
+ we reallocate it, we'll increase the size at least a bit. */
+ assert_cc(DATA_SIZE_MAX < ENTRY_SIZE_MAX);
+ if (imp->size - imp->filled < LINE_CHUNK &&
+ !realloc_buffer(imp, MIN(imp->filled + LINE_CHUNK, ENTRY_SIZE_MAX)))
+ return log_oom();
+
+ assert(imp->buf);
+ assert(imp->size - imp->filled >= LINE_CHUNK ||
+ imp->size == ENTRY_SIZE_MAX);
+
+ n = read(imp->fd,
+ imp->buf + imp->filled,
+ imp->size - imp->filled);
+ if (n < 0) {
+ if (errno != EAGAIN)
+ log_error_errno(errno, "read(%d, ..., %zu): %m",
+ imp->fd,
+ imp->size - imp->filled);
+ return -errno;
+ } else if (n == 0)
+ return 0;
+
+ imp->filled += n;
+ }
+
+ *line = imp->buf + imp->offset;
+ *size = c + 1 - imp->buf - imp->offset;
+ imp->offset += *size;
+
+ return 1;
+}
+
+static int fill_fixed_size(JournalImporter *imp, void **data, size_t size) {
+
+ assert(imp);
+ assert(imp->state == IMPORTER_STATE_DATA_START ||
+ imp->state == IMPORTER_STATE_DATA ||
+ imp->state == IMPORTER_STATE_DATA_FINISH);
+ assert(size <= DATA_SIZE_MAX);
+ assert(imp->offset <= imp->filled);
+ assert(imp->filled <= imp->size);
+ assert(imp->buf != NULL || imp->size == 0);
+ assert(imp->buf == NULL || imp->size > 0);
+ assert(imp->fd >= 0);
+ assert(data);
+
+ while (imp->filled - imp->offset < size) {
+ int n;
+
+ if (imp->passive_fd)
+ /* we have to wait for some data to come to us */
+ return -EAGAIN;
+
+ if (!realloc_buffer(imp, imp->offset + size))
+ return log_oom();
+
+ n = read(imp->fd, imp->buf + imp->filled,
+ imp->size - imp->filled);
+ if (n < 0) {
+ if (errno != EAGAIN)
+ log_error_errno(errno, "read(%d, ..., %zu): %m", imp->fd,
+ imp->size - imp->filled);
+ return -errno;
+ } else if (n == 0)
+ return 0;
+
+ imp->filled += n;
+ }
+
+ *data = imp->buf + imp->offset;
+ imp->offset += size;
+
+ return 1;
+}
+
+static int get_data_size(JournalImporter *imp) {
+ int r;
+ void *data;
+
+ assert(imp);
+ assert(imp->state == IMPORTER_STATE_DATA_START);
+ assert(imp->data_size == 0);
+
+ r = fill_fixed_size(imp, &data, sizeof(uint64_t));
+ if (r <= 0)
+ return r;
+
+ imp->data_size = unaligned_read_le64(data);
+ if (imp->data_size > DATA_SIZE_MAX) {
+ log_error("Stream declares field with size %zu > DATA_SIZE_MAX = %u",
+ imp->data_size, DATA_SIZE_MAX);
+ return -EINVAL;
+ }
+ if (imp->data_size == 0)
+ log_warning("Binary field with zero length");
+
+ return 1;
+}
+
+static int get_data_data(JournalImporter *imp, void **data) {
+ int r;
+
+ assert(imp);
+ assert(data);
+ assert(imp->state == IMPORTER_STATE_DATA);
+
+ r = fill_fixed_size(imp, data, imp->data_size);
+ if (r <= 0)
+ return r;
+
+ return 1;
+}
+
+static int get_data_newline(JournalImporter *imp) {
+ int r;
+ char *data;
+
+ assert(imp);
+ assert(imp->state == IMPORTER_STATE_DATA_FINISH);
+
+ r = fill_fixed_size(imp, (void**) &data, 1);
+ if (r <= 0)
+ return r;
+
+ assert(data);
+ if (*data != '\n') {
+ log_error("expected newline, got '%c'", *data);
+ return -EINVAL;
+ }
+
+ return 1;
+}
+
+static int process_dunder(JournalImporter *imp, char *line, size_t n) {
+ const char *timestamp;
+ int r;
+
+ assert(line);
+ assert(n > 0);
+ assert(line[n-1] == '\n');
+
+ /* XXX: is it worth to support timestamps in extended format?
+ * We don't produce them, but who knows... */
+
+ timestamp = startswith(line, "__CURSOR=");
+ if (timestamp)
+ /* ignore __CURSOR */
+ return 1;
+
+ timestamp = startswith(line, "__REALTIME_TIMESTAMP=");
+ if (timestamp) {
+ long long unsigned x;
+ line[n-1] = '\0';
+ r = safe_atollu(timestamp, &x);
+ if (r < 0)
+ log_warning("Failed to parse __REALTIME_TIMESTAMP: '%s'", timestamp);
+ else
+ imp->ts.realtime = x;
+ return r < 0 ? r : 1;
+ }
+
+ timestamp = startswith(line, "__MONOTONIC_TIMESTAMP=");
+ if (timestamp) {
+ long long unsigned x;
+ line[n-1] = '\0';
+ r = safe_atollu(timestamp, &x);
+ if (r < 0)
+ log_warning("Failed to parse __MONOTONIC_TIMESTAMP: '%s'", timestamp);
+ else
+ imp->ts.monotonic = x;
+ return r < 0 ? r : 1;
+ }
+
+ timestamp = startswith(line, "__");
+ if (timestamp) {
+ log_notice("Unknown dunder line %s", line);
+ return 1;
+ }
+
+ /* no dunder */
+ return 0;
+}
+
+int journal_importer_process_data(JournalImporter *imp) {
+ int r;
+
+ switch(imp->state) {
+ case IMPORTER_STATE_LINE: {
+ char *line, *sep;
+ size_t n = 0;
+
+ assert(imp->data_size == 0);
+
+ r = get_line(imp, &line, &n);
+ if (r < 0)
+ return r;
+ if (r == 0) {
+ imp->state = IMPORTER_STATE_EOF;
+ return 0;
+ }
+ assert(n > 0);
+ assert(line[n-1] == '\n');
+
+ if (n == 1) {
+ log_trace("Received empty line, event is ready");
+ return 1;
+ }
+
+ r = process_dunder(imp, line, n);
+ if (r != 0)
+ return r < 0 ? r : 0;
+
+ /* MESSAGE=xxx\n
+ or
+ COREDUMP\n
+ LLLLLLLL0011223344...\n
+ */
+ sep = memchr(line, '=', n);
+ if (sep) {
+ /* chomp newline */
+ n--;
+
+ r = iovw_put(&imp->iovw, line, n);
+ if (r < 0)
+ return r;
+ } else {
+ /* replace \n with = */
+ line[n-1] = '=';
+
+ imp->field_len = n;
+ imp->state = IMPORTER_STATE_DATA_START;
+
+ /* we cannot put the field in iovec until we have all data */
+ }
+
+ log_trace("Received: %.*s (%s)", (int) n, line, sep ? "text" : "binary");
+
+ return 0; /* continue */
+ }
+
+ case IMPORTER_STATE_DATA_START:
+ assert(imp->data_size == 0);
+
+ r = get_data_size(imp);
+ // log_debug("get_data_size() -> %d", r);
+ if (r < 0)
+ return r;
+ if (r == 0) {
+ imp->state = IMPORTER_STATE_EOF;
+ return 0;
+ }
+
+ imp->state = imp->data_size > 0 ?
+ IMPORTER_STATE_DATA : IMPORTER_STATE_DATA_FINISH;
+
+ return 0; /* continue */
+
+ case IMPORTER_STATE_DATA: {
+ void *data;
+ char *field;
+
+ assert(imp->data_size > 0);
+
+ r = get_data_data(imp, &data);
+ // log_debug("get_data_data() -> %d", r);
+ if (r < 0)
+ return r;
+ if (r == 0) {
+ imp->state = IMPORTER_STATE_EOF;
+ return 0;
+ }
+
+ assert(data);
+
+ field = (char*) data - sizeof(uint64_t) - imp->field_len;
+ memmove(field + sizeof(uint64_t), field, imp->field_len);
+
+ r = iovw_put(&imp->iovw, field + sizeof(uint64_t), imp->field_len + imp->data_size);
+ if (r < 0)
+ return r;
+
+ imp->state = IMPORTER_STATE_DATA_FINISH;
+
+ return 0; /* continue */
+ }
+
+ case IMPORTER_STATE_DATA_FINISH:
+ r = get_data_newline(imp);
+ // log_debug("get_data_newline() -> %d", r);
+ if (r < 0)
+ return r;
+ if (r == 0) {
+ imp->state = IMPORTER_STATE_EOF;
+ return 0;
+ }
+
+ imp->data_size = 0;
+ imp->state = IMPORTER_STATE_LINE;
+
+ return 0; /* continue */
+ default:
+ assert_not_reached("wtf?");
+ }
+}
+
+int journal_importer_push_data(JournalImporter *imp, const char *data, size_t size) {
+ assert(imp);
+ assert(imp->state != IMPORTER_STATE_EOF);
+
+ if (!realloc_buffer(imp, imp->filled + size)) {
+ log_error("Failed to store received data of size %zu "
+ "(in addition to existing %zu bytes with %zu filled): %s",
+ size, imp->size, imp->filled, strerror(ENOMEM));
+ return -ENOMEM;
+ }
+
+ memcpy(imp->buf + imp->filled, data, size);
+ imp->filled += size;
+
+ return 0;
+}
+
+void journal_importer_drop_iovw(JournalImporter *imp) {
+ size_t remain, target;
+
+ /* This function drops processed data that along with the iovw that points at it */
+
+ iovw_free_contents(&imp->iovw);
+
+ /* possibly reset buffer position */
+ remain = imp->filled - imp->offset;
+
+ if (remain == 0) /* no brainer */
+ imp->offset = imp->scanned = imp->filled = 0;
+ else if (imp->offset > imp->size - imp->filled &&
+ imp->offset > remain) {
+ memcpy(imp->buf, imp->buf + imp->offset, remain);
+ imp->offset = imp->scanned = 0;
+ imp->filled = remain;
+ }
+
+ target = imp->size;
+ while (target > 16 * LINE_CHUNK && imp->filled < target / 2)
+ target /= 2;
+ if (target < imp->size) {
+ char *tmp;
+
+ tmp = realloc(imp->buf, target);
+ if (!tmp)
+ log_warning("Failed to reallocate buffer to (smaller) size %zu",
+ target);
+ else {
+ log_debug("Reallocated buffer from %zu to %zu bytes",
+ imp->size, target);
+ imp->buf = tmp;
+ imp->size = target;
+ }
+ }
+}
+
+bool journal_importer_eof(const JournalImporter *imp) {
+ return imp->state == IMPORTER_STATE_EOF;
+}
diff --git a/src/basic/journal-importer.h b/src/basic/journal-importer.h
new file mode 100644
index 0000000000..b3e308dd6d
--- /dev/null
+++ b/src/basic/journal-importer.h
@@ -0,0 +1,70 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Zbigniew Jędrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <sys/uio.h>
+
+#include "time-util.h"
+
+/* Make sure not to make this smaller than the maximum coredump size.
+ * See COREDUMP_MAX in coredump.c */
+#define ENTRY_SIZE_MAX (1024*1024*770u)
+#define DATA_SIZE_MAX (1024*1024*768u)
+#define LINE_CHUNK 8*1024u
+
+struct iovec_wrapper {
+ struct iovec *iovec;
+ size_t size_bytes;
+ size_t count;
+};
+
+size_t iovw_size(struct iovec_wrapper *iovw);
+
+typedef struct JournalImporter {
+ int fd;
+ bool passive_fd;
+ char *name;
+
+ char *buf;
+ size_t size; /* total size of the buffer */
+ size_t offset; /* offset to the beginning of live data in the buffer */
+ size_t scanned; /* number of bytes since the beginning of data without a newline */
+ size_t filled; /* total number of bytes in the buffer */
+
+ size_t field_len; /* used for binary fields: the field name length */
+ size_t data_size; /* and the size of the binary data chunk being processed */
+
+ struct iovec_wrapper iovw;
+
+ int state;
+ dual_timestamp ts;
+} JournalImporter;
+
+void journal_importer_cleanup(JournalImporter *);
+int journal_importer_process_data(JournalImporter *);
+int journal_importer_push_data(JournalImporter *, const char *data, size_t size);
+void journal_importer_drop_iovw(JournalImporter *);
+bool journal_importer_eof(const JournalImporter *);
+
+static inline size_t journal_importer_bytes_remaining(const JournalImporter *imp) {
+ return imp->filled;
+}
diff --git a/src/basic/khash.c b/src/basic/khash.c
new file mode 100644
index 0000000000..84648dc1c9
--- /dev/null
+++ b/src/basic/khash.c
@@ -0,0 +1,275 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <linux/if_alg.h>
+#include <stdbool.h>
+#include <sys/socket.h>
+
+#include "alloc-util.h"
+#include "fd-util.h"
+#include "hexdecoct.h"
+#include "khash.h"
+#include "macro.h"
+#include "missing.h"
+#include "string-util.h"
+#include "util.h"
+
+/* On current kernels the maximum digest (according to "grep digestsize /proc/crypto | sort -u") is actually 32, but
+ * let's add some extra room, the few wasted bytes don't really matter... */
+#define LONGEST_DIGEST 128
+
+struct khash {
+ int fd;
+ char *algorithm;
+ uint8_t digest[LONGEST_DIGEST+1];
+ size_t digest_size;
+ bool digest_valid;
+};
+
+int khash_new_with_key(khash **ret, const char *algorithm, const void *key, size_t key_size) {
+ union {
+ struct sockaddr sa;
+ struct sockaddr_alg alg;
+ } sa = {
+ .alg.salg_family = AF_ALG,
+ .alg.salg_type = "hash",
+ };
+
+ _cleanup_(khash_unrefp) khash *h = NULL;
+ _cleanup_close_ int fd = -1;
+ ssize_t n;
+
+ assert(ret);
+ assert(key || key_size == 0);
+
+ /* Filter out an empty algorithm early, as we do not support an algorithm by that name. */
+ if (isempty(algorithm))
+ return -EINVAL;
+
+ /* Overly long hash algorithm names we definitely do not support */
+ if (strlen(algorithm) >= sizeof(sa.alg.salg_name))
+ return -EOPNOTSUPP;
+
+ fd = socket(AF_ALG, SOCK_SEQPACKET|SOCK_CLOEXEC, 0);
+ if (fd < 0)
+ return -errno;
+
+ strcpy((char*) sa.alg.salg_name, algorithm);
+ if (bind(fd, &sa.sa, sizeof(sa)) < 0) {
+ if (errno == ENOENT)
+ return -EOPNOTSUPP;
+ return -errno;
+ }
+
+ if (key) {
+ if (setsockopt(fd, SOL_ALG, ALG_SET_KEY, key, key_size) < 0)
+ return -errno;
+ }
+
+ h = new0(khash, 1);
+ if (!h)
+ return -ENOMEM;
+
+ h->fd = accept4(fd, NULL, 0, SOCK_CLOEXEC);
+ if (h->fd < 0)
+ return -errno;
+
+ h->algorithm = strdup(algorithm);
+ if (!h->algorithm)
+ return -ENOMEM;
+
+ /* Temporary fix for rc kernel bug: https://bugzilla.redhat.com/show_bug.cgi?id=1395896 */
+ (void) send(h->fd, NULL, 0, 0);
+
+ /* Figure out the digest size */
+ n = recv(h->fd, h->digest, sizeof(h->digest), 0);
+ if (n < 0)
+ return -errno;
+ if (n >= LONGEST_DIGEST) /* longer than what we expected? If so, we don't support this */
+ return -EOPNOTSUPP;
+
+ h->digest_size = (size_t) n;
+ h->digest_valid = true;
+
+ /* Temporary fix for rc kernel bug: https://bugzilla.redhat.com/show_bug.cgi?id=1395896 */
+ (void) send(h->fd, NULL, 0, 0);
+
+ *ret = h;
+ h = NULL;
+
+ return 0;
+}
+
+int khash_new(khash **ret, const char *algorithm) {
+ return khash_new_with_key(ret, algorithm, NULL, 0);
+}
+
+khash* khash_unref(khash *h) {
+ if (!h)
+ return NULL;
+
+ safe_close(h->fd);
+ free(h->algorithm);
+ free(h);
+
+ return NULL;
+}
+
+int khash_dup(khash *h, khash **ret) {
+ _cleanup_(khash_unrefp) khash *copy = NULL;
+
+ assert(h);
+ assert(ret);
+
+ copy = newdup(khash, h, 1);
+ if (!copy)
+ return -ENOMEM;
+
+ copy->fd = -1;
+ copy->algorithm = strdup(h->algorithm);
+ if (!copy->algorithm)
+ return -ENOMEM;
+
+ copy->fd = accept4(h->fd, NULL, 0, SOCK_CLOEXEC);
+ if (copy->fd < 0)
+ return -errno;
+
+ *ret = copy;
+ copy = NULL;
+
+ return 0;
+}
+
+const char *khash_get_algorithm(khash *h) {
+ assert(h);
+
+ return h->algorithm;
+}
+
+size_t khash_get_size(khash *h) {
+ assert(h);
+
+ return h->digest_size;
+}
+
+int khash_reset(khash *h) {
+ ssize_t n;
+
+ assert(h);
+
+ n = send(h->fd, NULL, 0, 0);
+ if (n < 0)
+ return -errno;
+
+ h->digest_valid = false;
+
+ return 0;
+}
+
+int khash_put(khash *h, const void *buffer, size_t size) {
+ ssize_t n;
+
+ assert(h);
+ assert(buffer || size == 0);
+
+ if (size <= 0)
+ return 0;
+
+ n = send(h->fd, buffer, size, MSG_MORE);
+ if (n < 0)
+ return -errno;
+
+ h->digest_valid = false;
+
+ return 0;
+}
+
+int khash_put_iovec(khash *h, const struct iovec *iovec, size_t n) {
+ struct msghdr mh = {
+ mh.msg_iov = (struct iovec*) iovec,
+ mh.msg_iovlen = n,
+ };
+ ssize_t k;
+
+ assert(h);
+ assert(iovec || n == 0);
+
+ if (n <= 0)
+ return 0;
+
+ k = sendmsg(h->fd, &mh, MSG_MORE);
+ if (k < 0)
+ return -errno;
+
+ h->digest_valid = false;
+
+ return 0;
+}
+
+static int retrieve_digest(khash *h) {
+ ssize_t n;
+
+ assert(h);
+
+ if (h->digest_valid)
+ return 0;
+
+ n = recv(h->fd, h->digest, h->digest_size, 0);
+ if (n < 0)
+ return n;
+ if ((size_t) n != h->digest_size) /* digest size changed? */
+ return -EIO;
+
+ h->digest_valid = true;
+
+ return 0;
+}
+
+int khash_digest_data(khash *h, const void **ret) {
+ int r;
+
+ assert(h);
+ assert(ret);
+
+ r = retrieve_digest(h);
+ if (r < 0)
+ return r;
+
+ *ret = h->digest;
+ return 0;
+}
+
+int khash_digest_string(khash *h, char **ret) {
+ int r;
+ char *p;
+
+ assert(h);
+ assert(ret);
+
+ r = retrieve_digest(h);
+ if (r < 0)
+ return r;
+
+ p = hexmem(h->digest, h->digest_size);
+ if (!p)
+ return -ENOMEM;
+
+ *ret = p;
+ return 0;
+}
diff --git a/src/basic/khash.h b/src/basic/khash.h
new file mode 100644
index 0000000000..410f3020e0
--- /dev/null
+++ b/src/basic/khash.h
@@ -0,0 +1,53 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+
+#include "macro.h"
+
+typedef struct khash khash;
+
+/* For plain hash functions. Hash functions commonly supported on today's kernels are: crc32c, crct10dif, crc32,
+ * sha224, sha256, sha512, sha384, sha1, md5, md4, sha3-224, sha3-256, sha3-384, sha3-512, and more. */
+int khash_new(khash **ret, const char *algorithm);
+
+/* For keyed hash functions. Hash functions commonly supported on today's kernels are: hmac(sha256), cmac(aes),
+ * cmac(des3_ede), hmac(sha3-512), hmac(sha3-384), hmac(sha3-256), hmac(sha3-224), hmac(rmd160), hmac(rmd128),
+ * hmac(sha224), hmac(sha512), hmac(sha384), hmac(sha1), hmac(md5), and more. */
+int khash_new_with_key(khash **ret, const char *algorithm, const void *key, size_t key_size);
+
+int khash_dup(khash *h, khash **ret);
+khash* khash_unref(khash *h);
+
+const char *khash_get_algorithm(khash *h);
+size_t khash_get_size(khash *h);
+
+int khash_reset(khash *h);
+
+int khash_put(khash *h, const void *buffer, size_t size);
+int khash_put_iovec(khash *h, const struct iovec *iovec, size_t n);
+
+int khash_digest_data(khash *h, const void **ret);
+int khash_digest_string(khash *h, char **ret);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(khash*, khash_unref);
diff --git a/src/basic/log.c b/src/basic/log.c
index 4919d175da..36efc9ac7d 100644
--- a/src/basic/log.c
+++ b/src/basic/log.c
@@ -37,7 +37,7 @@
#include "alloc-util.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "io-util.h"
#include "log.h"
#include "macro.h"
@@ -72,6 +72,7 @@ static bool show_color = false;
static bool show_location = false;
static bool upgrade_syslog_to_journal = false;
+static bool always_reopen_console = false;
/* Akin to glibc's __abort_msg; which is private and we hence cannot
* use here. */
@@ -95,7 +96,7 @@ static int log_open_console(void) {
if (console_fd >= 0)
return 0;
- if (getpid() == 1) {
+ if (always_reopen_console) {
console_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
if (console_fd < 0)
return console_fd;
@@ -243,13 +244,13 @@ int log_open(void) {
return 0;
}
- if ((log_target != LOG_TARGET_AUTO && log_target != LOG_TARGET_SAFE) ||
+ if (!IN_SET(log_target, LOG_TARGET_AUTO, LOG_TARGET_SAFE) ||
getpid() == 1 ||
isatty(STDERR_FILENO) <= 0) {
- if (log_target == LOG_TARGET_AUTO ||
- log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
- log_target == LOG_TARGET_JOURNAL) {
+ if (IN_SET(log_target, LOG_TARGET_AUTO,
+ LOG_TARGET_JOURNAL_OR_KMSG,
+ LOG_TARGET_JOURNAL)) {
r = log_open_journal();
if (r >= 0) {
log_close_syslog();
@@ -258,8 +259,8 @@ int log_open(void) {
}
}
- if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
- log_target == LOG_TARGET_SYSLOG) {
+ if (IN_SET(log_target, LOG_TARGET_SYSLOG_OR_KMSG,
+ LOG_TARGET_SYSLOG)) {
r = log_open_syslog();
if (r >= 0) {
log_close_journal();
@@ -268,11 +269,11 @@ int log_open(void) {
}
}
- if (log_target == LOG_TARGET_AUTO ||
- log_target == LOG_TARGET_SAFE ||
- log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
- log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
- log_target == LOG_TARGET_KMSG) {
+ if (IN_SET(log_target, LOG_TARGET_AUTO,
+ LOG_TARGET_SAFE,
+ LOG_TARGET_JOURNAL_OR_KMSG,
+ LOG_TARGET_SYSLOG_OR_KMSG,
+ LOG_TARGET_KMSG)) {
r = log_open_kmsg();
if (r >= 0) {
log_close_journal();
@@ -500,7 +501,7 @@ static int log_do_header(
line ? "CODE_LINE=" : "",
line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
line ? "\n" : "",
- isempty(func) ? "" : "CODE_FUNCTION=",
+ isempty(func) ? "" : "CODE_FUNC=",
isempty(func) ? "" : func,
isempty(func) ? "" : "\n",
error ? "ERRNO=" : "",
@@ -588,9 +589,9 @@ static int log_dispatch(
if ((e = strpbrk(buffer, NEWLINE)))
*(e++) = 0;
- if (log_target == LOG_TARGET_AUTO ||
- log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
- log_target == LOG_TARGET_JOURNAL) {
+ if (IN_SET(log_target, LOG_TARGET_AUTO,
+ LOG_TARGET_JOURNAL_OR_KMSG,
+ LOG_TARGET_JOURNAL)) {
k = write_to_journal(level, error, file, line, func, object_field, object, extra_field, extra, buffer);
if (k < 0) {
@@ -600,8 +601,8 @@ static int log_dispatch(
}
}
- if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
- log_target == LOG_TARGET_SYSLOG) {
+ if (IN_SET(log_target, LOG_TARGET_SYSLOG_OR_KMSG,
+ LOG_TARGET_SYSLOG)) {
k = write_to_syslog(level, error, file, line, func, buffer);
if (k < 0) {
@@ -612,11 +613,11 @@ static int log_dispatch(
}
if (k <= 0 &&
- (log_target == LOG_TARGET_AUTO ||
- log_target == LOG_TARGET_SAFE ||
- log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
- log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
- log_target == LOG_TARGET_KMSG)) {
+ IN_SET(log_target, LOG_TARGET_AUTO,
+ LOG_TARGET_SAFE,
+ LOG_TARGET_SYSLOG_OR_KMSG,
+ LOG_TARGET_JOURNAL_OR_KMSG,
+ LOG_TARGET_KMSG)) {
k = write_to_kmsg(level, error, file, line, func, buffer);
if (k < 0) {
@@ -881,9 +882,9 @@ int log_struct_internal(
if ((level & LOG_FACMASK) == 0)
level = log_facility | LOG_PRI(level);
- if ((log_target == LOG_TARGET_AUTO ||
- log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
- log_target == LOG_TARGET_JOURNAL) &&
+ if (IN_SET(log_target, LOG_TARGET_AUTO,
+ LOG_TARGET_JOURNAL_OR_KMSG,
+ LOG_TARGET_JOURNAL) &&
journal_fd >= 0) {
char header[LINE_MAX];
struct iovec iovec[17] = {};
@@ -981,24 +982,30 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
if (streq(key, "debug") && !value)
log_set_max_level(LOG_DEBUG);
- else if (streq(key, "systemd.log_target") && value) {
+ else if (proc_cmdline_key_streq(key, "systemd.log_target")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
if (log_set_target_from_string(value) < 0)
log_warning("Failed to parse log target '%s'. Ignoring.", value);
- } else if (streq(key, "systemd.log_level") && value) {
+ } else if (proc_cmdline_key_streq(key, "systemd.log_level")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
if (log_set_max_level_from_string(value) < 0)
log_warning("Failed to parse log level '%s'. Ignoring.", value);
- } else if (streq(key, "systemd.log_color") && value) {
+ } else if (proc_cmdline_key_streq(key, "systemd.log_color")) {
- if (log_show_color_from_string(value) < 0)
+ if (log_show_color_from_string(value ?: "1") < 0)
log_warning("Failed to parse log color setting '%s'. Ignoring.", value);
- } else if (streq(key, "systemd.log_location") && value) {
+ } else if (proc_cmdline_key_streq(key, "systemd.log_location")) {
- if (log_show_location_from_string(value) < 0)
+ if (log_show_location_from_string(value ?: "1") < 0)
log_warning("Failed to parse log location setting '%s'. Ignoring.", value);
}
@@ -1009,10 +1016,9 @@ void log_parse_environment(void) {
const char *e;
if (get_ctty_devnr(0, NULL) < 0)
- /* Only try to read the command line in daemons.
- We assume that anything that has a controlling
- tty is user stuff. */
- (void) parse_proc_cmdline(parse_proc_cmdline_item, NULL, true);
+ /* Only try to read the command line in daemons. We assume that anything that has a controlling tty is
+ user stuff. */
+ (void) proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
e = secure_getenv("SYSTEMD_LOG_TARGET");
if (e && log_set_target_from_string(e) < 0)
@@ -1078,8 +1084,8 @@ int log_show_location_from_string(const char *e) {
}
bool log_on_console(void) {
- if (log_target == LOG_TARGET_CONSOLE ||
- log_target == LOG_TARGET_CONSOLE_PREFIXED)
+ if (IN_SET(log_target, LOG_TARGET_CONSOLE,
+ LOG_TARGET_CONSOLE_PREFIXED))
return true;
return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
@@ -1134,8 +1140,8 @@ int log_syntax_internal(
PROTECT_ERRNO;
char buffer[LINE_MAX];
- int r;
va_list ap;
+ const char *unit_fmt = NULL;
if (error < 0)
error = -error;
@@ -1154,24 +1160,19 @@ int log_syntax_internal(
va_end(ap);
if (unit)
- r = log_struct_internal(
- level, error,
- file, line, func,
- getpid() == 1 ? "UNIT=%s" : "USER_UNIT=%s", unit,
- LOG_MESSAGE_ID(SD_MESSAGE_INVALID_CONFIGURATION),
- "CONFIG_FILE=%s", config_file,
- "CONFIG_LINE=%u", config_line,
- LOG_MESSAGE("[%s:%u] %s", config_file, config_line, buffer),
- NULL);
- else
- r = log_struct_internal(
- level, error,
- file, line, func,
- LOG_MESSAGE_ID(SD_MESSAGE_INVALID_CONFIGURATION),
- "CONFIG_FILE=%s", config_file,
- "CONFIG_LINE=%u", config_line,
- LOG_MESSAGE("[%s:%u] %s", config_file, config_line, buffer),
- NULL);
+ unit_fmt = getpid() == 1 ? "UNIT=%s" : "USER_UNIT=%s";
+
+ return log_struct_internal(
+ level, error,
+ file, line, func,
+ "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
+ "CONFIG_FILE=%s", config_file,
+ "CONFIG_LINE=%u", config_line,
+ LOG_MESSAGE("%s:%u: %s", config_file, config_line, buffer),
+ unit_fmt, unit,
+ NULL);
+}
- return r;
+void log_set_always_reopen_console(bool b) {
+ always_reopen_console = b;
}
diff --git a/src/basic/log.h b/src/basic/log.h
index 2afee20bb5..72714e02e5 100644
--- a/src/basic/log.h
+++ b/src/basic/log.h
@@ -214,13 +214,13 @@ bool log_on_console(void) _pure_;
const char *log_target_to_string(LogTarget target) _const_;
LogTarget log_target_from_string(const char *s) _pure_;
-/* Helpers to prepare various fields for structured logging */
+/* Helper to prepare various field for structured logging */
#define LOG_MESSAGE(fmt, ...) "MESSAGE=" fmt, ##__VA_ARGS__
-#define LOG_MESSAGE_ID(x) "MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(x)
void log_received_signal(int level, const struct signalfd_siginfo *si);
void log_set_upgrade_syslog_to_journal(bool b);
+void log_set_always_reopen_console(bool b);
int log_syntax_internal(
const char *unit,
diff --git a/src/basic/missing.h b/src/basic/missing.h
index 4c013be608..b797899a61 100644
--- a/src/basic/missing.h
+++ b/src/basic/missing.h
@@ -34,6 +34,7 @@
#include <net/ethernet.h>
#include <stdlib.h>
#include <sys/resource.h>
+#include <sys/socket.h>
#include <sys/syscall.h>
#include <uchar.h>
#include <unistd.h>
@@ -50,6 +51,23 @@
#include <linux/btrfs.h>
#endif
+#ifdef HAVE_LINUX_VM_SOCKETS_H
+#include <linux/vm_sockets.h>
+#else
+#define VMADDR_CID_ANY -1U
+struct sockaddr_vm {
+ unsigned short svm_family;
+ unsigned short svm_reserved1;
+ unsigned int svm_port;
+ unsigned int svm_cid;
+ unsigned char svm_zero[sizeof(struct sockaddr) -
+ sizeof(unsigned short) -
+ sizeof(unsigned short) -
+ sizeof(unsigned int) -
+ sizeof(unsigned int)];
+};
+#endif /* !HAVE_LINUX_VM_SOCKETS_H */
+
#include "macro.h"
#ifndef RLIMIT_RTTIME
@@ -143,6 +161,10 @@
#define GRND_RANDOM 0x0002
#endif
+#ifndef FS_NOCOW_FL
+#define FS_NOCOW_FL 0x00800000
+#endif
+
#ifndef BTRFS_IOCTL_MAGIC
#define BTRFS_IOCTL_MAGIC 0x94
#endif
@@ -1076,6 +1098,41 @@ typedef int32_t key_serial_t;
#define IFA_F_MCAUTOJOIN 0x400
#endif
+#ifndef HAVE_STRUCT_ETHTOOL_LINK_SETTINGS
+
+#define ETHTOOL_GLINKSETTINGS 0x0000004c /* Get ethtool_link_settings */
+#define ETHTOOL_SLINKSETTINGS 0x0000004d /* Set ethtool_link_settings */
+
+struct ethtool_link_settings {
+ __u32 cmd;
+ __u32 speed;
+ __u8 duplex;
+ __u8 port;
+ __u8 phy_address;
+ __u8 autoneg;
+ __u8 mdio_support;
+ __u8 eth_tp_mdix;
+ __u8 eth_tp_mdix_ctrl;
+ __s8 link_mode_masks_nwords;
+ __u32 reserved[8];
+ __u32 link_mode_masks[0];
+ /* layout of link_mode_masks fields:
+ * __u32 map_supported[link_mode_masks_nwords];
+ * __u32 map_advertising[link_mode_masks_nwords];
+ * __u32 map_lp_advertising[link_mode_masks_nwords];
+ */
+};
+
+#endif
+
+#endif
+
+#ifndef SOL_ALG
+#define SOL_ALG 279
+#endif
+
+#ifndef AF_VSOCK
+#define AF_VSOCK 40
#endif
#include "missing_syscall.h"
diff --git a/src/basic/missing_syscall.h b/src/basic/missing_syscall.h
index e6fd67cb9d..9fc4156564 100644
--- a/src/basic/missing_syscall.h
+++ b/src/basic/missing_syscall.h
@@ -194,6 +194,8 @@ static inline pid_t raw_getpid(void) {
# define __NR_renameat2 316
# elif defined __arm__
# define __NR_renameat2 382
+# elif defined __aarch64__
+# define __NR_renameat2 276
# elif defined _MIPS_SIM
# if _MIPS_SIM == _MIPS_SIM_ABI32
# define __NR_renameat2 4351
diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c
index c8f8022578..a8fd63fb45 100644
--- a/src/basic/mount-util.c
+++ b/src/basic/mount-util.c
@@ -29,6 +29,7 @@
#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
+#include "fs-util.h"
#include "hashmap.h"
#include "mount-util.h"
#include "parse-util.h"
@@ -111,9 +112,10 @@ int fd_is_mount_point(int fd, const char *filename, int flags) {
r = name_to_handle_at(fd, filename, &h.handle, &mount_id, flags);
if (r < 0) {
- if (errno == ENOSYS)
- /* This kernel does not support name_to_handle_at()
- * fall back to simpler logic. */
+ if (IN_SET(errno, ENOSYS, EACCES, EPERM))
+ /* This kernel does not support name_to_handle_at() at all, or the syscall was blocked (maybe
+ * through seccomp, because we are running inside of a container?): fall back to simpler
+ * logic. */
goto fallback_fdinfo;
else if (errno == EOPNOTSUPP)
/* This kernel or file system does not support
@@ -162,7 +164,7 @@ int fd_is_mount_point(int fd, const char *filename, int flags) {
fallback_fdinfo:
r = fd_fdinfo_mnt_id(fd, filename, flags, &mount_id);
- if (IN_SET(r, -EOPNOTSUPP, -EACCES))
+ if (IN_SET(r, -EOPNOTSUPP, -EACCES, -EPERM))
goto fallback_fstat;
if (r < 0)
return r;
@@ -205,9 +207,10 @@ fallback_fstat:
}
/* flags can be AT_SYMLINK_FOLLOW or 0 */
-int path_is_mount_point(const char *t, int flags) {
- _cleanup_close_ int fd = -1;
+int path_is_mount_point(const char *t, const char *root, int flags) {
_cleanup_free_ char *canonical = NULL, *parent = NULL;
+ _cleanup_close_ int fd = -1;
+ int r;
assert(t);
@@ -219,9 +222,9 @@ int path_is_mount_point(const char *t, int flags) {
* /bin -> /usr/bin/ and /usr is a mount point, then the parent that we
* look at needs to be /usr, not /. */
if (flags & AT_SYMLINK_FOLLOW) {
- canonical = canonicalize_file_name(t);
- if (!canonical)
- return -errno;
+ r = chase_symlinks(t, root, 0, &canonical);
+ if (r < 0)
+ return r;
t = canonical;
}
@@ -473,7 +476,7 @@ int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) {
return r;
/* Deal with mount points that are obstructed by a later mount */
- r = path_is_mount_point(x, 0);
+ r = path_is_mount_point(x, NULL, 0);
if (r == -ENOENT || r == 0)
continue;
if (r < 0)
@@ -642,7 +645,7 @@ static char* mount_flags_to_string(long unsigned flags) {
FLAG(MS_I_VERSION),
FLAG(MS_STRICTATIME),
FLAG(MS_LAZYTIME),
- y, NULL);
+ y);
if (!x)
return NULL;
if (!y)
@@ -671,6 +674,9 @@ int mount_verbose(
else if ((flags & MS_BIND) && !type)
log_debug("Bind-mounting %s on %s (%s \"%s\")...",
what, where, strnull(fl), strempty(options));
+ else if (flags & MS_MOVE)
+ log_debug("Moving mount %s → %s (%s \"%s\")...",
+ what, where, strnull(fl), strempty(options));
else
log_debug("Mounting %s on %s (%s \"%s\")...",
strna(type), where, strnull(fl), strempty(options));
@@ -687,3 +693,35 @@ int umount_verbose(const char *what) {
return log_error_errno(errno, "Failed to unmount %s: %m", what);
return 0;
}
+
+const char *mount_propagation_flags_to_string(unsigned long flags) {
+
+ switch (flags & (MS_SHARED|MS_SLAVE|MS_PRIVATE)) {
+ case 0:
+ return "";
+ case MS_SHARED:
+ return "shared";
+ case MS_SLAVE:
+ return "slave";
+ case MS_PRIVATE:
+ return "private";
+ }
+
+ return NULL;
+}
+
+
+int mount_propagation_flags_from_string(const char *name, unsigned long *ret) {
+
+ if (isempty(name))
+ *ret = 0;
+ else if (streq(name, "shared"))
+ *ret = MS_SHARED;
+ else if (streq(name, "slave"))
+ *ret = MS_SLAVE;
+ else if (streq(name, "private"))
+ *ret = MS_PRIVATE;
+ else
+ return -EINVAL;
+ return 0;
+}
diff --git a/src/basic/mount-util.h b/src/basic/mount-util.h
index 4f305df19f..1615c94e9a 100644
--- a/src/basic/mount-util.h
+++ b/src/basic/mount-util.h
@@ -30,7 +30,7 @@
#include "missing.h"
int fd_is_mount_point(int fd, const char *filename, int flags);
-int path_is_mount_point(const char *path, int flags);
+int path_is_mount_point(const char *path, const char *root, int flags);
int repeat_unmount(const char *path, int flags);
@@ -61,3 +61,6 @@ int mount_verbose(
unsigned long flags,
const char *options);
int umount_verbose(const char *where);
+
+const char *mount_propagation_flags_to_string(unsigned long flags);
+int mount_propagation_flags_from_string(const char *name, unsigned long *ret);
diff --git a/src/basic/nss-util.h b/src/basic/nss-util.h
index e7844fff96..9d927a8227 100644
--- a/src/basic/nss-util.h
+++ b/src/basic/nss-util.h
@@ -27,6 +27,10 @@
#define NSS_SIGNALS_BLOCK SIGALRM,SIGVTALRM,SIGPIPE,SIGCHLD,SIGTSTP,SIGIO,SIGHUP,SIGUSR1,SIGUSR2,SIGPROF,SIGURG,SIGWINCH
+#ifndef DEPRECATED_RES_USE_INET6
+# define DEPRECATED_RES_USE_INET6 0x00002000
+#endif
+
#define NSS_GETHOSTBYNAME_PROTOTYPES(module) \
enum nss_status _nss_##module##_gethostbyname4_r( \
const char *name, \
@@ -92,7 +96,7 @@ enum nss_status _nss_##module##_gethostbyname_r( \
int *errnop, int *h_errnop) { \
enum nss_status ret = NSS_STATUS_NOTFOUND; \
\
- if (_res.options & RES_USE_INET6) \
+ if (_res.options & DEPRECATED_RES_USE_INET6) \
ret = _nss_##module##_gethostbyname3_r( \
name, \
AF_INET6, \
diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c
index a0eb458052..d86700736d 100644
--- a/src/basic/parse-util.c
+++ b/src/basic/parse-util.c
@@ -573,3 +573,19 @@ int parse_nice(const char *p, int *ret) {
*ret = n;
return 0;
}
+
+int parse_ip_port(const char *s, uint16_t *ret) {
+ uint16_t l;
+ int r;
+
+ r = safe_atou16(s, &l);
+ if (r < 0)
+ return r;
+
+ if (l == 0)
+ return -EINVAL;
+
+ *ret = (uint16_t) l;
+
+ return 0;
+}
diff --git a/src/basic/parse-util.h b/src/basic/parse-util.h
index 461e1cd4d8..4d132f0de5 100644
--- a/src/basic/parse-util.h
+++ b/src/basic/parse-util.h
@@ -110,3 +110,5 @@ int parse_percent_unbounded(const char *p);
int parse_percent(const char *p);
int parse_nice(const char *p, int *ret);
+
+int parse_ip_port(const char *s, uint16_t *ret);
diff --git a/src/basic/path-util.c b/src/basic/path-util.c
index fd38f51c4c..1313a52c9c 100644
--- a/src/basic/path-util.c
+++ b/src/basic/path-util.c
@@ -83,7 +83,7 @@ char *path_make_absolute(const char *p, const char *prefix) {
if (path_is_absolute(p) || !prefix)
return strdup(p);
- return strjoin(prefix, "/", p, NULL);
+ return strjoin(prefix, "/", p);
}
int path_make_absolute_cwd(const char *p, char **ret) {
@@ -104,7 +104,7 @@ int path_make_absolute_cwd(const char *p, char **ret) {
if (!cwd)
return negative_errno();
- c = strjoin(cwd, "/", p, NULL);
+ c = strjoin(cwd, "/", p);
}
if (!c)
return -ENOMEM;
@@ -220,10 +220,11 @@ int path_strv_make_absolute_cwd(char **l) {
return 0;
}
-char **path_strv_resolve(char **l, const char *prefix) {
+char **path_strv_resolve(char **l, const char *root) {
char **s;
unsigned k = 0;
bool enomem = false;
+ int r;
if (strv_isempty(l))
return l;
@@ -233,17 +234,17 @@ char **path_strv_resolve(char **l, const char *prefix) {
* changes on failure. */
STRV_FOREACH(s, l) {
- char *t, *u;
_cleanup_free_ char *orig = NULL;
+ char *t, *u;
if (!path_is_absolute(*s)) {
free(*s);
continue;
}
- if (prefix) {
+ if (root) {
orig = *s;
- t = strappend(prefix, orig);
+ t = prefix_root(root, orig);
if (!t) {
enomem = true;
continue;
@@ -251,28 +252,26 @@ char **path_strv_resolve(char **l, const char *prefix) {
} else
t = *s;
- errno = 0;
- u = canonicalize_file_name(t);
- if (!u) {
- if (errno == ENOENT) {
- if (prefix) {
- u = orig;
- orig = NULL;
- free(t);
- } else
- u = t;
- } else {
+ r = chase_symlinks(t, root, 0, &u);
+ if (r == -ENOENT) {
+ if (root) {
+ u = orig;
+ orig = NULL;
free(t);
- if (errno == ENOMEM || errno == 0)
- enomem = true;
+ } else
+ u = t;
+ } else if (r < 0) {
+ free(t);
- continue;
- }
- } else if (prefix) {
+ if (r == -ENOMEM)
+ enomem = true;
+
+ continue;
+ } else if (root) {
char *x;
free(t);
- x = path_startswith(u, prefix);
+ x = path_startswith(u, root);
if (x) {
/* restore the slash if it was lost */
if (!startswith(x, "/"))
@@ -304,12 +303,12 @@ char **path_strv_resolve(char **l, const char *prefix) {
return l;
}
-char **path_strv_resolve_uniq(char **l, const char *prefix) {
+char **path_strv_resolve_uniq(char **l, const char *root) {
if (strv_isempty(l))
return l;
- if (!path_strv_resolve(l, prefix))
+ if (!path_strv_resolve(l, root))
return NULL;
return strv_uniq(l);
@@ -454,13 +453,11 @@ char* path_join(const char *root, const char *path, const char *rest) {
return strjoin(root, endswith(root, "/") ? "" : "/",
path[0] == '/' ? path+1 : path,
rest ? (endswith(path, "/") ? "" : "/") : NULL,
- rest && rest[0] == '/' ? rest+1 : rest,
- NULL);
+ rest && rest[0] == '/' ? rest+1 : rest);
else
return strjoin(path,
rest ? (endswith(path, "/") ? "" : "/") : NULL,
- rest && rest[0] == '/' ? rest+1 : rest,
- NULL);
+ rest && rest[0] == '/' ? rest+1 : rest);
}
int find_binary(const char *name, char **ret) {
@@ -504,7 +501,7 @@ int find_binary(const char *name, char **ret) {
if (!path_is_absolute(element))
continue;
- j = strjoin(element, "/", name, NULL);
+ j = strjoin(element, "/", name);
if (!j)
return -ENOMEM;
@@ -702,10 +699,7 @@ bool filename_is_valid(const char *p) {
if (isempty(p))
return false;
- if (streq(p, "."))
- return false;
-
- if (streq(p, ".."))
+ if (dot_or_dot_dot(p))
return false;
e = strchrnul(p, '/');
@@ -723,14 +717,17 @@ bool path_is_safe(const char *p) {
if (isempty(p))
return false;
- if (streq(p, "..") || startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../"))
+ if (dot_or_dot_dot(p))
+ return false;
+
+ if (startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../"))
return false;
if (strlen(p)+1 > PATH_MAX)
return false;
/* The following two checks are not really dangerous, but hey, they still are confusing */
- if (streq(p, ".") || startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
+ if (startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
return false;
if (strstr(p, "//"))
@@ -895,3 +892,16 @@ int systemd_installation_has_version(const char *root, unsigned minimal_version)
return false;
}
+
+bool dot_or_dot_dot(const char *path) {
+ if (!path)
+ return false;
+ if (path[0] != '.')
+ return false;
+ if (path[1] == 0)
+ return true;
+ if (path[1] != '.')
+ return false;
+
+ return path[2] == 0;
+}
diff --git a/src/basic/path-util.h b/src/basic/path-util.h
index 66545f52d9..35aef3adc8 100644
--- a/src/basic/path-util.h
+++ b/src/basic/path-util.h
@@ -24,6 +24,7 @@
#include <stddef.h>
#include "macro.h"
+#include "string-util.h"
#include "time-util.h"
#define DEFAULT_PATH_NORMAL "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"
@@ -65,9 +66,21 @@ static inline bool path_equal_ptr(const char *a, const char *b) {
_found; \
})
+#define PATH_STARTSWITH_SET(p, ...) \
+ ({ \
+ char **s; \
+ bool _found = false; \
+ STRV_FOREACH(s, STRV_MAKE(__VA_ARGS__)) \
+ if (path_startswith(p, *s)) { \
+ _found = true; \
+ break; \
+ } \
+ _found; \
+ })
+
int path_strv_make_absolute_cwd(char **l);
-char** path_strv_resolve(char **l, const char *prefix);
-char** path_strv_resolve_uniq(char **l, const char *prefix);
+char** path_strv_resolve(char **l, const char *root);
+char** path_strv_resolve_uniq(char **l, const char *root);
int find_binary(const char *name, char **filename);
@@ -128,3 +141,5 @@ bool is_device_path(const char *path);
bool is_deviceallow_pattern(const char *path);
int systemd_installation_has_version(const char *root, unsigned minimal_version);
+
+bool dot_or_dot_dot(const char *path);
diff --git a/src/basic/proc-cmdline.c b/src/basic/proc-cmdline.c
index 8297a222b7..8592a428d5 100644
--- a/src/basic/proc-cmdline.c
+++ b/src/basic/proc-cmdline.c
@@ -34,17 +34,30 @@
#include "virt.h"
int proc_cmdline(char **ret) {
+ const char *e;
assert(ret);
+ /* For testing purposes it is sometimes useful to be able to override what we consider /proc/cmdline to be */
+ e = secure_getenv("SYSTEMD_PROC_CMDLINE");
+ if (e) {
+ char *m;
+
+ m = strdup(e);
+ if (!m)
+ return -ENOMEM;
+
+ *ret = m;
+ return 0;
+ }
+
if (detect_container() > 0)
return get_process_cmdline(1, 0, false, ret);
else
return read_one_line_file("/proc/cmdline", ret);
}
-int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value, void *data),
- void *data,
- bool strip_prefix) {
+int proc_cmdline_parse(proc_cmdline_parse_t parse_item, void *data, unsigned flags) {
+
_cleanup_free_ char *line = NULL;
const char *p;
int r;
@@ -58,7 +71,7 @@ int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value, voi
p = line;
for (;;) {
_cleanup_free_ char *word = NULL;
- char *value = NULL, *unprefixed;
+ char *value, *key, *q;
r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
if (r < 0)
@@ -66,17 +79,23 @@ int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value, voi
if (r == 0)
break;
- /* Filter out arguments that are intended only for the
- * initrd */
- unprefixed = startswith(word, "rd.");
- if (unprefixed && !in_initrd())
- continue;
+ key = word;
+
+ /* Filter out arguments that are intended only for the initrd */
+ q = startswith(word, "rd.");
+ if (q) {
+ if (!in_initrd())
+ continue;
+
+ if (flags & PROC_CMDLINE_STRIP_RD_PREFIX)
+ key = q;
+ }
- value = strchr(word, '=');
+ value = strchr(key, '=');
if (value)
*(value++) = 0;
- r = parse_item(strip_prefix && unprefixed ? unprefixed : word, value, data);
+ r = parse_item(key, value, data);
if (r < 0)
return r;
}
@@ -84,13 +103,64 @@ int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value, voi
return 0;
}
-int get_proc_cmdline_key(const char *key, char **value) {
+static bool relaxed_equal_char(char a, char b) {
+
+ return a == b ||
+ (a == '_' && b == '-') ||
+ (a == '-' && b == '_');
+}
+
+char *proc_cmdline_key_startswith(const char *s, const char *prefix) {
+
+ assert(s);
+ assert(prefix);
+
+ /* Much like startswith(), but considers "-" and "_" the same */
+
+ for (; *prefix != 0; s++, prefix++)
+ if (!relaxed_equal_char(*s, *prefix))
+ return NULL;
+
+ return (char*) s;
+}
+
+bool proc_cmdline_key_streq(const char *x, const char *y) {
+ assert(x);
+ assert(y);
+
+ /* Much like streq(), but considers "-" and "_" the same */
+
+ for (; *x != 0 || *y != 0; x++, y++)
+ if (!relaxed_equal_char(*x, *y))
+ return false;
+
+ return true;
+}
+
+int proc_cmdline_get_key(const char *key, unsigned flags, char **value) {
_cleanup_free_ char *line = NULL, *ret = NULL;
bool found = false;
const char *p;
int r;
- assert(key);
+ /* Looks for a specific key on the kernel command line. Supports two modes:
+ *
+ * a) The "value" parameter is used. In this case a parameter beginning with the "key" string followed by "="
+ * is searched, and the value following this is returned in "value".
+ *
+ * b) as above, but the PROC_CMDLINE_VALUE_OPTIONAL flag is set. In this case if the key is found as a
+ * separate word (i.e. not followed by "=" but instead by whitespace or the end of the command line), then
+ * this is also accepted, and "value" is returned as NULL.
+ *
+ * c) The "value" parameter is NULL. In this case a search for the exact "key" parameter is performed.
+ *
+ * In all three cases, > 0 is returned if the key is found, 0 if not. */
+
+ if (isempty(key))
+ return -EINVAL;
+
+ if ((flags & PROC_CMDLINE_VALUE_OPTIONAL) && !value)
+ return -EINVAL;
r = proc_cmdline(&line);
if (r < 0)
@@ -107,21 +177,26 @@ int get_proc_cmdline_key(const char *key, char **value) {
if (r == 0)
break;
- /* Filter out arguments that are intended only for the
- * initrd */
+ /* Automatically filter out arguments that are intended only for the initrd, if we are not in the
+ * initrd. */
if (!in_initrd() && startswith(word, "rd."))
continue;
if (value) {
- e = startswith(word, key);
+ e = proc_cmdline_key_startswith(word, key);
if (!e)
continue;
- r = free_and_strdup(&ret, e);
- if (r < 0)
- return r;
+ if (*e == '=') {
+ r = free_and_strdup(&ret, e+1);
+ if (r < 0)
+ return r;
+
+ found = true;
+
+ } else if (*e == 0 && (flags & PROC_CMDLINE_VALUE_OPTIONAL))
+ found = true;
- found = true;
} else {
if (streq(word, key))
found = true;
@@ -134,20 +209,42 @@ int get_proc_cmdline_key(const char *key, char **value) {
}
return found;
+}
+
+int proc_cmdline_get_bool(const char *key, bool *ret) {
+ _cleanup_free_ char *v = NULL;
+ int r;
+
+ assert(ret);
+
+ r = proc_cmdline_get_key(key, PROC_CMDLINE_VALUE_OPTIONAL, &v);
+ if (r < 0)
+ return r;
+ if (r == 0) {
+ *ret = false;
+ return 0;
+ }
+
+ if (v) { /* parameter passed */
+ r = parse_boolean(v);
+ if (r < 0)
+ return r;
+ *ret = r;
+ } else /* no parameter passed */
+ *ret = true;
+ return 1;
}
int shall_restore_state(void) {
- _cleanup_free_ char *value = NULL;
+ bool ret;
int r;
- r = get_proc_cmdline_key("systemd.restore_state=", &value);
+ r = proc_cmdline_get_bool("systemd.restore_state", &ret);
if (r < 0)
return r;
- if (r == 0)
- return true;
- return parse_boolean(value);
+ return r > 0 ? ret : true;
}
static const char * const rlmap[] = {
diff --git a/src/basic/proc-cmdline.h b/src/basic/proc-cmdline.h
index 6d6ee95c11..ebfed355e9 100644
--- a/src/basic/proc-cmdline.h
+++ b/src/basic/proc-cmdline.h
@@ -19,11 +19,36 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <stdbool.h>
+
+#include "log.h"
+
+enum {
+ PROC_CMDLINE_STRIP_RD_PREFIX = 1,
+ PROC_CMDLINE_VALUE_OPTIONAL = 2,
+};
+
+typedef int (*proc_cmdline_parse_t)(const char *key, const char *value, void *data);
+
int proc_cmdline(char **ret);
-int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value, void *data),
- void *data,
- bool strip_prefix);
-int get_proc_cmdline_key(const char *parameter, char **value);
+
+int proc_cmdline_parse(const proc_cmdline_parse_t parse, void *userdata, unsigned flags);
+
+int proc_cmdline_get_key(const char *parameter, unsigned flags, char **value);
+int proc_cmdline_get_bool(const char *key, bool *ret);
+
+char *proc_cmdline_key_startswith(const char *s, const char *prefix);
+bool proc_cmdline_key_streq(const char *x, const char *y);
int shall_restore_state(void);
const char* runlevel_to_target(const char *rl);
+
+/* A little helper call, to be used in proc_cmdline_parse_t callbacks */
+static inline bool proc_cmdline_value_missing(const char *key, const char *value) {
+ if (!value) {
+ log_warning("Missing argument for %s= kernel command line switch, ignoring.", key);
+ return true;
+ }
+
+ return false;
+}
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index 54b644ad56..0df3fed640 100644
--- a/src/basic/process-util.c
+++ b/src/basic/process-util.c
@@ -27,6 +27,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/mman.h>
#include <sys/personality.h>
#include <sys/prctl.h>
#include <sys/types.h>
@@ -103,7 +104,7 @@ int get_process_comm(pid_t pid, char **name) {
int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
_cleanup_fclose_ FILE *f = NULL;
bool space = false;
- char *r = NULL, *k;
+ char *k, *ans = NULL;
const char *p;
int c;
@@ -117,7 +118,7 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
* command line that resolves to the empty string will return the "comm" name of the process instead.
*
* Returns -ESRCH if the process doesn't exist, and -ENOENT if the process has no command line (and
- * comm_fallback is false). */
+ * comm_fallback is false). Returns 0 and sets *line otherwise. */
p = procfs_file_alloca(pid, "cmdline");
@@ -131,11 +132,11 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
if (max_length == 1) {
/* If there's only room for one byte, return the empty string */
- r = new0(char, 1);
- if (!r)
+ ans = new0(char, 1);
+ if (!ans)
return -ENOMEM;
- *line = r;
+ *line = ans;
return 0;
} else if (max_length == 0) {
@@ -143,36 +144,36 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
while ((c = getc(f)) != EOF) {
- if (!GREEDY_REALLOC(r, allocated, len+3)) {
- free(r);
+ if (!GREEDY_REALLOC(ans, allocated, len+3)) {
+ free(ans);
return -ENOMEM;
}
if (isprint(c)) {
if (space) {
- r[len++] = ' ';
+ ans[len++] = ' ';
space = false;
}
- r[len++] = c;
+ ans[len++] = c;
} else if (len > 0)
space = true;
}
if (len > 0)
- r[len] = 0;
+ ans[len] = '\0';
else
- r = mfree(r);
+ ans = mfree(ans);
} else {
bool dotdotdot = false;
size_t left;
- r = new(char, max_length);
- if (!r)
+ ans = new(char, max_length);
+ if (!ans)
return -ENOMEM;
- k = r;
+ k = ans;
left = max_length;
while ((c = getc(f)) != EOF) {
@@ -196,20 +197,20 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
*(k++) = (char) c;
left--;
- } else if (k > r)
+ } else if (k > ans)
space = true;
}
if (dotdotdot) {
if (max_length <= 4) {
- k = r;
+ k = ans;
left = max_length;
} else {
- k = r + max_length - 4;
+ k = ans + max_length - 4;
left = 4;
/* Eat up final spaces */
- while (k > r && isspace(k[-1])) {
+ while (k > ans && isspace(k[-1])) {
k--;
left++;
}
@@ -222,11 +223,11 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
}
/* Kernel threads have no argv[] */
- if (isempty(r)) {
+ if (isempty(ans)) {
_cleanup_free_ char *t = NULL;
int h;
- free(r);
+ free(ans);
if (!comm_fallback)
return -ENOENT;
@@ -236,22 +237,22 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
return h;
if (max_length == 0)
- r = strjoin("[", t, "]", NULL);
+ ans = strjoin("[", t, "]");
else {
size_t l;
l = strlen(t);
if (l + 3 <= max_length)
- r = strjoin("[", t, "]", NULL);
+ ans = strjoin("[", t, "]");
else if (max_length <= 6) {
- r = new(char, max_length);
- if (!r)
+ ans = new(char, max_length);
+ if (!ans)
return -ENOMEM;
- memcpy(r, "[...]", max_length-1);
- r[max_length-1] = 0;
+ memcpy(ans, "[...]", max_length-1);
+ ans[max_length-1] = 0;
} else {
char *e;
@@ -263,38 +264,111 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
e--;
*e = 0;
- r = strjoin("[", t, "...]", NULL);
+ ans = strjoin("[", t, "...]");
}
}
- if (!r)
+ if (!ans)
return -ENOMEM;
}
- *line = r;
+ *line = ans;
return 0;
}
-void rename_process(const char name[8]) {
- assert(name);
+int rename_process(const char name[]) {
+ static size_t mm_size = 0;
+ static char *mm = NULL;
+ bool truncated = false;
+ size_t l;
+
+ /* This is a like a poor man's setproctitle(). It changes the comm field, argv[0], and also the glibc's
+ * internally used name of the process. For the first one a limit of 16 chars applies; to the second one in
+ * many cases one of 10 (i.e. length of "/sbin/init") — however if we have CAP_SYS_RESOURCES it is unbounded;
+ * to the third one 7 (i.e. the length of "systemd". If you pass a longer string it will likely be
+ * truncated.
+ *
+ * Returns 0 if a name was set but truncated, > 0 if it was set but not truncated. */
+
+ if (isempty(name))
+ return -EINVAL; /* let's not confuse users unnecessarily with an empty name */
- /* This is a like a poor man's setproctitle(). It changes the
- * comm field, argv[0], and also the glibc's internally used
- * name of the process. For the first one a limit of 16 chars
- * applies, to the second one usually one of 10 (i.e. length
- * of "/sbin/init"), to the third one one of 7 (i.e. length of
- * "systemd"). If you pass a longer string it will be
- * truncated */
+ l = strlen(name);
+ /* First step, change the comm field. */
(void) prctl(PR_SET_NAME, name);
+ if (l > 15) /* Linux process names can be 15 chars at max */
+ truncated = true;
+
+ /* Second step, change glibc's ID of the process name. */
+ if (program_invocation_name) {
+ size_t k;
+
+ k = strlen(program_invocation_name);
+ strncpy(program_invocation_name, name, k);
+ if (l > k)
+ truncated = true;
+ }
+
+ /* Third step, completely replace the argv[] array the kernel maintains for us. This requires privileges, but
+ * has the advantage that the argv[] array is exactly what we want it to be, and not filled up with zeros at
+ * the end. This is the best option for changing /proc/self/cmdline. */
+ if (mm_size < l+1) {
+ size_t nn_size;
+ char *nn;
+
+ /* Let's not bother with this if we don't have euid == 0. Strictly speaking if people do weird stuff
+ * with capabilities this could work even for euid != 0, but our own code generally doesn't do that,
+ * hence let's use this as quick bypass check, to avoid calling mmap() if PR_SET_MM_ARG_START fails
+ * with EPERM later on anyway. After all geteuid() is dead cheap to call, but mmap() is not. */
+ if (geteuid() != 0) {
+ log_debug("Skipping PR_SET_MM_ARG_START, as we don't have privileges.");
+ goto use_saved_argv;
+ }
+
+ nn_size = PAGE_ALIGN(l+1);
+ nn = mmap(NULL, nn_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+ if (nn == MAP_FAILED) {
+ log_debug_errno(errno, "mmap() failed: %m");
+ goto use_saved_argv;
+ }
+
+ strncpy(nn, name, nn_size);
+
+ /* Now, let's tell the kernel about this new memory */
+ if (prctl(PR_SET_MM, PR_SET_MM_ARG_START, (unsigned long) nn, 0, 0) < 0) {
+ log_debug_errno(errno, "PR_SET_MM_ARG_START failed, proceeding without: %m");
+ (void) munmap(nn, nn_size);
+ goto use_saved_argv;
+ }
+
+ /* And update the end pointer to the new end, too. If this fails, we don't really know what to do, it's
+ * pretty unlikely that we can rollback, hence we'll just accept the failure, and continue. */
+ if (prctl(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) nn + l + 1, 0, 0) < 0)
+ log_debug_errno(errno, "PR_SET_MM_ARG_END failed, proceeding without: %m");
- if (program_invocation_name)
- strncpy(program_invocation_name, name, strlen(program_invocation_name));
+ if (mm)
+ (void) munmap(mm, mm_size);
+
+ mm = nn;
+ mm_size = nn_size;
+ } else
+ strncpy(mm, name, mm_size);
+
+use_saved_argv:
+ /* Fourth step: in all cases we'll also update the original argv[], so that our own code gets it right too if
+ * it still looks here */
if (saved_argc > 0) {
int i;
- if (saved_argv[0])
- strncpy(saved_argv[0], name, strlen(saved_argv[0]));
+ if (saved_argv[0]) {
+ size_t k;
+
+ k = strlen(saved_argv[0]);
+ strncpy(saved_argv[0], name, k);
+ if (l > k)
+ truncated = true;
+ }
for (i = 1; i < saved_argc; i++) {
if (!saved_argv[i])
@@ -303,6 +377,8 @@ void rename_process(const char name[8]) {
memzero(saved_argv[i], strlen(saved_argv[i]));
}
}
+
+ return !truncated;
}
int is_kernel_thread(pid_t pid) {
@@ -627,7 +703,7 @@ int kill_and_sigcont(pid_t pid, int sig) {
/* If this worked, also send SIGCONT, unless we already just sent a SIGCONT, or SIGKILL was sent which isn't
* affected by a process being suspended anyway. */
- if (r >= 0 && !IN_SET(SIGCONT, SIGKILL))
+ if (r >= 0 && !IN_SET(sig, SIGCONT, SIGKILL))
(void) kill(pid, SIGCONT);
return r;
@@ -675,7 +751,7 @@ int getenv_for_pid(pid_t pid, const char *field, char **_value) {
}
line[i] = 0;
- if (memcmp(line, field, l) == 0 && line[l] == '=') {
+ if (strneq(line, field, l) && line[l] == '=') {
value = strdup(line + l + 1);
if (!value)
return -ENOMEM;
diff --git a/src/basic/process-util.h b/src/basic/process-util.h
index 2568e3834f..d378901399 100644
--- a/src/basic/process-util.h
+++ b/src/basic/process-util.h
@@ -28,7 +28,7 @@
#include <sys/types.h>
#include <sys/resource.h>
-#include "formats-util.h"
+#include "format-util.h"
#include "macro.h"
#define procfs_file_alloca(pid, field) \
@@ -64,7 +64,7 @@ void sigkill_waitp(pid_t *pid);
int kill_and_sigcont(pid_t pid, int sig);
-void rename_process(const char name[8]);
+int rename_process(const char name[]);
int is_kernel_thread(pid_t pid);
int getenv_for_pid(pid_t pid, const char *field, char **_value);
diff --git a/src/basic/raw-clone.h b/src/basic/raw-clone.h
index d473828999..c6e531ada4 100644
--- a/src/basic/raw-clone.h
+++ b/src/basic/raw-clone.h
@@ -47,8 +47,8 @@
static inline int raw_clone(unsigned long flags) {
assert((flags & (CLONE_VM|CLONE_PARENT_SETTID|CLONE_CHILD_SETTID|
CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0);
-#if defined(__s390__) || defined(__CRIS__)
- /* On s390 and cris the order of the first and second arguments
+#if defined(__s390x__) || defined(__s390__) || defined(__CRIS__)
+ /* On s390/s390x and cris the order of the first and second arguments
* of the raw clone() system call is reversed. */
return (int) syscall(__NR_clone, NULL, flags);
#elif defined(__sparc__) && defined(__arch64__)
diff --git a/src/basic/rlimit-util.c b/src/basic/rlimit-util.c
index ee063720ed..ca834df621 100644
--- a/src/basic/rlimit-util.c
+++ b/src/basic/rlimit-util.c
@@ -22,7 +22,7 @@
#include "alloc-util.h"
#include "extract-word.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "macro.h"
#include "missing.h"
#include "rlimit-util.h"
diff --git a/src/basic/rm-rf.c b/src/basic/rm-rf.c
index baa70c2c8d..bdaca264ff 100644
--- a/src/basic/rm-rf.c
+++ b/src/basic/rm-rf.c
@@ -17,7 +17,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
@@ -28,6 +27,7 @@
#include "btrfs-util.h"
#include "cgroup-util.h"
+#include "dirent-util.h"
#include "fd-util.h"
#include "log.h"
#include "macro.h"
@@ -43,6 +43,7 @@ static bool is_physical_fs(const struct statfs *sfs) {
int rm_rf_children(int fd, RemoveFlags flags, struct stat *root_dev) {
_cleanup_closedir_ DIR *d = NULL;
+ struct dirent *de;
int ret = 0, r;
struct statfs sfs;
@@ -78,20 +79,11 @@ int rm_rf_children(int fd, RemoveFlags flags, struct stat *root_dev) {
return errno == ENOENT ? 0 : -errno;
}
- for (;;) {
- struct dirent *de;
+ FOREACH_DIRENT_ALL(de, d, return -errno) {
bool is_dir;
struct stat st;
- errno = 0;
- de = readdir(d);
- if (!de) {
- if (errno > 0 && ret == 0)
- ret = -errno;
- return ret;
- }
-
- if (streq(de->d_name, ".") || streq(de->d_name, ".."))
+ if (dot_or_dot_dot(de->d_name))
continue;
if (de->d_type == DT_UNKNOWN ||
@@ -178,6 +170,7 @@ int rm_rf_children(int fd, RemoveFlags flags, struct stat *root_dev) {
}
}
}
+ return ret;
}
int rm_rf(const char *path, RemoveFlags flags) {
@@ -194,6 +187,13 @@ int rm_rf(const char *path, RemoveFlags flags) {
return -EPERM;
}
+ /* Another safe-check. Removing "/path/.." could easily remove entire root as well.
+ * It's especially easy to do using globs in tmpfiles, like "/path/.*", which the glob()
+ * function expands to both "/path/." and "/path/..".
+ * Return -EINVAL to be consistent with rmdir("/path/."). */
+ if (endswith(path, "/..") || endswith(path, "/../"))
+ return -EINVAL;
+
if ((flags & (REMOVE_SUBVOLUME|REMOVE_ROOT|REMOVE_PHYSICAL)) == (REMOVE_SUBVOLUME|REMOVE_ROOT|REMOVE_PHYSICAL)) {
/* Try to remove as subvolume first */
r = btrfs_subvol_remove(path, BTRFS_REMOVE_RECURSIVE|BTRFS_REMOVE_QUOTA);
diff --git a/src/basic/rm-rf.h b/src/basic/rm-rf.h
index f693a5bb7c..e13f7003e3 100644
--- a/src/basic/rm-rf.h
+++ b/src/basic/rm-rf.h
@@ -33,8 +33,6 @@ int rm_rf(const char *path, RemoveFlags flags);
/* Useful for usage with _cleanup_(), destroys a directory and frees the pointer */
static inline void rm_rf_physical_and_free(char *p) {
- if (!p)
- return;
(void) rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL);
free(p);
}
diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c
index 1662c04705..e5847dce00 100644
--- a/src/basic/socket-util.c
+++ b/src/basic/socket-util.c
@@ -34,7 +34,7 @@
#include "alloc-util.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "log.h"
#include "macro.h"
#include "missing.h"
@@ -113,6 +113,30 @@ int socket_address_parse(SocketAddress *a, const char *s) {
memcpy(a->sockaddr.un.sun_path+1, s+1, l);
a->size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
+ } else if (startswith(s, "vsock:")) {
+ /* AF_VSOCK socket in vsock:cid:port notation */
+ const char *cid_start = s + strlen("vsock:");
+
+ e = strchr(cid_start, ':');
+ if (!e)
+ return -EINVAL;
+
+ r = safe_atou(e+1, &u);
+ if (r < 0)
+ return r;
+
+ n = strndupa(cid_start, e - cid_start);
+ if (!isempty(n)) {
+ r = safe_atou(n, &a->sockaddr.vm.svm_cid);
+ if (r < 0)
+ return r;
+ } else
+ a->sockaddr.vm.svm_cid = VMADDR_CID_ANY;
+
+ a->sockaddr.vm.svm_family = AF_VSOCK;
+ a->sockaddr.vm.svm_port = u;
+ a->size = sizeof(struct sockaddr_vm);
+
} else {
e = strchr(s, ':');
if (e) {
@@ -289,6 +313,15 @@ int socket_address_verify(const SocketAddress *a) {
return 0;
+ case AF_VSOCK:
+ if (a->size != sizeof(struct sockaddr_vm))
+ return -EINVAL;
+
+ if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM)
+ return -EINVAL;
+
+ return 0;
+
default:
return -EAFNOSUPPORT;
}
@@ -394,6 +427,15 @@ bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
break;
+ case AF_VSOCK:
+ if (a->sockaddr.vm.svm_cid != b->sockaddr.vm.svm_cid)
+ return false;
+
+ if (a->sockaddr.vm.svm_port != b->sockaddr.vm.svm_port)
+ return false;
+
+ break;
+
default:
/* Cannot compare, so we assume the addresses are different */
return false;
@@ -480,15 +522,27 @@ bool socket_address_matches_fd(const SocketAddress *a, int fd) {
return socket_address_equal(a, &b);
}
-int sockaddr_port(const struct sockaddr *_sa) {
+int sockaddr_port(const struct sockaddr *_sa, unsigned *port) {
union sockaddr_union *sa = (union sockaddr_union*) _sa;
assert(sa);
- if (!IN_SET(sa->sa.sa_family, AF_INET, AF_INET6))
- return -EAFNOSUPPORT;
+ switch (sa->sa.sa_family) {
+ case AF_INET:
+ *port = be16toh(sa->in.sin_port);
+ return 0;
+
+ case AF_INET6:
+ *port = be16toh(sa->in6.sin6_port);
+ return 0;
- return be16toh(sa->sa.sa_family == AF_INET6 ? sa->in6.sin6_port : sa->in.sin_port);
+ case AF_VSOCK:
+ *port = sa->vm.svm_port;
+ return 0;
+
+ default:
+ return -EAFNOSUPPORT;
+ }
}
int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret) {
@@ -591,6 +645,18 @@ int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_
break;
+ case AF_VSOCK:
+ if (include_port)
+ r = asprintf(&p,
+ "vsock:%u:%u",
+ sa->vm.svm_cid,
+ sa->vm.svm_port);
+ else
+ r = asprintf(&p, "vsock:%u", sa->vm.svm_cid);
+ if (r < 0)
+ return -ENOMEM;
+ break;
+
default:
return -EOPNOTSUPP;
}
@@ -748,6 +814,9 @@ bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b
if (a->sa.sa_family == AF_INET6)
return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)) == 0;
+ if (a->sa.sa_family == AF_VSOCK)
+ return a->vm.svm_cid == b->vm.svm_cid;
+
return false;
}
@@ -808,7 +877,7 @@ bool ifname_valid(const char *p) {
if (strlen(p) >= IFNAMSIZ)
return false;
- if (STR_IN_SET(p, ".", ".."))
+ if (dot_or_dot_dot(p))
return false;
while (*p) {
@@ -831,6 +900,26 @@ bool ifname_valid(const char *p) {
return true;
}
+bool address_label_valid(const char *p) {
+
+ if (isempty(p))
+ return false;
+
+ if (strlen(p) >= IFNAMSIZ)
+ return false;
+
+ while (*p) {
+ if ((uint8_t) *p >= 127U)
+ return false;
+
+ if ((uint8_t) *p <= 31U)
+ return false;
+ p++;
+ }
+
+ return true;
+}
+
int getpeercred(int fd, struct ucred *ucred) {
socklen_t n = sizeof(struct ucred);
struct ucred u;
diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h
index 2ef572badb..73c3a339fc 100644
--- a/src/basic/socket-util.h
+++ b/src/basic/socket-util.h
@@ -30,6 +30,7 @@
#include <linux/if_packet.h>
#include "macro.h"
+#include "missing.h"
#include "util.h"
union sockaddr_union {
@@ -40,6 +41,7 @@ union sockaddr_union {
struct sockaddr_nl nl;
struct sockaddr_storage storage;
struct sockaddr_ll ll;
+ struct sockaddr_vm vm;
};
typedef struct SocketAddress {
@@ -100,7 +102,7 @@ const char* socket_address_get_path(const SocketAddress *a);
bool socket_ipv6_is_supported(void);
-int sockaddr_port(const struct sockaddr *_sa) _pure_;
+int sockaddr_port(const struct sockaddr *_sa, unsigned *port);
int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret);
int getpeername_pretty(int fd, bool include_port, char **ret);
@@ -124,6 +126,7 @@ int ip_tos_to_string_alloc(int i, char **s);
int ip_tos_from_string(const char *s);
bool ifname_valid(const char *p);
+bool address_label_valid(const char *p);
int getpeercred(int fd, struct ucred *ucred);
int getpeersec(int fd, char **ret);
diff --git a/src/basic/special.h b/src/basic/special.h
index 5276bcf598..feb8e5fe21 100644
--- a/src/basic/special.h
+++ b/src/basic/special.h
@@ -103,6 +103,7 @@
#define SPECIAL_DBUS_SOCKET "dbus.socket"
#define SPECIAL_JOURNALD_SOCKET "systemd-journald.socket"
#define SPECIAL_JOURNALD_SERVICE "systemd-journald.service"
+#define SPECIAL_TMPFILES_SETUP_SERVICE "systemd-tmpfiles-setup.service"
/* Magic init signals */
#define SPECIAL_KBREQUEST_TARGET "kbrequest.target"
diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c
index 309e84b93d..7e1914aa14 100644
--- a/src/basic/stat-util.c
+++ b/src/basic/stat-util.c
@@ -28,6 +28,7 @@
#include "dirent-util.h"
#include "fd-util.h"
+#include "fs-util.h"
#include "macro.h"
#include "missing.h"
#include "stat-util.h"
@@ -143,22 +144,29 @@ int path_is_read_only_fs(const char *path) {
}
int path_is_os_tree(const char *path) {
- char *p;
int r;
assert(path);
- /* We use /usr/lib/os-release as flag file if something is an OS */
- p = strjoina(path, "/usr/lib/os-release");
- r = access(p, F_OK);
- if (r >= 0)
- return 1;
+ /* Does the path exist at all? If not, generate an error immediately. This is useful so that a missing root dir
+ * always results in -ENOENT, and we can properly distuingish the case where the whole root doesn't exist from
+ * the case where just the os-release file is missing. */
+ if (laccess(path, F_OK) < 0)
+ return -errno;
- /* Also check for the old location in /etc, just in case. */
- p = strjoina(path, "/etc/os-release");
- r = access(p, F_OK);
+ /* We use /usr/lib/os-release as flag file if something is an OS */
+ r = chase_symlinks("/usr/lib/os-release", path, CHASE_PREFIX_ROOT, NULL);
+ if (r == -ENOENT) {
+
+ /* Also check for the old location in /etc, just in case. */
+ r = chase_symlinks("/etc/os-release", path, CHASE_PREFIX_ROOT, NULL);
+ if (r == -ENOENT)
+ return 0; /* We got nothing */
+ }
+ if (r < 0)
+ return r;
- return r >= 0;
+ return 1;
}
int files_same(const char *filea, const char *fileb) {
@@ -196,7 +204,7 @@ int fd_check_fstype(int fd, statfs_f_type_t magic_value) {
int path_check_fstype(const char *path, statfs_f_type_t magic_value) {
_cleanup_close_ int fd = -1;
- fd = open(path, O_RDONLY);
+ fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_PATH);
if (fd < 0)
return -errno;
@@ -216,3 +224,13 @@ int fd_is_temporary_fs(int fd) {
return is_temporary_fs(&s);
}
+
+int path_is_temporary_fs(const char *path) {
+ _cleanup_close_ int fd = -1;
+
+ fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_PATH);
+ if (fd < 0)
+ return -errno;
+
+ return fd_is_temporary_fs(fd);
+}
diff --git a/src/basic/stat-util.h b/src/basic/stat-util.h
index 56d28f791e..5d571efe18 100644
--- a/src/basic/stat-util.h
+++ b/src/basic/stat-util.h
@@ -61,6 +61,7 @@ int path_check_fstype(const char *path, statfs_f_type_t magic_value);
bool is_temporary_fs(const struct statfs *s) _pure_;
int fd_is_temporary_fs(int fd);
+int path_is_temporary_fs(const char *path);
/* Because statfs.t_type can be int on some architectures, we have to cast
* the const magic to the type, otherwise the compiler warns about
diff --git a/src/basic/string-util.c b/src/basic/string-util.c
index 6b06e643c9..9d2f4bc8f9 100644
--- a/src/basic/string-util.c
+++ b/src/basic/string-util.c
@@ -218,7 +218,7 @@ char *strappend(const char *s, const char *suffix) {
return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
}
-char *strjoin(const char *x, ...) {
+char *strjoin_real(const char *x, ...) {
va_list ap;
size_t l;
char *r, *p;
@@ -821,6 +821,7 @@ int free_and_strdup(char **p, const char *s) {
return 1;
}
+#if !HAVE_DECL_EXPLICIT_BZERO
/*
* Pointer to memset is volatile so that compiler must de-reference
* the pointer and can't assume that it points to any function in
@@ -831,19 +832,19 @@ typedef void *(*memset_t)(void *,int,size_t);
static volatile memset_t memset_func = memset;
-void* memory_erase(void *p, size_t l) {
- return memset_func(p, 'x', l);
+void explicit_bzero(void *p, size_t l) {
+ memset_func(p, '\0', l);
}
+#endif
char* string_erase(char *x) {
-
if (!x)
return NULL;
/* A delicious drop of snake-oil! To be called on memory where
* we stored passphrases or so, after we used them. */
-
- return memory_erase(x, strlen(x));
+ explicit_bzero(x, strlen(x));
+ return x;
}
char *string_free_erase(char *s) {
diff --git a/src/basic/string-util.h b/src/basic/string-util.h
index d029d538bd..be44dedff4 100644
--- a/src/basic/string-util.h
+++ b/src/basic/string-util.h
@@ -107,16 +107,14 @@ const char* split(const char **state, size_t *l, const char *separator, bool quo
#define FOREACH_WORD_SEPARATOR(word, length, s, separator, state) \
_FOREACH_WORD(word, length, s, separator, false, state)
-#define FOREACH_WORD_QUOTED(word, length, s, state) \
- _FOREACH_WORD(word, length, s, WHITESPACE, true, state)
-
#define _FOREACH_WORD(word, length, s, separator, quoted, state) \
for ((state) = (s), (word) = split(&(state), &(length), (separator), (quoted)); (word); (word) = split(&(state), &(length), (separator), (quoted)))
char *strappend(const char *s, const char *suffix);
char *strnappend(const char *s, const char *suffix, size_t length);
-char *strjoin(const char *x, ...) _sentinel_;
+char *strjoin_real(const char *x, ...) _sentinel_;
+#define strjoin(a, ...) strjoin_real((a), __VA_ARGS__, NULL)
#define strjoina(a, ...) \
({ \
@@ -191,7 +189,10 @@ static inline void *memmem_safe(const void *haystack, size_t haystacklen, const
return memmem(haystack, haystacklen, needle, needlelen);
}
-void* memory_erase(void *p, size_t l);
+#if !HAVE_DECL_EXPLICIT_BZERO
+void explicit_bzero(void *p, size_t l);
+#endif
+
char *string_erase(char *x);
char *string_free_erase(char *s);
diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c
index eafdea9eb3..9a8ef825c5 100644
--- a/src/basic/terminal-util.c
+++ b/src/basic/terminal-util.c
@@ -144,12 +144,14 @@ int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
return 0;
}
-int ask_char(char *ret, const char *replies, const char *text, ...) {
+#define DEFAULT_ASK_REFRESH_USEC (2*USEC_PER_SEC)
+
+int ask_char(char *ret, const char *replies, const char *fmt, ...) {
int r;
assert(ret);
assert(replies);
- assert(text);
+ assert(fmt);
for (;;) {
va_list ap;
@@ -159,8 +161,10 @@ int ask_char(char *ret, const char *replies, const char *text, ...) {
if (colors_enabled())
fputs(ANSI_HIGHLIGHT, stdout);
- va_start(ap, text);
- vprintf(text, ap);
+ putchar('\r');
+
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
va_end(ap);
if (colors_enabled())
@@ -168,9 +172,12 @@ int ask_char(char *ret, const char *replies, const char *text, ...) {
fflush(stdout);
- r = read_one_char(stdin, &c, USEC_INFINITY, &need_nl);
+ r = read_one_char(stdin, &c, DEFAULT_ASK_REFRESH_USEC, &need_nl);
if (r < 0) {
+ if (r == -ETIMEDOUT)
+ continue;
+
if (r == -EBADMSG) {
puts("Bad input, please try again.");
continue;
@@ -455,7 +462,7 @@ int acquire_terminal(
goto fail;
}
- r = fd_wait_for_event(fd, POLLIN, ts + timeout - n);
+ r = fd_wait_for_event(notify, POLLIN, ts + timeout - n);
if (r < 0)
goto fail;
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
index cc5a158669..a0db97c41a 100644
--- a/src/basic/time-util.c
+++ b/src/basic/time-util.c
@@ -185,7 +185,7 @@ usec_t triple_timestamp_by_clock(triple_timestamp *ts, clockid_t clock) {
usec_t timespec_load(const struct timespec *ts) {
assert(ts);
- if (ts->tv_sec == (time_t) -1 && ts->tv_nsec == (long) -1)
+ if (ts->tv_sec < 0 || ts->tv_nsec < 0)
return USEC_INFINITY;
if ((usec_t) ts->tv_sec > (UINT64_MAX - (ts->tv_nsec / NSEC_PER_USEC)) / USEC_PER_SEC)
@@ -199,7 +199,7 @@ usec_t timespec_load(const struct timespec *ts) {
nsec_t timespec_load_nsec(const struct timespec *ts) {
assert(ts);
- if (ts->tv_sec == (time_t) -1 && ts->tv_nsec == (long) -1)
+ if (ts->tv_sec < 0 || ts->tv_nsec < 0)
return NSEC_INFINITY;
if ((nsec_t) ts->tv_sec >= (UINT64_MAX - ts->tv_nsec) / NSEC_PER_SEC)
@@ -211,7 +211,8 @@ nsec_t timespec_load_nsec(const struct timespec *ts) {
struct timespec *timespec_store(struct timespec *ts, usec_t u) {
assert(ts);
- if (u == USEC_INFINITY) {
+ if (u == USEC_INFINITY ||
+ u / USEC_PER_SEC >= TIME_T_MAX) {
ts->tv_sec = (time_t) -1;
ts->tv_nsec = (long) -1;
return ts;
@@ -226,8 +227,7 @@ struct timespec *timespec_store(struct timespec *ts, usec_t u) {
usec_t timeval_load(const struct timeval *tv) {
assert(tv);
- if (tv->tv_sec == (time_t) -1 &&
- tv->tv_usec == (suseconds_t) -1)
+ if (tv->tv_sec < 0 || tv->tv_usec < 0)
return USEC_INFINITY;
if ((usec_t) tv->tv_sec > (UINT64_MAX - tv->tv_usec) / USEC_PER_SEC)
@@ -241,7 +241,8 @@ usec_t timeval_load(const struct timeval *tv) {
struct timeval *timeval_store(struct timeval *tv, usec_t u) {
assert(tv);
- if (u == USEC_INFINITY) {
+ if (u == USEC_INFINITY||
+ u / USEC_PER_SEC > TIME_T_MAX) {
tv->tv_sec = (time_t) -1;
tv->tv_usec = (suseconds_t) -1;
} else {
@@ -288,9 +289,11 @@ static char *format_timestamp_internal(
if (t <= 0 || t == USEC_INFINITY)
return NULL; /* Timestamp is unset */
+ /* Let's not format times with years > 9999 */
+ if (t > USEC_TIMESTAMP_FORMATTABLE_MAX)
+ return NULL;
+
sec = (time_t) (t / USEC_PER_SEC); /* Round down */
- if ((usec_t) sec != (t / USEC_PER_SEC))
- return NULL; /* overflow? */
if (!localtime_or_gmtime_r(&sec, &tm, utc))
return NULL;
@@ -309,7 +312,7 @@ static char *format_timestamp_internal(
if (n + 8 > l)
return NULL; /* Microseconds part doesn't fit. */
- sprintf(buf + n, ".%06llu", (unsigned long long) (t % USEC_PER_SEC));
+ sprintf(buf + n, ".%06"PRI_USEC, t % USEC_PER_SEC);
}
/* Append the timezone */
@@ -499,11 +502,11 @@ char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) {
if (j > 0) {
k = snprintf(p, l,
- "%s"USEC_FMT".%0*llu%s",
+ "%s"USEC_FMT".%0*"PRI_USEC"%s",
p > buf ? " " : "",
a,
j,
- (unsigned long long) b,
+ b,
table[i].suffix);
t = 0;
@@ -551,12 +554,12 @@ void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t) {
}
int dual_timestamp_deserialize(const char *value, dual_timestamp *t) {
- unsigned long long a, b;
+ uint64_t a, b;
assert(value);
assert(t);
- if (sscanf(value, "%llu %llu", &a, &b) != 2) {
+ if (sscanf(value, "%" PRIu64 "%" PRIu64, &a, &b) != 2) {
log_debug("Failed to parse dual timestamp value \"%s\": %m", value);
return -EINVAL;
}
@@ -830,16 +833,23 @@ parse_usec:
from_tm:
x = mktime_or_timegm(&tm, utc);
- if (x == (time_t) -1)
+ if (x < 0)
return -EINVAL;
if (weekday >= 0 && tm.tm_wday != weekday)
return -EINVAL;
ret = (usec_t) x * USEC_PER_SEC + x_usec;
+ if (ret > USEC_TIMESTAMP_FORMATTABLE_MAX)
+ return -EINVAL;
finish:
+ if (ret + plus < ret) /* overflow? */
+ return -EINVAL;
ret += plus;
+ if (ret > USEC_TIMESTAMP_FORMATTABLE_MAX)
+ return -EINVAL;
+
if (ret > minus)
ret -= minus;
else
@@ -883,6 +893,7 @@ static char* extract_multiplier(char *p, usec_t *multiplier) {
{ "y", USEC_PER_YEAR },
{ "usec", 1ULL },
{ "us", 1ULL },
+ { "µs", 1ULL },
};
unsigned i;
@@ -1016,6 +1027,7 @@ int parse_nsec(const char *t, nsec_t *nsec) {
{ "y", NSEC_PER_YEAR },
{ "usec", NSEC_PER_USEC },
{ "us", NSEC_PER_USEC },
+ { "µs", NSEC_PER_USEC },
{ "nsec", 1ULL },
{ "ns", 1ULL },
{ "", 1ULL }, /* default is nsec */
@@ -1320,7 +1332,7 @@ unsigned long usec_to_jiffies(usec_t u) {
r = sysconf(_SC_CLK_TCK);
assert(r > 0);
- hz = (unsigned long) r;
+ hz = r;
}
return DIV_ROUND_UP(u , USEC_PER_SEC / hz);
diff --git a/src/basic/time-util.h b/src/basic/time-util.h
index 558b0b5b7f..7463507f51 100644
--- a/src/basic/time-util.h
+++ b/src/basic/time-util.h
@@ -29,8 +29,10 @@
typedef uint64_t usec_t;
typedef uint64_t nsec_t;
-#define NSEC_FMT "%" PRIu64
-#define USEC_FMT "%" PRIu64
+#define PRI_NSEC PRIu64
+#define PRI_USEC PRIu64
+#define NSEC_FMT "%" PRI_NSEC
+#define USEC_FMT "%" PRI_USEC
#include "macro.h"
@@ -179,3 +181,14 @@ static inline usec_t usec_sub(usec_t timestamp, int64_t delta) {
return timestamp - delta;
}
+
+#if SIZEOF_TIME_T == 8
+/* The last second we can format is 31. Dec 9999, 1s before midnight, because otherwise we'd enter 5 digit year
+ * territory. However, since we want to stay away from this in all timezones we take one day off. */
+#define USEC_TIMESTAMP_FORMATTABLE_MAX ((usec_t) 253402214399000000)
+#elif SIZEOF_TIME_T == 4
+/* With a 32bit time_t we can't go beyond 2038... */
+#define USEC_TIMESTAMP_FORMATTABLE_MAX ((usec_t) 2147483647000000)
+#else
+#error "Yuck, time_t is neither 4 not 8 bytes wide?"
+#endif
diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c
index fe883b95c7..0a6efa449a 100644
--- a/src/basic/unit-name.c
+++ b/src/basic/unit-name.c
@@ -273,7 +273,7 @@ int unit_name_build(const char *prefix, const char *instance, const char *suffix
if (!instance)
s = strappend(prefix, suffix);
else
- s = strjoin(prefix, "@", instance, suffix, NULL);
+ s = strjoin(prefix, "@", instance, suffix);
if (!s)
return -ENOMEM;
@@ -554,7 +554,7 @@ int unit_name_from_path_instance(const char *prefix, const char *path, const cha
if (r < 0)
return r;
- s = strjoin(prefix, "@", p, suffix, NULL);
+ s = strjoin(prefix, "@", p, suffix);
if (!s)
return -ENOMEM;
diff --git a/src/basic/user-util.c b/src/basic/user-util.c
index de6c93056e..c619dad527 100644
--- a/src/basic/user-util.c
+++ b/src/basic/user-util.c
@@ -34,7 +34,7 @@
#include "alloc-util.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "macro.h"
#include "missing.h"
#include "parse-util.h"
@@ -46,6 +46,8 @@
bool uid_is_valid(uid_t uid) {
+ /* Also see POSIX IEEE Std 1003.1-2008, 2016 Edition, 3.436. */
+
/* Some libc APIs use UID_INVALID as special placeholder */
if (uid == (uid_t) UINT32_C(0xFFFFFFFF))
return false;
@@ -519,7 +521,15 @@ bool valid_user_group_name(const char *u) {
const char *i;
long sz;
- /* Checks if the specified name is a valid user/group name. */
+ /* Checks if the specified name is a valid user/group name. Also see POSIX IEEE Std 1003.1-2008, 2016 Edition,
+ * 3.437. We are a bit stricter here however. Specifically we deviate from POSIX rules:
+ *
+ * - We don't allow any dots (this would break chown syntax which permits dots as user/group name separator)
+ * - We require that names fit into the appropriate utmp field
+ * - We don't allow empty user names
+ *
+ * Note that other systems are even more restrictive, and don't permit underscores or uppercase characters.
+ */
if (isempty(u))
return false;
diff --git a/src/basic/util.c b/src/basic/util.c
index ec7939dc83..3dce0ea92e 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -18,7 +18,6 @@
***/
#include <alloca.h>
-#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <sched.h>
@@ -41,7 +40,7 @@
#include "dirent-util.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "hashmap.h"
#include "hostname-util.h"
#include "log.h"
@@ -60,9 +59,6 @@
#include "user-util.h"
#include "util.h"
-/* Put this test here for a lack of better place */
-assert_cc(EAGAIN == EWOULDBLOCK);
-
int saved_argc = 0;
char **saved_argv = NULL;
static int saved_in_initrd = -1;
@@ -81,146 +77,6 @@ size_t page_size(void) {
return pgsz;
}
-static int do_execute(char **directories, usec_t timeout, char *argv[]) {
- _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
- _cleanup_set_free_free_ Set *seen = NULL;
- char **directory;
-
- /* We fork this all off from a child process so that we can
- * somewhat cleanly make use of SIGALRM to set a time limit */
-
- (void) reset_all_signal_handlers();
- (void) reset_signal_mask();
-
- assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
-
- pids = hashmap_new(NULL);
- if (!pids)
- return log_oom();
-
- seen = set_new(&string_hash_ops);
- if (!seen)
- return log_oom();
-
- STRV_FOREACH(directory, directories) {
- _cleanup_closedir_ DIR *d;
- struct dirent *de;
-
- d = opendir(*directory);
- if (!d) {
- if (errno == ENOENT)
- continue;
-
- return log_error_errno(errno, "Failed to open directory %s: %m", *directory);
- }
-
- FOREACH_DIRENT(de, d, break) {
- _cleanup_free_ char *path = NULL;
- pid_t pid;
- int r;
-
- if (!dirent_is_file(de))
- continue;
-
- if (set_contains(seen, de->d_name)) {
- log_debug("%1$s/%2$s skipped (%2$s was already seen).", *directory, de->d_name);
- continue;
- }
-
- r = set_put_strdup(seen, de->d_name);
- if (r < 0)
- return log_oom();
-
- path = strjoin(*directory, "/", de->d_name, NULL);
- if (!path)
- return log_oom();
-
- if (null_or_empty_path(path)) {
- log_debug("%s is empty (a mask).", path);
- continue;
- }
-
- pid = fork();
- if (pid < 0) {
- log_error_errno(errno, "Failed to fork: %m");
- continue;
- } else if (pid == 0) {
- char *_argv[2];
-
- assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
-
- if (!argv) {
- _argv[0] = path;
- _argv[1] = NULL;
- argv = _argv;
- } else
- argv[0] = path;
-
- execv(path, argv);
- return log_error_errno(errno, "Failed to execute %s: %m", path);
- }
-
- log_debug("Spawned %s as " PID_FMT ".", path, pid);
-
- r = hashmap_put(pids, PID_TO_PTR(pid), path);
- if (r < 0)
- return log_oom();
- path = NULL;
- }
- }
-
- /* Abort execution of this process after the timout. We simply
- * rely on SIGALRM as default action terminating the process,
- * and turn on alarm(). */
-
- if (timeout != USEC_INFINITY)
- alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
-
- while (!hashmap_isempty(pids)) {
- _cleanup_free_ char *path = NULL;
- pid_t pid;
-
- pid = PTR_TO_PID(hashmap_first_key(pids));
- assert(pid > 0);
-
- path = hashmap_remove(pids, PID_TO_PTR(pid));
- assert(path);
-
- wait_for_terminate_and_warn(path, pid, true);
- }
-
- return 0;
-}
-
-void execute_directories(const char* const* directories, usec_t timeout, char *argv[]) {
- pid_t executor_pid;
- int r;
- char *name;
- char **dirs = (char**) directories;
-
- assert(!strv_isempty(dirs));
-
- name = basename(dirs[0]);
- assert(!isempty(name));
-
- /* Executes all binaries in the directories in parallel and waits
- * for them to finish. Optionally a timeout is applied. If a file
- * with the same name exists in more than one directory, the
- * earliest one wins. */
-
- executor_pid = fork();
- if (executor_pid < 0) {
- log_error_errno(errno, "Failed to fork: %m");
- return;
-
- } else if (executor_pid == 0) {
- r = do_execute(dirs, timeout, argv);
- _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
- }
-
- wait_for_terminate_and_warn(name, executor_pid, true);
-}
-
bool plymouth_running(void) {
return access("/run/plymouth/pid", F_OK) >= 0;
}
@@ -493,7 +349,7 @@ void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
u = nmemb;
while (l < u) {
idx = (l + u) / 2;
- p = (void *)(((const char *) base) + (idx * size));
+ p = (const char *) base + idx * size;
comparison = compar(key, p, arg);
if (comparison < 0)
u = idx;
@@ -508,28 +364,17 @@ void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
int on_ac_power(void) {
bool found_offline = false, found_online = false;
_cleanup_closedir_ DIR *d = NULL;
+ struct dirent *de;
d = opendir("/sys/class/power_supply");
if (!d)
return errno == ENOENT ? true : -errno;
- for (;;) {
- struct dirent *de;
+ FOREACH_DIRENT(de, d, return -errno) {
_cleanup_close_ int fd = -1, device = -1;
char contents[6];
ssize_t n;
- errno = 0;
- de = readdir(d);
- if (!de && errno > 0)
- return -errno;
-
- if (!de)
- break;
-
- if (hidden_or_backup_file(de->d_name))
- continue;
-
device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
if (device < 0) {
if (errno == ENOENT || errno == ENOTDIR)
diff --git a/src/basic/util.h b/src/basic/util.h
index bb2fc318ef..c7da6c39bf 100644
--- a/src/basic/util.h
+++ b/src/basic/util.h
@@ -41,7 +41,7 @@
#include <time.h>
#include <unistd.h>
-#include "formats-util.h"
+#include "format-util.h"
#include "macro.h"
#include "missing.h"
#include "time-util.h"
@@ -65,8 +65,6 @@ static inline const char* enable_disable(bool b) {
return b ? "enable" : "disable";
}
-void execute_directories(const char* const* directories, usec_t timeout, char *argv[]);
-
bool plymouth_running(void);
bool display_is_local(const char *display) _pure_;
diff --git a/src/basic/virt.c b/src/basic/virt.c
index d8d57381ad..ff4491d6d6 100644
--- a/src/basic/virt.c
+++ b/src/basic/virt.c
@@ -25,6 +25,7 @@
#include "alloc-util.h"
#include "dirent-util.h"
+#include "env-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "macro.h"
@@ -33,7 +34,6 @@
#include "string-table.h"
#include "string-util.h"
#include "virt.h"
-#include "env-util.h"
static int detect_vm_cpuid(void) {
@@ -48,7 +48,7 @@ static int detect_vm_cpuid(void) {
{ "KVMKVMKVM", VIRTUALIZATION_KVM },
/* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
{ "VMwareVMware", VIRTUALIZATION_VMWARE },
- /* http://msdn.microsoft.com/en-us/library/ff542428.aspx */
+ /* https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs */
{ "Microsoft Hv", VIRTUALIZATION_MICROSOFT },
/* https://wiki.freebsd.org/bhyve */
{ "bhyve bhyve ", VIRTUALIZATION_BHYVE },
@@ -315,25 +315,31 @@ static int detect_vm_zvm(void) {
/* Returns a short identifier for the various VM implementations */
int detect_vm(void) {
static thread_local int cached_found = _VIRTUALIZATION_INVALID;
- int r;
+ int r, dmi;
if (cached_found >= 0)
return cached_found;
/* We have to use the correct order here:
- * Some virtualization technologies do use KVM hypervisor but are
- * expected to be detected as something else. So detect DMI first.
*
- * An example is Virtualbox since version 5.0, which uses KVM backend.
- * Detection via DMI works corretly, the CPU ID would find KVM
- * only. */
- r = detect_vm_dmi();
+ * -> First try to detect Oracle Virtualbox, even if it uses KVM.
+ * -> Second try to detect from cpuid, this will report KVM for
+ * whatever software is used even if info in dmi is overwritten.
+ * -> Third try to detect from dmi. */
+
+ dmi = detect_vm_dmi();
+ if (dmi == VIRTUALIZATION_ORACLE) {
+ r = dmi;
+ goto finish;
+ }
+
+ r = detect_vm_cpuid();
if (r < 0)
return r;
if (r != VIRTUALIZATION_NONE)
goto finish;
- r = detect_vm_cpuid();
+ r = dmi;
if (r < 0)
return r;
if (r != VIRTUALIZATION_NONE)
@@ -408,8 +414,7 @@ int detect_container(void) {
if (cached_found >= 0)
return cached_found;
- /* /proc/vz exists in container and outside of the container,
- * /proc/bc only outside of the container. */
+ /* /proc/vz exists in container and outside of the container, /proc/bc only outside of the container. */
if (access("/proc/vz", F_OK) >= 0 &&
access("/proc/bc", F_OK) < 0) {
r = VIRTUALIZATION_OPENVZ;
@@ -417,50 +422,58 @@ int detect_container(void) {
}
if (getpid() == 1) {
- /* If we are PID 1 we can just check our own
- * environment variable */
+ /* If we are PID 1 we can just check our own environment variable, and that's authoritative. */
e = getenv("container");
if (isempty(e)) {
r = VIRTUALIZATION_NONE;
goto finish;
}
- } else {
-
- /* Otherwise, PID 1 dropped this information into a
- * file in /run. This is better than accessing
- * /proc/1/environ, since we don't need CAP_SYS_PTRACE
- * for that. */
-
- r = read_one_line_file("/run/systemd/container", &m);
- if (r == -ENOENT) {
-
- /* Fallback for cases where PID 1 was not
- * systemd (for example, cases where
- * init=/bin/sh is used. */
-
- r = getenv_for_pid(1, "container", &m);
- if (r <= 0) {
-
- /* If that didn't work, give up,
- * assume no container manager.
- *
- * Note: This means we still cannot
- * detect containers if init=/bin/sh
- * is passed but privileges dropped,
- * as /proc/1/environ is only readable
- * with privileges. */
-
- r = VIRTUALIZATION_NONE;
- goto finish;
- }
- }
- if (r < 0)
- return r;
+ goto translate_name;
+ }
+
+ /* Otherwise, PID 1 might have dropped this information into a file in /run. This is better than accessing
+ * /proc/1/environ, since we don't need CAP_SYS_PTRACE for that. */
+ r = read_one_line_file("/run/systemd/container", &m);
+ if (r >= 0) {
+ e = m;
+ goto translate_name;
+ }
+ if (r != -ENOENT)
+ return log_debug_errno(r, "Failed to read /run/systemd/container: %m");
+
+ /* Fallback for cases where PID 1 was not systemd (for example, cases where init=/bin/sh is used. */
+ r = getenv_for_pid(1, "container", &m);
+ if (r > 0) {
e = m;
+ goto translate_name;
}
+ if (r < 0) /* This only works if we have CAP_SYS_PTRACE, hence let's better ignore failures here */
+ log_debug_errno(r, "Failed to read $container of PID 1, ignoring: %m");
+
+ /* Interestingly /proc/1/sched actually shows the host's PID for what we see as PID 1. Hence, if the PID shown
+ * there is not 1, we know we are in a PID namespace. and hence a container. */
+ r = read_one_line_file("/proc/1/sched", &m);
+ if (r >= 0) {
+ const char *t;
+
+ t = strrchr(m, '(');
+ if (!t)
+ return -EIO;
+
+ if (!startswith(t, "(1,")) {
+ r = VIRTUALIZATION_CONTAINER_OTHER;
+ goto finish;
+ }
+ } else if (r != -ENOENT)
+ return r;
+
+ /* If that didn't work, give up, assume no container manager. */
+ r = VIRTUALIZATION_NONE;
+ goto finish;
+translate_name:
for (j = 0; j < ELEMENTSOF(value_table); j++)
if (streq(e, value_table[j].value)) {
r = value_table[j].id;
@@ -470,7 +483,7 @@ int detect_container(void) {
r = VIRTUALIZATION_CONTAINER_OTHER;
finish:
- log_debug("Found container virtualization %s", virtualization_to_string(r));
+ log_debug("Found container virtualization %s.", virtualization_to_string(r));
cached_found = r;
return r;
}
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
index d53f8b2a6f..297dcb535a 100644
--- a/src/boot/bootctl.c
+++ b/src/boot/bootctl.c
@@ -38,20 +38,22 @@
#include "alloc-util.h"
#include "blkid-util.h"
+#include "copy.h"
#include "dirent-util.h"
#include "efivars.h"
#include "fd-util.h"
#include "fileio.h"
+#include "fs-util.h"
#include "locale-util.h"
#include "parse-util.h"
#include "rm-rf.h"
+#include "stat-util.h"
#include "string-util.h"
#include "strv.h"
#include "umask-util.h"
#include "util.h"
#include "verbs.h"
#include "virt.h"
-#include "stat-util.h"
static char *arg_path = NULL;
static bool arg_touch_variables = true;
@@ -123,12 +125,8 @@ static int verify_esp(
errno = 0;
b = blkid_new_probe_from_filename(t);
- if (!b) {
- if (errno == 0)
- return log_oom();
-
- return log_error_errno(errno, "Failed to open file system \"%s\": %m", p);
- }
+ if (!b)
+ return log_error_errno(errno ?: ENOMEM, "Failed to open file system \"%s\": %m", p);
blkid_probe_enable_superblocks(b, 1);
blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
@@ -143,17 +141,13 @@ static int verify_esp(
} else if (r == 1) {
log_error("File system \"%s\" does not contain a label.", p);
return -ENODEV;
- } else if (r != 0) {
- r = errno ? -errno : -EIO;
- return log_error_errno(r, "Failed to probe file system \"%s\": %m", p);
- }
+ } else if (r != 0)
+ return log_error_errno(errno ?: EIO, "Failed to probe file system \"%s\": %m", p);
errno = 0;
r = blkid_probe_lookup_value(b, "TYPE", &v, NULL);
- if (r != 0) {
- r = errno ? -errno : -EIO;
- return log_error_errno(r, "Failed to probe file system type \"%s\": %m", p);
- }
+ if (r != 0)
+ return log_error_errno(errno ?: EIO, "Failed to probe file system type \"%s\": %m", p);
if (!streq(v, "vfat")) {
log_error("File system \"%s\" is not FAT.", p);
return -ENODEV;
@@ -161,10 +155,8 @@ static int verify_esp(
errno = 0;
r = blkid_probe_lookup_value(b, "PART_ENTRY_SCHEME", &v, NULL);
- if (r != 0) {
- r = errno ? -errno : -EIO;
- return log_error_errno(r, "Failed to probe partition scheme \"%s\": %m", p);
- }
+ if (r != 0)
+ return log_error_errno(errno ?: EIO, "Failed to probe partition scheme \"%s\": %m", p);
if (!streq(v, "gpt")) {
log_error("File system \"%s\" is not on a GPT partition table.", p);
return -ENODEV;
@@ -172,10 +164,8 @@ static int verify_esp(
errno = 0;
r = blkid_probe_lookup_value(b, "PART_ENTRY_TYPE", &v, NULL);
- if (r != 0) {
- r = errno ? -errno : -EIO;
- return log_error_errno(r, "Failed to probe partition type UUID \"%s\": %m", p);
- }
+ if (r != 0)
+ return log_error_errno(errno ?: EIO, "Failed to probe partition type UUID \"%s\": %m", p);
if (!streq(v, "c12a7328-f81f-11d2-ba4b-00a0c93ec93b")) {
log_error("File system \"%s\" has wrong type for an EFI System Partition (ESP).", p);
return -ENODEV;
@@ -183,10 +173,8 @@ static int verify_esp(
errno = 0;
r = blkid_probe_lookup_value(b, "PART_ENTRY_UUID", &v, NULL);
- if (r != 0) {
- r = errno ? -errno : -EIO;
- return log_error_errno(r, "Failed to probe partition entry UUID \"%s\": %m", p);
- }
+ if (r != 0)
+ return log_error_errno(errno ?: EIO, "Failed to probe partition entry UUID \"%s\": %m", p);
r = sd_id128_from_string(v, &uuid);
if (r < 0) {
log_error("Partition \"%s\" has invalid UUID \"%s\".", p, v);
@@ -195,30 +183,24 @@ static int verify_esp(
errno = 0;
r = blkid_probe_lookup_value(b, "PART_ENTRY_NUMBER", &v, NULL);
- if (r != 0) {
- r = errno ? -errno : -EIO;
- return log_error_errno(r, "Failed to probe partition number \"%s\": m", p);
- }
+ if (r != 0)
+ return log_error_errno(errno ?: EIO, "Failed to probe partition number \"%s\": m", p);
r = safe_atou32(v, &part);
if (r < 0)
return log_error_errno(r, "Failed to parse PART_ENTRY_NUMBER field.");
errno = 0;
r = blkid_probe_lookup_value(b, "PART_ENTRY_OFFSET", &v, NULL);
- if (r != 0) {
- r = errno ? -errno : -EIO;
- return log_error_errno(r, "Failed to probe partition offset \"%s\": %m", p);
- }
+ if (r != 0)
+ return log_error_errno(errno ?: EIO, "Failed to probe partition offset \"%s\": %m", p);
r = safe_atou64(v, &pstart);
if (r < 0)
return log_error_errno(r, "Failed to parse PART_ENTRY_OFFSET field.");
errno = 0;
r = blkid_probe_lookup_value(b, "PART_ENTRY_SIZE", &v, NULL);
- if (r != 0) {
- r = errno ? -errno : -EIO;
- return log_error_errno(r, "Failed to probe partition size \"%s\": %m", p);
- }
+ if (r != 0)
+ return log_error_errno(errno ?: EIO, "Failed to probe partition size \"%s\": %m", p);
r = safe_atou64(v, &psize);
if (r < 0)
return log_error_errno(r, "Failed to parse PART_ENTRY_SIZE field.");
@@ -255,7 +237,7 @@ static int find_esp(uint32_t *part, uint64_t *pstart, uint64_t *psize, sd_id128_
if (!arg_path)
return log_oom();
- log_info("Using EFI System Parition at %s.", path);
+ log_info("Using EFI System Partition at %s.", path);
return 0;
}
@@ -476,16 +458,16 @@ static int compare_version(const char *a, const char *b) {
return strverscmp(a, b);
}
-static int version_check(int fd, const char *from, const char *to) {
+static int version_check(int fd_from, const char *from, int fd_to, const char *to) {
_cleanup_free_ char *a = NULL, *b = NULL;
- _cleanup_close_ int fd2 = -1;
int r;
- assert(fd >= 0);
+ assert(fd_from >= 0);
assert(from);
+ assert(fd_to >= 0);
assert(to);
- r = get_file_version(fd, &a);
+ r = get_file_version(fd_from, &a);
if (r < 0)
return r;
if (r == 0) {
@@ -493,15 +475,7 @@ static int version_check(int fd, const char *from, const char *to) {
return -EINVAL;
}
- fd2 = open(to, O_RDONLY|O_CLOEXEC);
- if (fd2 < 0) {
- if (errno == ENOENT)
- return 0;
-
- return log_error_errno(errno, "Failed to open \"%s\" for reading: %m", to);
- }
-
- r = get_file_version(fd2, &b);
+ r = get_file_version(fd_to, &b);
if (r < 0)
return r;
if (r == 0 || compare_product(a, b) != 0) {
@@ -517,90 +491,59 @@ static int version_check(int fd, const char *from, const char *to) {
return 0;
}
-static int copy_file(const char *from, const char *to, bool force) {
- _cleanup_fclose_ FILE *f = NULL, *g = NULL;
- char *p;
+static int copy_file_with_version_check(const char *from, const char *to, bool force) {
+ _cleanup_close_ int fd_from = -1, fd_to = -1;
+ _cleanup_free_ char *t = NULL;
int r;
- struct timespec t[2];
- struct stat st;
- assert(from);
- assert(to);
-
- f = fopen(from, "re");
- if (!f)
+ fd_from = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
+ if (fd_from < 0)
return log_error_errno(errno, "Failed to open \"%s\" for reading: %m", from);
if (!force) {
- /* If this is an update, then let's compare versions first */
- r = version_check(fileno(f), from, to);
- if (r < 0)
- return r;
- }
-
- p = strjoina(to, "~");
- g = fopen(p, "wxe");
- if (!g) {
- /* Directory doesn't exist yet? Then let's skip this... */
- if (!force && errno == ENOENT)
- return 0;
-
- return log_error_errno(errno, "Failed to open \"%s\" for writing: %m", to);
- }
+ fd_to = open(to, O_RDONLY|O_CLOEXEC|O_NOCTTY);
+ if (fd_to < 0) {
+ if (errno != -ENOENT)
+ return log_error_errno(errno, "Failed to open \"%s\" for reading: %m", to);
+ } else {
+ r = version_check(fd_from, from, fd_to, to);
+ if (r < 0)
+ return r;
- rewind(f);
- do {
- size_t k;
- uint8_t buf[32*1024];
+ if (lseek(fd_from, 0, SEEK_SET) == (off_t) -1)
+ return log_error_errno(errno, "Failed to seek in \%s\": %m", from);
- k = fread(buf, 1, sizeof(buf), f);
- if (ferror(f)) {
- r = log_error_errno(EIO, "Failed to read \"%s\": %m", from);
- goto error;
+ fd_to = safe_close(fd_to);
}
+ }
- if (k == 0)
- break;
-
- fwrite(buf, 1, k, g);
- if (ferror(g)) {
- r = log_error_errno(EIO, "Failed to write \"%s\": %m", to);
- goto error;
- }
- } while (!feof(f));
+ r = tempfn_random(to, NULL, &t);
+ if (r < 0)
+ return log_oom();
- r = fflush_and_check(g);
- if (r < 0) {
- log_error_errno(r, "Failed to write \"%s\": %m", to);
- goto error;
+ RUN_WITH_UMASK(0000) {
+ fd_to = open(t, O_WRONLY|O_CREAT|O_CLOEXEC|O_EXCL|O_NOFOLLOW, 0644);
+ if (fd_to < 0)
+ return log_error_errno(errno, "Failed to open \"%s\" for writing: %m", t);
}
- r = fstat(fileno(f), &st);
+ r = copy_bytes(fd_from, fd_to, (uint64_t) -1, COPY_REFLINK);
if (r < 0) {
- r = log_error_errno(errno, "Failed to get file timestamps of \"%s\": %m", from);
- goto error;
+ unlink(t);
+ return log_error_errno(errno, "Failed to copy data from \"%s\" to \"%s\": %m", from, t);
}
- t[0] = st.st_atim;
- t[1] = st.st_mtim;
+ (void) copy_times(fd_from, fd_to);
- r = futimens(fileno(g), t);
+ r = renameat(AT_FDCWD, t, AT_FDCWD, to);
if (r < 0) {
- r = log_error_errno(errno, "Failed to set file timestamps on \"%s\": %m", p);
- goto error;
- }
-
- if (rename(p, to) < 0) {
- r = log_error_errno(errno, "Failed to rename \"%s\" to \"%s\": %m", p, to);
- goto error;
+ (void) unlink_noerrno(t);
+ return log_error_errno(errno, "Failed to rename \"%s\" to \"%s\": %m", t, to);
}
log_info("Copied \"%s\" to \"%s\".", from, to);
- return 0;
-error:
- (void) unlink(p);
- return r;
+ return 0;
}
static int mkdir_one(const char *prefix, const char *suffix) {
@@ -644,7 +587,7 @@ static int copy_one_file(const char *esp_path, const char *name, bool force) {
p = strjoina(BOOTLIBDIR "/", name);
q = strjoina(esp_path, "/EFI/systemd/", name);
- r = copy_file(p, q, force);
+ r = copy_file_with_version_check(p, q, force);
if (startswith(name, "systemd-boot")) {
int k;
@@ -654,7 +597,7 @@ static int copy_one_file(const char *esp_path, const char *name, bool force) {
v = strjoina(esp_path, "/EFI/BOOT/BOOT", name + strlen("systemd-boot"));
ascii_strupper(strrchr(v, '/') + 1);
- k = copy_file(p, v, force);
+ k = copy_file_with_version_check(p, v, force);
if (k < 0 && r == 0)
r = k;
}
@@ -950,20 +893,31 @@ static int remove_variables(sd_id128_t uuid, const char *path, bool in_order) {
static int install_loader_config(const char *esp_path) {
- _cleanup_fclose_ FILE *f = NULL;
char machine_string[SD_ID128_STRING_MAX];
+ _cleanup_(unlink_and_freep) char *t = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
sd_id128_t machine_id;
const char *p;
- int r;
+ int r, fd;
r = sd_id128_get_machine(&machine_id);
if (r < 0)
return log_error_errno(r, "Failed to get machine did: %m");
p = strjoina(esp_path, "/loader/loader.conf");
- f = fopen(p, "wxe");
- if (!f)
- return log_error_errno(errno, "Failed to open loader.conf for writing: %m");
+
+ if (access(p, F_OK) >= 0) /* Silently skip creation if the file already exists (early check) */
+ return 0;
+
+ fd = open_tmpfile_linkable(p, O_WRONLY|O_CLOEXEC, &t);
+ if (fd < 0)
+ return log_error_errno(fd, "Failed to open \"%s\" for writing: %m", p);
+
+ f = fdopen(fd, "we");
+ if (!f) {
+ safe_close(fd);
+ return log_oom();
+ }
fprintf(f, "#timeout 3\n");
fprintf(f, "default %s-*\n", sd_id128_to_string(machine_id, machine_string));
@@ -972,7 +926,15 @@ static int install_loader_config(const char *esp_path) {
if (r < 0)
return log_error_errno(r, "Failed to write \"%s\": %m", p);
- return 0;
+ r = link_tmpfile(fd, t, p);
+ if (r == -EEXIST)
+ return 0; /* Silently skip creation if the file exists now (recheck) */
+ if (r < 0)
+ return log_error_errno(r, "Failed to move \"%s\" into place: %m", p);
+
+ t = mfree(t);
+
+ return 1;
}
static int help(int argc, char *argv[], void *userdata) {
diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c
index 30c1ead1aa..681e783f2e 100644
--- a/src/boot/efi/boot.c
+++ b/src/boot/efi/boot.c
@@ -1482,7 +1482,7 @@ static VOID config_entry_add_osx(Config *config) {
root = LibOpenRoot(handles[i]);
if (!root)
continue;
- found = config_entry_add_loader_auto(config, handles[i], root, NULL, L"auto-osx", 'a', L"OS X",
+ found = config_entry_add_loader_auto(config, handles[i], root, NULL, L"auto-osx", 'a', L"macOS",
L"\\System\\Library\\CoreServices\\boot.efi");
uefi_call_wrapper(root->Close, 1, root);
if (found)
@@ -1647,7 +1647,7 @@ static EFI_STATUS image_start(EFI_HANDLE parent_image, const Config *config, con
loaded_image->LoadOptionsSize = (StrLen(loaded_image->LoadOptions)+1) * sizeof(CHAR16);
#ifdef SD_BOOT_LOG_TPM
- /* Try to log any options to the TPM, escpecially to catch manually edited options */
+ /* Try to log any options to the TPM, especially to catch manually edited options */
err = tpm_log_event(SD_TPM_PCR,
(EFI_PHYSICAL_ADDRESS) loaded_image->LoadOptions,
loaded_image->LoadOptionsSize, loaded_image->LoadOptions);
@@ -1787,7 +1787,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
config_title_generate(&config);
- /* select entry by configured pattern or EFI LoaderDefaultEntry= variable*/
+ /* select entry by configured pattern or EFI LoaderDefaultEntry= variable */
config_default_entry_select(&config);
/* if no configured entry to select from was found, enable the menu */
diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c
index 1e250f34f4..b7d5d3cdae 100644
--- a/src/boot/efi/stub.c
+++ b/src/boot/efi/stub.c
@@ -87,7 +87,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
cmdline_len = szs[0];
/* if we are not in secure boot mode, accept a custom command line and replace the built-in one */
- if (!secure && loaded_image->LoadOptionsSize > 0) {
+ if (!secure && loaded_image->LoadOptionsSize > 0 && *(CHAR16 *)loaded_image->LoadOptions != 0) {
CHAR16 *options;
CHAR8 *line;
UINTN i;
@@ -100,7 +100,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
cmdline = line;
#ifdef SD_BOOT_LOG_TPM
- /* Try to log any options to the TPM, escpecially manually edited options */
+ /* Try to log any options to the TPM, especially manually edited options */
err = tpm_log_event(SD_TPM_PCR,
(EFI_PHYSICAL_ADDRESS) loaded_image->LoadOptions,
loaded_image->LoadOptionsSize, loaded_image->LoadOptions);
diff --git a/src/cgls/cgls.c b/src/cgls/cgls.c
index adf488e8e1..1b746a0e13 100644
--- a/src/cgls/cgls.c
+++ b/src/cgls/cgls.c
@@ -26,7 +26,6 @@
#include "sd-bus.h"
#include "alloc-util.h"
-#include "bus-error.h"
#include "bus-util.h"
#include "cgroup-show.h"
#include "cgroup-util.h"
@@ -35,12 +34,21 @@
#include "output-mode.h"
#include "pager.h"
#include "path-util.h"
+#include "strv.h"
#include "unit-name.h"
#include "util.h"
static bool arg_no_pager = false;
static bool arg_kernel_threads = false;
static bool arg_all = false;
+
+static enum {
+ SHOW_UNIT_NONE,
+ SHOW_UNIT_SYSTEM,
+ SHOW_UNIT_USER,
+} arg_show_unit = SHOW_UNIT_NONE;
+static char **arg_names = NULL;
+
static int arg_full = -1;
static char* arg_machine = NULL;
@@ -51,6 +59,8 @@ static void help(void) {
" --version Show package version\n"
" --no-pager Do not pipe output into a pager\n"
" -a --all Show all groups, including empty\n"
+ " -u --unit Show the subtrees of specifified system units\n"
+ " --user-unit Show the subtrees of specifified user units\n"
" -l --full Do not ellipsize output\n"
" -k Include kernel threads in output\n"
" -M --machine= Show container\n"
@@ -62,15 +72,18 @@ static int parse_argv(int argc, char *argv[]) {
enum {
ARG_NO_PAGER = 0x100,
ARG_VERSION,
+ ARG_USER_UNIT,
};
static const struct option options[] = {
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, ARG_VERSION },
- { "no-pager", no_argument, NULL, ARG_NO_PAGER },
- { "all", no_argument, NULL, 'a' },
- { "full", no_argument, NULL, 'l' },
- { "machine", required_argument, NULL, 'M' },
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, ARG_VERSION },
+ { "no-pager", no_argument, NULL, ARG_NO_PAGER },
+ { "all", no_argument, NULL, 'a' },
+ { "full", no_argument, NULL, 'l' },
+ { "machine", required_argument, NULL, 'M' },
+ { "unit", optional_argument, NULL, 'u' },
+ { "user-unit", optional_argument, NULL, ARG_USER_UNIT },
{}
};
@@ -79,7 +92,7 @@ static int parse_argv(int argc, char *argv[]) {
assert(argc >= 1);
assert(argv);
- while ((c = getopt_long(argc, argv, "hkalM:", options, NULL)) >= 0)
+ while ((c = getopt_long(argc, argv, "-hkalM:u::", options, NULL)) >= 0)
switch (c) {
@@ -98,6 +111,24 @@ static int parse_argv(int argc, char *argv[]) {
arg_all = true;
break;
+ case 'u':
+ arg_show_unit = SHOW_UNIT_SYSTEM;
+ if (strv_push(&arg_names, optarg) < 0) /* push optarg if not empty */
+ return log_oom();
+ break;
+
+ case ARG_USER_UNIT:
+ arg_show_unit = SHOW_UNIT_USER;
+ if (strv_push(&arg_names, optarg) < 0) /* push optarg if not empty */
+ return log_oom();
+ break;
+
+ case 1:
+ /* positional argument */
+ if (strv_push(&arg_names, optarg) < 0)
+ return log_oom();
+ break;
+
case 'l':
arg_full = true;
break;
@@ -117,56 +148,17 @@ static int parse_argv(int argc, char *argv[]) {
assert_not_reached("Unhandled option");
}
- return 1;
-}
-
-static int get_cgroup_root(char **ret) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
- _cleanup_free_ char *unit = NULL, *path = NULL;
- const char *m;
- int r;
-
- if (!arg_machine) {
- r = cg_get_root_path(ret);
- if (r == -ENOMEDIUM)
- return log_error_errno(r, "Failed to get root control group path: No cgroup filesystem mounted on /sys/fs/cgroup");
- else if (r < 0)
- return log_error_errno(r, "Failed to get root control group path: %m");
-
- return 0;
+ if (arg_machine && arg_show_unit != SHOW_UNIT_NONE) {
+ log_error("Cannot combine --unit or --user-unit with --machine=.");
+ return -EINVAL;
}
- m = strjoina("/run/systemd/machines/", arg_machine);
- r = parse_env_file(m, NEWLINE, "SCOPE", &unit, NULL);
- if (r < 0)
- return log_error_errno(r, "Failed to load machine data: %m");
-
- path = unit_dbus_path_from_name(unit);
- if (!path)
- return log_oom();
-
- r = bus_connect_transport_systemd(BUS_TRANSPORT_LOCAL, NULL, false, &bus);
- if (r < 0)
- return log_error_errno(r, "Failed to create bus connection: %m");
-
- r = sd_bus_get_property_string(
- bus,
- "org.freedesktop.systemd1",
- path,
- unit_dbus_interface_from_name(unit),
- "ControlGroup",
- &error,
- ret);
- if (r < 0)
- return log_error_errno(r, "Failed to query unit control group path: %s", bus_error_message(&error, r));
-
- return 0;
+ return 1;
}
static void show_cg_info(const char *controller, const char *path) {
- if (cg_all_unified() <= 0 && controller && !streq(controller, SYSTEMD_CGROUP_CONTROLLER))
+ if (cg_all_unified() == 0 && controller && !streq(controller, SYSTEMD_CGROUP_CONTROLLER))
printf("Controller %s; ", controller);
printf("Control group %s:\n", isempty(path) ? "/" : path);
@@ -194,36 +186,70 @@ int main(int argc, char *argv[]) {
(arg_full > 0) * OUTPUT_FULL_WIDTH |
arg_kernel_threads * OUTPUT_KERNEL_THREADS;
- if (optind < argc) {
+ if (arg_names) {
+ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
_cleanup_free_ char *root = NULL;
- int i;
+ char **name;
- r = get_cgroup_root(&root);
- if (r < 0)
- goto finish;
-
- for (i = optind; i < argc; i++) {
+ STRV_FOREACH(name, arg_names) {
int q;
- if (path_startswith(argv[i], "/sys/fs/cgroup")) {
+ if (arg_show_unit != SHOW_UNIT_NONE) {
+ /* Command line arguments are unit names */
+ _cleanup_free_ char *cgroup = NULL;
+
+ if (!bus) {
+ /* Connect to the bus only if necessary */
+ r = bus_connect_transport_systemd(BUS_TRANSPORT_LOCAL, NULL,
+ arg_show_unit == SHOW_UNIT_USER,
+ &bus);
+ if (r < 0) {
+ log_error_errno(r, "Failed to create bus connection: %m");
+ goto finish;
+ }
+ }
+
+ q = show_cgroup_get_unit_path_and_warn(bus, *name, &cgroup);
+ if (q < 0)
+ goto failed;
+
+ if (isempty(cgroup)) {
+ log_warning("Unit %s not found.", *name);
+ q = -ENOENT;
+ goto failed;
+ }
+
+ printf("Unit %s (%s):\n", *name, cgroup);
+ fflush(stdout);
+
+ q = show_cgroup_by_path(cgroup, NULL, 0, output_flags);
- printf("Directory %s:\n", argv[i]);
+ } else if (path_startswith(*name, "/sys/fs/cgroup")) {
+
+ printf("Directory %s:\n", *name);
fflush(stdout);
- q = show_cgroup_by_path(argv[i], NULL, 0, output_flags);
+ q = show_cgroup_by_path(*name, NULL, 0, output_flags);
} else {
_cleanup_free_ char *c = NULL, *p = NULL, *j = NULL;
const char *controller, *path;
- r = cg_split_spec(argv[i], &c, &p);
- if (r < 0) {
- log_error_errno(r, "Failed to split argument %s: %m", argv[i]);
- goto finish;
+ if (!root) {
+ /* Query root only if needed, treat error as fatal */
+ r = show_cgroup_get_path_and_warn(arg_machine, NULL, &root);
+ if (r < 0)
+ goto finish;
+ }
+
+ q = cg_split_spec(*name, &c, &p);
+ if (q < 0) {
+ log_error_errno(q, "Failed to split argument %s: %m", *name);
+ goto failed;
}
controller = c ?: SYSTEMD_CGROUP_CONTROLLER;
if (p) {
- j = strjoin(root, "/", p, NULL);
+ j = strjoin(root, "/", p);
if (!j) {
r = log_oom();
goto finish;
@@ -239,7 +265,8 @@ int main(int argc, char *argv[]) {
q = show_cgroup(controller, path, NULL, 0, output_flags);
}
- if (q < 0)
+ failed:
+ if (q < 0 && r >= 0)
r = q;
}
@@ -267,7 +294,7 @@ int main(int argc, char *argv[]) {
if (!done) {
_cleanup_free_ char *root = NULL;
- r = get_cgroup_root(&root);
+ r = show_cgroup_get_path_and_warn(arg_machine, NULL, &root);
if (r < 0)
goto finish;
@@ -283,6 +310,7 @@ int main(int argc, char *argv[]) {
finish:
pager_close();
+ free(arg_names); /* don't free the strings */
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c
index aba17c9829..67f3a99860 100644
--- a/src/cgtop/cgtop.c
+++ b/src/cgtop/cgtop.c
@@ -31,6 +31,7 @@
#include "alloc-util.h"
#include "bus-error.h"
#include "bus-util.h"
+#include "cgroup-show.h"
#include "cgroup-util.h"
#include "fd-util.h"
#include "fileio.h"
@@ -117,7 +118,7 @@ static const char *maybe_format_bytes(char *buf, size_t l, bool is_valid, uint64
if (!is_valid)
return "-";
if (arg_raw) {
- snprintf(buf, l, "%jd", t);
+ snprintf(buf, l, "%" PRIu64, t);
return buf;
}
return format_bytes(buf, l, t);
@@ -132,12 +133,16 @@ static int process(
Group **ret) {
Group *g;
- int r;
+ int r, all_unified;
assert(controller);
assert(path);
assert(a);
+ all_unified = cg_all_unified();
+ if (all_unified < 0)
+ return all_unified;
+
g = hashmap_get(a, path);
if (!g) {
g = hashmap_get(b, path);
@@ -213,7 +218,7 @@ static int process(
uint64_t new_usage;
nsec_t timestamp;
- if (cg_all_unified() > 0) {
+ if (all_unified) {
const char *keys[] = { "usage_usec", NULL };
_cleanup_free_ char *val = NULL;
@@ -273,10 +278,10 @@ static int process(
} else if (streq(controller, "memory")) {
_cleanup_free_ char *p = NULL, *v = NULL;
- if (cg_all_unified() <= 0)
- r = cg_get_path(controller, path, "memory.usage_in_bytes", &p);
- else
+ if (all_unified)
r = cg_get_path(controller, path, "memory.current", &p);
+ else
+ r = cg_get_path(controller, path, "memory.usage_in_bytes", &p);
if (r < 0)
return r;
@@ -293,15 +298,14 @@ static int process(
if (g->memory > 0)
g->memory_valid = true;
- } else if ((streq(controller, "io") && cg_all_unified() > 0) ||
- (streq(controller, "blkio") && cg_all_unified() <= 0)) {
+ } else if ((streq(controller, "io") && all_unified) ||
+ (streq(controller, "blkio") && !all_unified)) {
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *p = NULL;
- bool unified = cg_all_unified() > 0;
uint64_t wr = 0, rd = 0;
nsec_t timestamp;
- r = cg_get_path(controller, path, unified ? "io.stat" : "blkio.io_service_bytes", &p);
+ r = cg_get_path(controller, path, all_unified ? "io.stat" : "blkio.io_service_bytes", &p);
if (r < 0)
return r;
@@ -324,7 +328,7 @@ static int process(
l += strcspn(l, WHITESPACE);
l += strspn(l, WHITESPACE);
- if (unified) {
+ if (all_unified) {
while (!isempty(l)) {
if (sscanf(l, "rbytes=%" SCNu64, &k))
rd += k;
@@ -431,7 +435,7 @@ static int refresh_one(
if (r == 0)
break;
- p = strjoin(path, "/", fn, NULL);
+ p = strjoin(path, "/", fn);
if (!p)
return -ENOMEM;
@@ -862,13 +866,9 @@ static int parse_argv(int argc, char *argv[]) {
assert_not_reached("Unhandled option");
}
- if (optind == argc-1) {
- if (arg_machine) {
- log_error("Specifying a control group path together with the -M option is not allowed");
- return -EINVAL;
- }
+ if (optind == argc - 1)
arg_root = argv[optind];
- } else if (optind < argc) {
+ else if (optind < argc) {
log_error("Too many arguments.");
return -EINVAL;
}
@@ -890,59 +890,6 @@ static const char* counting_what(void) {
return "userspace processes (excl. kernel)";
}
-static int get_cgroup_root(char **ret) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
- _cleanup_free_ char *unit = NULL, *path = NULL;
- const char *m;
- int r;
-
- if (arg_root) {
- char *aux;
-
- aux = strdup(arg_root);
- if (!aux)
- return log_oom();
-
- *ret = aux;
- return 0;
- }
-
- if (!arg_machine) {
- r = cg_get_root_path(ret);
- if (r < 0)
- return log_error_errno(r, "Failed to get root control group path: %m");
-
- return 0;
- }
-
- m = strjoina("/run/systemd/machines/", arg_machine);
- r = parse_env_file(m, NEWLINE, "SCOPE", &unit, NULL);
- if (r < 0)
- return log_error_errno(r, "Failed to load machine data: %m");
-
- path = unit_dbus_path_from_name(unit);
- if (!path)
- return log_oom();
-
- r = bus_connect_transport_systemd(BUS_TRANSPORT_LOCAL, NULL, false, &bus);
- if (r < 0)
- return log_error_errno(r, "Failed to create bus connection: %m");
-
- r = sd_bus_get_property_string(
- bus,
- "org.freedesktop.systemd1",
- path,
- unit_dbus_interface_from_name(unit),
- "ControlGroup",
- &error,
- ret);
- if (r < 0)
- return log_error_errno(r, "Failed to query unit control group path: %s", bus_error_message(&error, r));
-
- return 0;
-}
-
int main(int argc, char *argv[]) {
int r;
Hashmap *a = NULL, *b = NULL;
@@ -967,11 +914,12 @@ int main(int argc, char *argv[]) {
if (r <= 0)
goto finish;
- r = get_cgroup_root(&root);
+ r = show_cgroup_get_path_and_warn(arg_machine, arg_root, &root);
if (r < 0) {
log_error_errno(r, "Failed to get root control group path: %m");
goto finish;
- }
+ } else
+ log_debug("Cgroup path: %s", root);
a = hashmap_new(&string_hash_ops);
b = hashmap_new(&string_hash_ops);
diff --git a/src/core/automount.c b/src/core/automount.c
index 7d7a0a6e46..ccc113b598 100644
--- a/src/core/automount.c
+++ b/src/core/automount.c
@@ -34,7 +34,7 @@
#include "bus-util.h"
#include "dbus-automount.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "io-util.h"
#include "label.h"
#include "mkdir.h"
@@ -101,17 +101,17 @@ static void unmount_autofs(Automount *a) {
a->pipe_event_source = sd_event_source_unref(a->pipe_event_source);
a->pipe_fd = safe_close(a->pipe_fd);
- /* If we reload/reexecute things we keep the mount point
- * around */
- if (a->where &&
- (UNIT(a)->manager->exit_code != MANAGER_RELOAD &&
- UNIT(a)->manager->exit_code != MANAGER_REEXECUTE)) {
+ /* If we reload/reexecute things we keep the mount point around */
+ if (!IN_SET(UNIT(a)->manager->exit_code, MANAGER_RELOAD, MANAGER_REEXECUTE)) {
+
automount_send_ready(a, a->tokens, -EHOSTDOWN);
automount_send_ready(a, a->expire_tokens, -EHOSTDOWN);
- r = repeat_unmount(a->where, MNT_DETACH);
- if (r < 0)
- log_error_errno(r, "Failed to unmount: %m");
+ if (a->where) {
+ r = repeat_unmount(a->where, MNT_DETACH);
+ if (r < 0)
+ log_error_errno(r, "Failed to unmount: %m");
+ }
}
}
@@ -186,6 +186,22 @@ static int automount_verify(Automount *a) {
return 0;
}
+static int automount_set_where(Automount *a) {
+ int r;
+
+ assert(a);
+
+ if (a->where)
+ return 0;
+
+ r = unit_name_to_path(UNIT(a)->id, &a->where);
+ if (r < 0)
+ return r;
+
+ path_kill_slashes(a->where);
+ return 1;
+}
+
static int automount_load(Unit *u) {
Automount *a = AUTOMOUNT(u);
int r;
@@ -201,13 +217,9 @@ static int automount_load(Unit *u) {
if (u->load_state == UNIT_LOADED) {
Unit *x;
- if (!a->where) {
- r = unit_name_to_path(u->id, &a->where);
- if (r < 0)
- return r;
- }
-
- path_kill_slashes(a->where);
+ r = automount_set_where(a);
+ if (r < 0)
+ return r;
r = unit_load_related_unit(u, ".mount", &x);
if (r < 0)
@@ -256,26 +268,30 @@ static int automount_coldplug(Unit *u) {
assert(a);
assert(a->state == AUTOMOUNT_DEAD);
- if (a->deserialized_state != a->state) {
+ if (a->deserialized_state == a->state)
+ return 0;
+
+ if (IN_SET(a->deserialized_state, AUTOMOUNT_WAITING, AUTOMOUNT_RUNNING)) {
+
+ r = automount_set_where(a);
+ if (r < 0)
+ return r;
r = open_dev_autofs(u->manager);
if (r < 0)
return r;
- if (a->deserialized_state == AUTOMOUNT_WAITING ||
- a->deserialized_state == AUTOMOUNT_RUNNING) {
- assert(a->pipe_fd >= 0);
+ assert(a->pipe_fd >= 0);
- r = sd_event_add_io(u->manager->event, &a->pipe_event_source, a->pipe_fd, EPOLLIN, automount_dispatch_io, u);
- if (r < 0)
- return r;
+ r = sd_event_add_io(u->manager->event, &a->pipe_event_source, a->pipe_fd, EPOLLIN, automount_dispatch_io, u);
+ if (r < 0)
+ return r;
- (void) sd_event_source_set_description(a->pipe_event_source, "automount-io");
- if (a->deserialized_state == AUTOMOUNT_RUNNING) {
- r = automount_start_expire(a);
- if (r < 0)
- log_unit_warning_errno(UNIT(a), r, "Failed to start expiration timer, ignoring: %m");
- }
+ (void) sd_event_source_set_description(a->pipe_event_source, "automount-io");
+ if (a->deserialized_state == AUTOMOUNT_RUNNING) {
+ r = automount_start_expire(a);
+ if (r < 0)
+ log_unit_warning_errno(UNIT(a), r, "Failed to start expiration timer, ignoring: %m");
}
automount_set_state(a, a->deserialized_state);
@@ -399,8 +415,11 @@ static int autofs_set_timeout(int dev_autofs_fd, int ioctl_fd, usec_t usec) {
init_autofs_dev_ioctl(&param);
param.ioctlfd = ioctl_fd;
- /* Convert to seconds, rounding up. */
- param.timeout.timeout = (usec + USEC_PER_SEC - 1) / USEC_PER_SEC;
+ if (usec == USEC_INFINITY)
+ param.timeout.timeout = 0;
+ else
+ /* Convert to seconds, rounding up. */
+ param.timeout.timeout = (usec + USEC_PER_SEC - 1) / USEC_PER_SEC;
if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT, &param) < 0)
return -errno;
@@ -733,6 +752,12 @@ static void automount_enter_runnning(Automount *a) {
assert(a);
+ /* If the user masked our unit in the meantime, fail */
+ if (UNIT(a)->load_state != UNIT_LOADED) {
+ log_unit_error(UNIT(a), "Suppressing automount event since unit is no longer loaded.");
+ goto fail;
+ }
+
/* We don't take mount requests anymore if we are supposed to
* shut down anyway */
if (unit_stop_pending(UNIT(a))) {
@@ -783,7 +808,7 @@ static int automount_start(Unit *u) {
assert(a);
assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED);
- if (path_is_mount_point(a->where, 0) > 0) {
+ if (path_is_mount_point(a->where, NULL, 0) > 0) {
log_unit_error(u, "Path %s is already a mount point, refusing start.", a->where);
return -EEXIST;
}
diff --git a/src/core/busname.c b/src/core/busname.c
index b96ec09e67..88b758eecb 100644
--- a/src/core/busname.c
+++ b/src/core/busname.c
@@ -27,7 +27,7 @@
#include "busname.h"
#include "dbus-busname.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "kdbus.h"
#include "parse-util.h"
#include "process-util.h"
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index 23a92f9651..774b832a63 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -287,14 +287,24 @@ static int lookup_block_device(const char *p, dev_t *dev) {
static int whitelist_device(const char *path, const char *node, const char *acc) {
char buf[2+DECIMAL_STR_MAX(dev_t)*2+2+4];
struct stat st;
+ bool ignore_notfound;
int r;
assert(path);
assert(acc);
+ if (node[0] == '-') {
+ /* Non-existent paths starting with "-" must be silently ignored */
+ node++;
+ ignore_notfound = true;
+ } else
+ ignore_notfound = false;
+
if (stat(node, &st) < 0) {
- log_warning("Couldn't stat device %s", node);
- return -errno;
+ if (errno == ENOENT && ignore_notfound)
+ return 0;
+
+ return log_warning_errno(errno, "Couldn't stat device %s: %m", node);
}
if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) {
@@ -849,8 +859,7 @@ static void cgroup_context_apply(Unit *u, CGroupMask mask, ManagerState state) {
if ((mask & CGROUP_MASK_MEMORY) && !is_root) {
if (cg_all_unified() > 0) {
- uint64_t max;
- uint64_t swap_max = CGROUP_LIMIT_MAX;
+ uint64_t max, swap_max = CGROUP_LIMIT_MAX;
if (cgroup_context_has_unified_memory_config(c)) {
max = c->memory_max;
@@ -914,8 +923,8 @@ static void cgroup_context_apply(Unit *u, CGroupMask mask, ManagerState state) {
"/dev/tty\0" "rwm\0"
"/dev/pts/ptmx\0" "rw\0" /* /dev/pts/ptmx may not be duplicated, but accessed */
/* Allow /run/systemd/inaccessible/{chr,blk} devices for mapping InaccessiblePaths */
- "/run/systemd/inaccessible/chr\0" "rwm\0"
- "/run/systemd/inaccessible/blk\0" "rwm\0";
+ "-/run/systemd/inaccessible/chr\0" "rwm\0"
+ "-/run/systemd/inaccessible/blk\0" "rwm\0";
const char *x, *y;
@@ -928,7 +937,7 @@ static void cgroup_context_apply(Unit *u, CGroupMask mask, ManagerState state) {
}
LIST_FOREACH(device_allow, a, c->device_allow) {
- char acc[4];
+ char acc[4], *val;
unsigned k = 0;
if (a->r)
@@ -945,10 +954,10 @@ static void cgroup_context_apply(Unit *u, CGroupMask mask, ManagerState state) {
if (startswith(a->path, "/dev/"))
whitelist_device(path, a->path, acc);
- else if (startswith(a->path, "block-"))
- whitelist_major(path, a->path + 6, 'b', acc);
- else if (startswith(a->path, "char-"))
- whitelist_major(path, a->path + 5, 'c', acc);
+ else if ((val = startswith(a->path, "block-")))
+ whitelist_major(path, val, 'b', acc);
+ else if ((val = startswith(a->path, "char-")))
+ whitelist_major(path, val, 'c', acc);
else
log_unit_debug(u, "Ignoring device %s while writing cgroup attribute.", a->path);
}
@@ -1201,9 +1210,10 @@ char *unit_default_cgroup_path(Unit *u) {
return NULL;
if (slice)
- return strjoin(u->manager->cgroup_root, "/", slice, "/", escaped, NULL);
+ return strjoin(u->manager->cgroup_root, "/", slice, "/",
+ escaped);
else
- return strjoin(u->manager->cgroup_root, "/", escaped, NULL);
+ return strjoin(u->manager->cgroup_root, "/", escaped);
}
int unit_set_cgroup_path(Unit *u, const char *path) {
@@ -1249,9 +1259,9 @@ int unit_watch_cgroup(Unit *u) {
return 0;
/* Only applies to the unified hierarchy */
- r = cg_unified(SYSTEMD_CGROUP_CONTROLLER);
+ r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
if (r < 0)
- return log_unit_error_errno(u, r, "Failed detect whether the unified hierarchy is used: %m");
+ return log_error_errno(r, "Failed to determine whether the name=systemd hierarchy is unified: %m");
if (r == 0)
return 0;
@@ -1643,7 +1653,7 @@ static int unit_watch_pids_in_path(Unit *u, const char *path) {
while ((r = cg_read_subgroup(d, &fn)) > 0) {
_cleanup_free_ char *p = NULL;
- p = strjoin(path, "/", fn, NULL);
+ p = strjoin(path, "/", fn);
free(fn);
if (!p)
@@ -1662,6 +1672,8 @@ static int unit_watch_pids_in_path(Unit *u, const char *path) {
}
int unit_watch_all_pids(Unit *u) {
+ int r;
+
assert(u);
/* Adds all PIDs from our cgroup to the set of PIDs we
@@ -1672,7 +1684,10 @@ int unit_watch_all_pids(Unit *u) {
if (!u->cgroup_path)
return -ENOENT;
- if (cg_unified(SYSTEMD_CGROUP_CONTROLLER) > 0) /* On unified we can use proper notifications */
+ r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
+ if (r < 0)
+ return r;
+ if (r > 0) /* On unified we can use proper notifications */
return 0;
return unit_watch_pids_in_path(u, u->cgroup_path);
@@ -1745,7 +1760,7 @@ static int on_cgroup_inotify_event(sd_event_source *s, int fd, uint32_t revents,
int manager_setup_cgroup(Manager *m) {
_cleanup_free_ char *path = NULL;
CGroupController c;
- int r, all_unified, systemd_unified;
+ int r, all_unified;
char *e;
assert(m);
@@ -1782,25 +1797,30 @@ int manager_setup_cgroup(Manager *m) {
if (r < 0)
return log_error_errno(r, "Cannot find cgroup mount point: %m");
- all_unified = cg_all_unified();
- systemd_unified = cg_unified(SYSTEMD_CGROUP_CONTROLLER);
-
- if (all_unified < 0 || systemd_unified < 0)
- return log_error_errno(all_unified < 0 ? all_unified : systemd_unified,
- "Couldn't determine if we are running in the unified hierarchy: %m");
+ r = cg_unified_flush();
+ if (r < 0)
+ return log_error_errno(r, "Couldn't determine if we are running in the unified hierarchy: %m");
- if (all_unified > 0)
+ all_unified = cg_all_unified();
+ if (r < 0)
+ return log_error_errno(r, "Couldn't determine whether we are in all unified mode: %m");
+ if (r > 0)
log_debug("Unified cgroup hierarchy is located at %s.", path);
- else if (systemd_unified > 0)
- log_debug("Unified cgroup hierarchy is located at %s. Controllers are on legacy hierarchies.", path);
- else
- log_debug("Using cgroup controller " SYSTEMD_CGROUP_CONTROLLER ". File system hierarchy is at %s.", path);
+ else {
+ r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
+ if (r < 0)
+ return log_error_errno(r, "Failed to determine whether systemd's own controller is in unified mode: %m");
+ if (r > 0)
+ log_debug("Unified cgroup hierarchy is located at %s. Controllers are on legacy hierarchies.", path);
+ else
+ log_debug("Using cgroup controller " SYSTEMD_CGROUP_CONTROLLER_LEGACY ". File system hierarchy is at %s.", path);
+ }
if (!m->test_run) {
const char *scope_path;
/* 3. Install agent */
- if (systemd_unified) {
+ if (cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) > 0) {
/* In the unified hierarchy we can get
* cgroup empty notifications via inotify. */
@@ -1986,10 +2006,13 @@ int unit_get_memory_current(Unit *u, uint64_t *ret) {
if ((u->cgroup_realized_mask & CGROUP_MASK_MEMORY) == 0)
return -ENODATA;
- if (cg_all_unified() <= 0)
- r = cg_get_attribute("memory", u->cgroup_path, "memory.usage_in_bytes", &v);
- else
+ r = cg_all_unified();
+ if (r < 0)
+ return r;
+ if (r > 0)
r = cg_get_attribute("memory", u->cgroup_path, "memory.current", &v);
+ else
+ r = cg_get_attribute("memory", u->cgroup_path, "memory.usage_in_bytes", &v);
if (r == -ENOENT)
return -ENODATA;
if (r < 0)
@@ -2031,7 +2054,10 @@ static int unit_get_cpu_usage_raw(Unit *u, nsec_t *ret) {
if (!u->cgroup_path)
return -ENODATA;
- if (cg_all_unified() > 0) {
+ r = cg_all_unified();
+ if (r < 0)
+ return r;
+ if (r > 0) {
const char *keys[] = { "usage_usec", NULL };
_cleanup_free_ char *val = NULL;
uint64_t us;
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
index 1a7f770db1..0454a28e12 100644
--- a/src/core/dbus-execute.c
+++ b/src/core/dbus-execute.c
@@ -34,6 +34,7 @@
#include "fileio.h"
#include "ioprio.h"
#include "missing.h"
+#include "mount-util.h"
#include "namespace.h"
#include "parse-util.h"
#include "path-util.h"
@@ -674,6 +675,49 @@ static int property_get_output_fdname(
return sd_bus_message_append(reply, "s", name);
}
+static int property_get_bind_paths(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+ ExecContext *c = userdata;
+ unsigned i;
+ bool ro;
+ int r;
+
+ assert(bus);
+ assert(c);
+ assert(property);
+ assert(reply);
+
+ ro = !!strstr(property, "ReadOnly");
+
+ r = sd_bus_message_open_container(reply, 'a', "(ssbt)");
+ if (r < 0)
+ return r;
+
+ for (i = 0; i < c->n_bind_mounts; i++) {
+
+ if (ro != c->bind_mounts[i].read_only)
+ continue;
+
+ r = sd_bus_message_append(
+ reply, "(ssbt)",
+ c->bind_mounts[i].source,
+ c->bind_mounts[i].destination,
+ c->bind_mounts[i].ignore_enoent,
+ c->bind_mounts[i].recursive ? (uint64_t) MS_REC : (uint64_t) 0);
+ if (r < 0)
+ return r;
+ }
+
+ return sd_bus_message_close_container(reply);
+}
+
const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -714,6 +758,7 @@ const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_PROPERTY("LimitRTTIMESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("WorkingDirectory", "s", property_get_working_directory, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("RootImage", "s", NULL, offsetof(ExecContext, root_image), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST),
@@ -781,6 +826,10 @@ const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_PROPERTY("RuntimeDirectory", "as", NULL, offsetof(ExecContext, runtime_directory), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("MemoryDenyWriteExecute", "b", bus_property_get_bool, offsetof(ExecContext, memory_deny_write_execute), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RestrictRealtime", "b", bus_property_get_bool, offsetof(ExecContext, restrict_realtime), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("RestrictNamespaces", "t", bus_property_get_ulong, offsetof(ExecContext, restrict_namespaces), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("BindPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("MountAPIVFS", "b", bus_property_get_bool, offsetof(ExecContext, mount_apivfs), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_VTABLE_END
};
@@ -1000,7 +1049,7 @@ int bus_exec_context_set_transient_property(
return 1;
- } else if (STR_IN_SET(name, "TTYPath", "RootDirectory")) {
+ } else if (STR_IN_SET(name, "TTYPath", "RootDirectory", "RootImage")) {
const char *s;
r = sd_bus_message_read(message, "s", &s);
@@ -1013,6 +1062,8 @@ int bus_exec_context_set_transient_property(
if (mode != UNIT_CHECK) {
if (streq(name, "TTYPath"))
r = free_and_strdup(&c->tty_path, s);
+ else if (streq(name, "RootImage"))
+ r = free_and_strdup(&c->root_image, s);
else {
assert(streq(name, "RootDirectory"));
r = free_and_strdup(&c->root_directory, s);
@@ -1160,7 +1211,7 @@ int bus_exec_context_set_transient_property(
"PrivateTmp", "PrivateDevices", "PrivateNetwork", "PrivateUsers",
"NoNewPrivileges", "SyslogLevelPrefix", "MemoryDenyWriteExecute",
"RestrictRealtime", "DynamicUser", "RemoveIPC", "ProtectKernelTunables",
- "ProtectKernelModules", "ProtectControlGroups")) {
+ "ProtectKernelModules", "ProtectControlGroups", "MountAPIVFS")) {
int b;
r = sd_bus_message_read(message, "b", &b);
@@ -1200,6 +1251,8 @@ int bus_exec_context_set_transient_property(
c->protect_kernel_modules = b;
else if (streq(name, "ProtectControlGroups"))
c->protect_control_groups = b;
+ else if (streq(name, "MountAPIVFS"))
+ c->mount_apivfs = b;
unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, yes_no(b));
}
@@ -1335,7 +1388,7 @@ int bus_exec_context_set_transient_property(
_cleanup_free_ char *joined = NULL;
_cleanup_fclose_ FILE *f = NULL;
- _cleanup_free_ char **l = NULL;
+ _cleanup_strv_free_ char **l = NULL;
size_t size = 0;
char **i;
@@ -1362,13 +1415,13 @@ int bus_exec_context_set_transient_property(
if (r < 0)
return r;
- if (!isempty(path) && !path_is_absolute(path))
- return sd_bus_error_set_errnof(error, EINVAL, "Path %s is not absolute.", path);
+ if (!path_is_absolute(path))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path);
if (mode != UNIT_CHECK) {
char *buf = NULL;
- buf = strjoin(b ? "-" : "", path, NULL);
+ buf = strjoin(b ? "-" : "", path);
if (!buf)
return -ENOMEM;
@@ -1448,12 +1501,15 @@ int bus_exec_context_set_transient_property(
return r;
STRV_FOREACH(p, l) {
- int offset;
- if (!utf8_is_valid(*p))
+ const char *i = *p;
+ size_t offset;
+
+ if (!utf8_is_valid(i))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
- offset = **p == '-';
- if (!path_is_absolute(*p + offset))
+ offset = i[0] == '-';
+ offset += i[offset] == '+';
+ if (!path_is_absolute(i + offset))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
}
@@ -1472,7 +1528,6 @@ int bus_exec_context_set_transient_property(
unit_write_drop_in_private_format(u, mode, name, "%s=", name);
} else {
r = strv_extend_strv(dirs, l, true);
-
if (r < 0)
return -ENOMEM;
@@ -1591,7 +1646,108 @@ int bus_exec_context_set_transient_property(
}
return 1;
+ } else if (streq(name, "RestrictNamespaces")) {
+ uint64_t flags;
+
+ r = sd_bus_message_read(message, "t", &flags);
+ if (r < 0)
+ return r;
+ if ((flags & NAMESPACE_FLAGS_ALL) != flags)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown namespace types");
+
+ if (mode != UNIT_CHECK) {
+ _cleanup_free_ char *s = NULL;
+
+ r = namespace_flag_to_string_many(flags, &s);
+ if (r < 0)
+ return r;
+
+ c->restrict_namespaces = flags;
+ unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s);
+ }
+
+ return 1;
+ } else if (streq(name, "MountFlags")) {
+ uint64_t flags;
+
+ r = sd_bus_message_read(message, "t", &flags);
+ if (r < 0)
+ return r;
+ if (!IN_SET(flags, 0, MS_SHARED, MS_PRIVATE, MS_SLAVE))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount propagation flags");
+
+ if (mode != UNIT_CHECK) {
+ c->mount_flags = flags;
+
+ unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, mount_propagation_flags_to_string(flags));
+ }
+
+ return 1;
+ } else if (STR_IN_SET(name, "BindPaths", "BindReadOnlyPaths")) {
+ unsigned empty = true;
+
+ r = sd_bus_message_enter_container(message, 'a', "(ssbt)");
+ if (r < 0)
+ return r;
+
+ while ((r = sd_bus_message_enter_container(message, 'r', "ssbt")) > 0) {
+ const char *source, *destination;
+ int ignore_enoent;
+ uint64_t mount_flags;
+
+ r = sd_bus_message_read(message, "ssbt", &source, &destination, &ignore_enoent, &mount_flags);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_exit_container(message);
+ if (r < 0)
+ return r;
+ if (!path_is_absolute(source))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not absolute.", source);
+ if (!path_is_absolute(destination))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not absolute.", destination);
+ if (!IN_SET(mount_flags, 0, MS_REC))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount flags.");
+
+ if (mode != UNIT_CHECK) {
+ r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
+ &(BindMount) {
+ .source = strdup(source),
+ .destination = strdup(destination),
+ .read_only = !!strstr(name, "ReadOnly"),
+ .recursive = !!(mount_flags & MS_REC),
+ .ignore_enoent = ignore_enoent,
+ });
+ if (r < 0)
+ return r;
+
+ unit_write_drop_in_private_format(
+ u, mode, name,
+ "%s=%s%s:%s:%s",
+ name,
+ ignore_enoent ? "-" : "",
+ source,
+ destination,
+ (mount_flags & MS_REC) ? "rbind" : "norbind");
+ }
+
+ empty = false;
+ }
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_exit_container(message);
+ if (r < 0)
+ return r;
+
+ if (empty) {
+ bind_mount_free_many(c->bind_mounts, c->n_bind_mounts);
+ c->bind_mounts = NULL;
+ c->n_bind_mounts = 0;
+ }
+
+ return 1;
}
ri = rlimit_from_string(name);
diff --git a/src/core/dbus-job.c b/src/core/dbus-job.c
index ccf7453d47..effc45db45 100644
--- a/src/core/dbus-job.c
+++ b/src/core/dbus-job.c
@@ -65,7 +65,7 @@ int bus_job_method_cancel(sd_bus_message *message, void *userdata, sd_bus_error
return r;
/* Access is granted to the job owner */
- if (!sd_bus_track_contains(j->clients, sd_bus_message_get_sender(message))) {
+ if (!sd_bus_track_contains(j->bus_track, sd_bus_message_get_sender(message))) {
/* And for everybody else consult PolicyKit */
r = bus_verify_manage_units_async(j->unit->manager, message, error);
@@ -80,9 +80,61 @@ int bus_job_method_cancel(sd_bus_message *message, void *userdata, sd_bus_error
return sd_bus_reply_method_return(message, NULL);
}
+int bus_job_method_get_waiting_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ _cleanup_free_ Job **list = NULL;
+ Job *j = userdata;
+ int r, i, n;
+
+ if (strstr(sd_bus_message_get_member(message), "After"))
+ n = job_get_after(j, &list);
+ else
+ n = job_get_before(j, &list);
+ if (n < 0)
+ return n;
+
+ r = sd_bus_message_new_method_return(message, &reply);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
+ if (r < 0)
+ return r;
+
+ for (i = 0; i < n; i ++) {
+ _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
+
+ job_path = job_dbus_path(list[i]);
+ if (!job_path)
+ return -ENOMEM;
+
+ unit_path = unit_dbus_path(list[i]->unit);
+ if (!unit_path)
+ return -ENOMEM;
+
+ r = sd_bus_message_append(reply, "(usssoo)",
+ list[i]->id,
+ list[i]->unit->id,
+ job_type_to_string(list[i]->type),
+ job_state_to_string(list[i]->state),
+ job_path,
+ unit_path);
+ if (r < 0)
+ return r;
+ }
+
+ r = sd_bus_message_close_container(reply);
+ if (r < 0)
+ return r;
+
+ return sd_bus_send(NULL, reply, NULL);
+}
+
const sd_bus_vtable bus_job_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_METHOD("Cancel", NULL, NULL, bus_job_method_cancel, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetAfter", NULL, "a(usssoo)", bus_job_method_get_waiting_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetBefore", NULL, "a(usssoo)", bus_job_method_get_waiting_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_PROPERTY("Id", "u", NULL, offsetof(Job, id), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Unit", "(so)", property_get_unit, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("JobType", "s", property_get_type, offsetof(Job, type), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -143,7 +195,7 @@ void bus_job_send_change_signal(Job *j) {
j->in_dbus_queue = false;
}
- r = bus_foreach_bus(j->manager, j->clients, j->sent_dbus_new_signal ? send_changed_signal : send_new_signal, j);
+ r = bus_foreach_bus(j->manager, j->bus_track, j->sent_dbus_new_signal ? send_changed_signal : send_new_signal, j);
if (r < 0)
log_debug_errno(r, "Failed to send job change signal for %u: %m", j->id);
@@ -187,7 +239,70 @@ void bus_job_send_removed_signal(Job *j) {
if (!j->sent_dbus_new_signal)
bus_job_send_change_signal(j);
- r = bus_foreach_bus(j->manager, j->clients, send_removed_signal, j);
+ r = bus_foreach_bus(j->manager, j->bus_track, send_removed_signal, j);
if (r < 0)
log_debug_errno(r, "Failed to send job remove signal for %u: %m", j->id);
}
+
+static int bus_job_track_handler(sd_bus_track *t, void *userdata) {
+ Job *j = userdata;
+
+ assert(t);
+ assert(j);
+
+ j->bus_track = sd_bus_track_unref(j->bus_track); /* make sure we aren't called again */
+
+ /* Last client dropped off the bus, maybe we should GC this now? */
+ job_add_to_gc_queue(j);
+ return 0;
+}
+
+static int bus_job_allocate_bus_track(Job *j) {
+
+ assert(j);
+
+ if (j->bus_track)
+ return 0;
+
+ return sd_bus_track_new(j->unit->manager->api_bus, &j->bus_track, bus_job_track_handler, j);
+}
+
+int bus_job_coldplug_bus_track(Job *j) {
+ int r = 0;
+ _cleanup_strv_free_ char **deserialized_clients = NULL;
+
+ assert(j);
+
+ deserialized_clients = j->deserialized_clients;
+ j->deserialized_clients = NULL;
+
+ if (strv_isempty(deserialized_clients))
+ return 0;
+
+ if (!j->manager->api_bus)
+ return 0;
+
+ r = bus_job_allocate_bus_track(j);
+ if (r < 0)
+ return r;
+
+ return bus_track_add_name_many(j->bus_track, deserialized_clients);
+}
+
+int bus_job_track_sender(Job *j, sd_bus_message *m) {
+ int r;
+
+ assert(j);
+ assert(m);
+
+ if (sd_bus_message_get_bus(m) != j->unit->manager->api_bus) {
+ j->ref_by_private_bus = true;
+ return 0;
+ }
+
+ r = bus_job_allocate_bus_track(j);
+ if (r < 0)
+ return r;
+
+ return sd_bus_track_add_sender(j->bus_track, m);
+}
diff --git a/src/core/dbus-job.h b/src/core/dbus-job.h
index 024d06719e..a4366a0720 100644
--- a/src/core/dbus-job.h
+++ b/src/core/dbus-job.h
@@ -26,6 +26,10 @@
extern const sd_bus_vtable bus_job_vtable[];
int bus_job_method_cancel(sd_bus_message *message, void *job, sd_bus_error *error);
+int bus_job_method_get_waiting_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error);
void bus_job_send_change_signal(Job *j);
void bus_job_send_removed_signal(Job *j);
+
+int bus_job_coldplug_bus_track(Job *j);
+int bus_job_track_sender(Job *j, sd_bus_message *m);
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index d7d3d3c8ce..f87b52a266 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -19,6 +19,7 @@
#include <errno.h>
#include <sys/prctl.h>
+#include <sys/statvfs.h>
#include <unistd.h>
#include "alloc-util.h"
@@ -34,9 +35,11 @@
#include "env-util.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
+#include "fs-util.h"
#include "install.h"
#include "log.h"
+#include "parse-util.h"
#include "path-util.h"
#include "selinux-access.h"
#include "stat-util.h"
@@ -47,6 +50,10 @@
#include "virt.h"
#include "watchdog.h"
+/* Require 16MiB free in /run/systemd for reloading/reexecing. After all we need to serialize our state there, and if
+ * we can't we'll fail badly. */
+#define RELOAD_DISK_SPACE_MIN (UINT64_C(16) * UINT64_C(1024) * UINT64_C(1024))
+
static UnitFileFlags unit_file_bools_to_flags(bool runtime, bool force) {
return (runtime ? UNIT_FILE_RUNTIME : 0) |
(force ? UNIT_FILE_FORCE : 0);
@@ -841,13 +848,9 @@ static int method_get_unit_processes(sd_bus_message *message, void *userdata, sd
if (r < 0)
return r;
- r = manager_load_unit(m, name, NULL, error, &u);
- if (r < 0)
- return r;
-
- r = bus_unit_check_load_state(u, error);
- if (r < 0)
- return r;
+ u = manager_get_unit(m, name);
+ if (!u)
+ return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
return bus_unit_method_get_processes(message, u, error);
}
@@ -1311,6 +1314,40 @@ static int method_refuse_snapshot(sd_bus_message *message, void *userdata, sd_bu
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Support for snapshots has been removed.");
}
+static int verify_run_space(const char *message, sd_bus_error *error) {
+ struct statvfs svfs;
+ uint64_t available;
+
+ if (statvfs("/run/systemd", &svfs) < 0)
+ return sd_bus_error_set_errnof(error, errno, "Failed to statvfs(/run/systemd): %m");
+
+ available = (uint64_t) svfs.f_bfree * (uint64_t) svfs.f_bsize;
+
+ if (available < RELOAD_DISK_SPACE_MIN) {
+ char fb_available[FORMAT_BYTES_MAX], fb_need[FORMAT_BYTES_MAX];
+ return sd_bus_error_setf(error,
+ BUS_ERROR_DISK_FULL,
+ "%s, not enough space available on /run/systemd. "
+ "Currently, %s are free, but a safety buffer of %s is enforced.",
+ message,
+ format_bytes(fb_available, sizeof(fb_available), available),
+ format_bytes(fb_need, sizeof(fb_need), RELOAD_DISK_SPACE_MIN));
+ }
+
+ return 0;
+}
+
+int verify_run_space_and_log(const char *message) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ int r;
+
+ r = verify_run_space(message, &error);
+ if (r < 0)
+ log_error_errno(r, "%s", bus_error_message(&error, r));
+
+ return r;
+}
+
static int method_reload(sd_bus_message *message, void *userdata, sd_bus_error *error) {
Manager *m = userdata;
int r;
@@ -1318,6 +1355,10 @@ static int method_reload(sd_bus_message *message, void *userdata, sd_bus_error *
assert(message);
assert(m);
+ r = verify_run_space("Refusing to reload", error);
+ if (r < 0)
+ return r;
+
r = mac_selinux_access_check(message, "reload", error);
if (r < 0)
return r;
@@ -1350,6 +1391,10 @@ static int method_reexecute(sd_bus_message *message, void *userdata, sd_bus_erro
assert(message);
assert(m);
+ r = verify_run_space("Refusing to reexecute", error);
+ if (r < 0)
+ return r;
+
r = mac_selinux_access_check(message, "reload", error);
if (r < 0)
return r;
@@ -1468,11 +1513,26 @@ static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_er
char *ri = NULL, *rt = NULL;
const char *root, *init;
Manager *m = userdata;
+ struct statvfs svfs;
+ uint64_t available;
int r;
assert(message);
assert(m);
+ if (statvfs("/run/systemd", &svfs) < 0)
+ return sd_bus_error_set_errnof(error, errno, "Failed to statvfs(/run/systemd): %m");
+
+ available = (uint64_t) svfs.f_bfree * (uint64_t) svfs.f_bsize;
+
+ if (available < RELOAD_DISK_SPACE_MIN) {
+ char fb_available[FORMAT_BYTES_MAX], fb_need[FORMAT_BYTES_MAX];
+ log_warning("Dangerously low amount of free space on /run/systemd, root switching operation might not complete successfuly. "
+ "Currently, %s are free, but %s are suggested. Proceeding anyway.",
+ format_bytes(fb_available, sizeof(fb_available), available),
+ format_bytes(fb_need, sizeof(fb_need), RELOAD_DISK_SPACE_MIN));
+ }
+
r = mac_selinux_access_check(message, "reboot", error);
if (r < 0)
return r;
@@ -1484,25 +1544,36 @@ static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_er
if (r < 0)
return r;
- if (path_equal(root, "/") || !path_is_absolute(root))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid switch root path %s", root);
+ if (isempty(root))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New root directory may not be the empty string.");
+ if (!path_is_absolute(root))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New root path '%s' is not absolute.", root);
+ if (path_equal(root, "/"))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New root directory cannot be the old root directory.");
/* Safety check */
if (isempty(init)) {
- if (!path_is_os_tree(root))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path %s does not seem to be an OS tree. os-release file is missing.", root);
+ r = path_is_os_tree(root);
+ if (r < 0)
+ return sd_bus_error_set_errnof(error, r, "Failed to determine whether root path '%s' contains an OS tree: %m", root);
+ if (r == 0)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path '%s' does not seem to be an OS tree. os-release file is missing.", root);
} else {
- _cleanup_free_ char *p = NULL;
+ _cleanup_free_ char *chased = NULL;
if (!path_is_absolute(init))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid init path %s", init);
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path to init binary '%s' not absolute.", init);
- p = strappend(root, init);
- if (!p)
- return -ENOMEM;
+ r = chase_symlinks(init, root, CHASE_PREFIX_ROOT, &chased);
+ if (r < 0)
+ return sd_bus_error_set_errnof(error, r, "Could not resolve init executable %s: %m", init);
+
+ if (laccess(chased, X_OK) < 0) {
+ if (errno == EACCES)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Init binary %s is not executable.", init);
- if (access(p, X_OK) < 0)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p);
+ return sd_bus_error_set_errnof(error, r, "Could not check whether init binary %s is executable: %m", init);
+ }
}
rt = strdup(root);
@@ -1841,63 +1912,6 @@ static int send_unit_files_changed(sd_bus *bus, void *userdata) {
return sd_bus_send(bus, message, NULL);
}
-static int reply_unit_file_changes_and_free(
- Manager *m,
- sd_bus_message *message,
- int carries_install_info,
- UnitFileChange *changes,
- unsigned n_changes) {
-
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- unsigned i;
- int r;
-
- if (unit_file_changes_have_modification(changes, n_changes)) {
- r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL);
- if (r < 0)
- log_debug_errno(r, "Failed to send UnitFilesChanged signal: %m");
- }
-
- r = sd_bus_message_new_method_return(message, &reply);
- if (r < 0)
- goto fail;
-
- if (carries_install_info >= 0) {
- r = sd_bus_message_append(reply, "b", carries_install_info);
- if (r < 0)
- goto fail;
- }
-
- r = sd_bus_message_open_container(reply, 'a', "(sss)");
- if (r < 0)
- goto fail;
-
- for (i = 0; i < n_changes; i++)
- if (changes[i].type >= 0) {
- const char *change = unit_file_change_type_to_string(changes[i].type);
- assert(change != NULL);
-
- r = sd_bus_message_append(
- reply, "(sss)",
- change,
- changes[i].path,
- changes[i].source);
- if (r < 0)
- goto fail;
- }
-
- r = sd_bus_message_close_container(reply);
- if (r < 0)
- goto fail;
-
- unit_file_changes_free(changes, n_changes);
- return sd_bus_send(NULL, reply, NULL);
-
-fail:
- unit_file_changes_free(changes, n_changes);
- return r;
-}
-
/* Create an error reply, using the error information from changes[]
* if possible, and fall back to generating an error from error code c.
* The error message only describes the first error.
@@ -1911,12 +1925,14 @@ static int install_error(
unsigned n_changes) {
int r;
unsigned i;
- assert(c < 0);
for (i = 0; i < n_changes; i++)
+
switch(changes[i].type) {
+
case 0 ... INT_MAX:
continue;
+
case -EEXIST:
if (changes[i].source)
r = sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS,
@@ -1927,29 +1943,106 @@ static int install_error(
"File %s already exists.",
changes[i].path);
goto found;
+
case -ERFKILL:
r = sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED,
"Unit file %s is masked.", changes[i].path);
goto found;
+
case -EADDRNOTAVAIL:
r = sd_bus_error_setf(error, BUS_ERROR_UNIT_GENERATED,
"Unit %s is transient or generated.", changes[i].path);
goto found;
+
case -ELOOP:
r = sd_bus_error_setf(error, BUS_ERROR_UNIT_LINKED,
"Refusing to operate on linked unit file %s", changes[i].path);
goto found;
+
+ case -ENOENT:
+ r = sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit file %s does not exist.", changes[i].path);
+ goto found;
+
default:
r = sd_bus_error_set_errnof(error, changes[i].type, "File %s: %m", changes[i].path);
goto found;
}
- r = c;
+ r = c < 0 ? c : -EINVAL;
+
found:
unit_file_changes_free(changes, n_changes);
return r;
}
+static int reply_unit_file_changes_and_free(
+ Manager *m,
+ sd_bus_message *message,
+ int carries_install_info,
+ UnitFileChange *changes,
+ unsigned n_changes,
+ sd_bus_error *error) {
+
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ bool bad = false, good = false;
+ unsigned i;
+ int r;
+
+ if (unit_file_changes_have_modification(changes, n_changes)) {
+ r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL);
+ if (r < 0)
+ log_debug_errno(r, "Failed to send UnitFilesChanged signal: %m");
+ }
+
+ r = sd_bus_message_new_method_return(message, &reply);
+ if (r < 0)
+ goto fail;
+
+ if (carries_install_info >= 0) {
+ r = sd_bus_message_append(reply, "b", carries_install_info);
+ if (r < 0)
+ goto fail;
+ }
+
+ r = sd_bus_message_open_container(reply, 'a', "(sss)");
+ if (r < 0)
+ goto fail;
+
+ for (i = 0; i < n_changes; i++) {
+
+ if (changes[i].type < 0) {
+ bad = true;
+ continue;
+ }
+
+ r = sd_bus_message_append(
+ reply, "(sss)",
+ unit_file_change_type_to_string(changes[i].type),
+ changes[i].path,
+ changes[i].source);
+ if (r < 0)
+ goto fail;
+
+ good = true;
+ }
+
+ /* If there was a failed change, and no successful change, then return the first failure as proper method call
+ * error. */
+ if (bad && !good)
+ return install_error(error, 0, changes, n_changes);
+
+ r = sd_bus_message_close_container(reply);
+ if (r < 0)
+ goto fail;
+
+ unit_file_changes_free(changes, n_changes);
+ return sd_bus_send(NULL, reply, NULL);
+
+fail:
+ unit_file_changes_free(changes, n_changes);
+ return r;
+}
+
static int method_enable_unit_files_generic(
sd_bus_message *message,
Manager *m,
@@ -1986,7 +2079,7 @@ static int method_enable_unit_files_generic(
if (r < 0)
return install_error(error, r, changes, n_changes);
- return reply_unit_file_changes_and_free(m, message, carries_install_info ? r : -1, changes, n_changes);
+ return reply_unit_file_changes_and_free(m, message, carries_install_info ? r : -1, changes, n_changes, error);
}
static int method_enable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
@@ -2055,7 +2148,7 @@ static int method_preset_unit_files_with_mode(sd_bus_message *message, void *use
if (r < 0)
return install_error(error, r, changes, n_changes);
- return reply_unit_file_changes_and_free(m, message, r, changes, n_changes);
+ return reply_unit_file_changes_and_free(m, message, r, changes, n_changes, error);
}
static int method_disable_unit_files_generic(
@@ -2090,7 +2183,7 @@ static int method_disable_unit_files_generic(
if (r < 0)
return install_error(error, r, changes, n_changes);
- return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
+ return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes, error);
}
static int method_disable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
@@ -2125,7 +2218,7 @@ static int method_revert_unit_files(sd_bus_message *message, void *userdata, sd_
if (r < 0)
return install_error(error, r, changes, n_changes);
- return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
+ return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes, error);
}
static int method_set_default_target(sd_bus_message *message, void *userdata, sd_bus_error *error) {
@@ -2156,7 +2249,7 @@ static int method_set_default_target(sd_bus_message *message, void *userdata, sd
if (r < 0)
return install_error(error, r, changes, n_changes);
- return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
+ return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes, error);
}
static int method_preset_all_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
@@ -2199,7 +2292,7 @@ static int method_preset_all_unit_files(sd_bus_message *message, void *userdata,
if (r < 0)
return install_error(error, r, changes, n_changes);
- return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
+ return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes, error);
}
static int method_add_dependency_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
@@ -2239,7 +2332,7 @@ static int method_add_dependency_unit_files(sd_bus_message *message, void *userd
if (r < 0)
return install_error(error, r, changes, n_changes);
- return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
+ return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes, error);
}
static int method_get_unit_file_links(sd_bus_message *message, void *userdata, sd_bus_error *error) {
@@ -2285,6 +2378,26 @@ static int method_get_unit_file_links(sd_bus_message *message, void *userdata, s
return sd_bus_send(NULL, reply, NULL);
}
+static int method_get_job_waiting(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ Manager *m = userdata;
+ uint32_t id;
+ Job *j;
+ int r;
+
+ assert(message);
+ assert(m);
+
+ r = sd_bus_message_read(message, "u", &id);
+ if (r < 0)
+ return r;
+
+ j = manager_get_job(m, id);
+ if (!j)
+ return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
+
+ return bus_job_method_get_waiting_jobs(message, j, error);
+}
+
const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_VTABLE_START(0),
@@ -2390,6 +2503,8 @@ const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetUnitProcesses", "s", "a(sus)", method_get_unit_processes, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetJobAfter", "u", "a(usssoo)", method_get_job_waiting, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetJobBefore", "u", "a(usssoo)", method_get_job_waiting, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, SD_BUS_VTABLE_UNPRIVILEGED),
diff --git a/src/core/dbus-manager.h b/src/core/dbus-manager.h
index 36a2e9481b..9f3222da28 100644
--- a/src/core/dbus-manager.h
+++ b/src/core/dbus-manager.h
@@ -26,3 +26,5 @@ extern const sd_bus_vtable bus_manager_vtable[];
void bus_manager_send_finished(Manager *m, usec_t firmware_usec, usec_t loader_usec, usec_t kernel_usec, usec_t initrd_usec, usec_t userspace_usec, usec_t total_usec);
void bus_manager_send_reloading(Manager *m, bool active);
void bus_manager_send_change_signal(Manager *m);
+
+int verify_run_space_and_log(const char *message);
diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c
index 61b83d2d62..85b67318ed 100644
--- a/src/core/dbus-service.c
+++ b/src/core/dbus-service.c
@@ -143,6 +143,29 @@ static int bus_service_set_transient_property(
return 1;
+ } else if (streq(name, "Restart")) {
+ ServiceRestart sr;
+ const char *v;
+
+ r = sd_bus_message_read(message, "s", &v);
+ if (r < 0)
+ return r;
+
+ if (isempty(v))
+ sr = SERVICE_RESTART_NO;
+ else {
+ sr = service_restart_from_string(v);
+ if (sr < 0)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid restart setting: %s", v);
+ }
+
+ if (mode != UNIT_CHECK) {
+ s->restart = sr;
+ unit_write_drop_in_private_format(UNIT(s), mode, name, "Restart=%s", service_restart_to_string(sr));
+ }
+
+ return 1;
+
} else if (STR_IN_SET(name,
"StandardInputFileDescriptor",
"StandardOutputFileDescriptor",
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index 69e249c844..f15bb2196c 100644
--- a/src/core/dbus-unit.c
+++ b/src/core/dbus-unit.c
@@ -22,6 +22,7 @@
#include "alloc-util.h"
#include "bus-common-errors.h"
#include "cgroup-util.h"
+#include "dbus-job.h"
#include "dbus-unit.h"
#include "dbus.h"
#include "fd-util.h"
@@ -481,7 +482,7 @@ int bus_unit_method_start_generic(
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s invalid", smode);
if (reload_if_possible)
- verb = strjoin("reload-or-", job_type_to_string(job_type), NULL);
+ verb = strjoin("reload-or-", job_type_to_string(job_type));
else
verb = strdup(job_type_to_string(job_type));
if (!verb)
@@ -984,7 +985,7 @@ static int append_cgroup(sd_bus_message *reply, const char *p, Set *pids) {
if (r == 0)
break;
- j = strjoin(p, "/", g, NULL);
+ j = strjoin(p, "/", g);
if (!j)
return -ENOMEM;
@@ -1005,6 +1006,10 @@ int bus_unit_method_get_processes(sd_bus_message *message, void *userdata, sd_bu
assert(message);
+ r = mac_selinux_unit_access_check(u, message, "status", error);
+ if (r < 0)
+ return r;
+
pids = set_new(NULL);
if (!pids)
return -ENOMEM;
@@ -1126,7 +1131,7 @@ void bus_unit_send_change_signal(Unit *u) {
if (!u->id)
return;
- r = bus_foreach_bus(u->manager, NULL, u->sent_dbus_new_signal ? send_changed_signal : send_new_signal, u);
+ r = bus_foreach_bus(u->manager, u->bus_track, u->sent_dbus_new_signal ? send_changed_signal : send_new_signal, u);
if (r < 0)
log_unit_debug_errno(u, r, "Failed to send unit change signal for %s: %m", u->id);
@@ -1172,7 +1177,7 @@ void bus_unit_send_removed_signal(Unit *u) {
if (!u->id)
return;
- r = bus_foreach_bus(u->manager, NULL, send_removed_signal, u);
+ r = bus_foreach_bus(u->manager, u->bus_track, send_removed_signal, u);
if (r < 0)
log_unit_debug_errno(u, r, "Failed to send unit remove signal for %s: %m", u->id);
}
@@ -1217,23 +1222,15 @@ int bus_unit_queue_job(
(type == JOB_STOP && u->refuse_manual_stop) ||
((type == JOB_RESTART || type == JOB_TRY_RESTART) && (u->refuse_manual_start || u->refuse_manual_stop)) ||
(type == JOB_RELOAD_OR_START && job_type_collapse(type, u) == JOB_START && u->refuse_manual_start))
- return sd_bus_error_setf(error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, unit %s may be requested by dependency only.", u->id);
+ return sd_bus_error_setf(error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).", u->id);
r = manager_add_job(u->manager, type, u, mode, error, &j);
if (r < 0)
return r;
- if (sd_bus_message_get_bus(message) == u->manager->api_bus) {
- if (!j->clients) {
- r = sd_bus_track_new(sd_bus_message_get_bus(message), &j->clients, NULL, NULL);
- if (r < 0)
- return r;
- }
-
- r = sd_bus_track_add_sender(j->clients, message);
- if (r < 0)
- return r;
- }
+ r = bus_job_track_sender(j, message);
+ if (r < 0)
+ return r;
path = job_dbus_path(j);
if (!path)
@@ -1363,7 +1360,7 @@ static int bus_unit_set_transient_property(
if (r < 0)
return r;
- label = strjoin(name, "-", other, NULL);
+ label = strjoin(name, "-", other);
if (!label)
return -ENOMEM;
@@ -1507,7 +1504,7 @@ int bus_unit_check_load_state(Unit *u, sd_bus_error *error) {
return sd_bus_error_set_errnof(error, u->load_error, "Unit %s is not loaded properly: %m.", u->id);
}
-static int bus_track_handler(sd_bus_track *t, void *userdata) {
+static int bus_unit_track_handler(sd_bus_track *t, void *userdata) {
Unit *u = userdata;
assert(t);
@@ -1519,7 +1516,7 @@ static int bus_track_handler(sd_bus_track *t, void *userdata) {
return 0;
}
-static int allocate_bus_track(Unit *u) {
+static int bus_unit_allocate_bus_track(Unit *u) {
int r;
assert(u);
@@ -1527,7 +1524,7 @@ static int allocate_bus_track(Unit *u) {
if (u->bus_track)
return 0;
- r = sd_bus_track_new(u->manager->api_bus, &u->bus_track, bus_track_handler, u);
+ r = sd_bus_track_new(u->manager->api_bus, &u->bus_track, bus_unit_track_handler, u);
if (r < 0)
return r;
@@ -1545,7 +1542,7 @@ int bus_unit_track_add_name(Unit *u, const char *name) {
assert(u);
- r = allocate_bus_track(u);
+ r = bus_unit_allocate_bus_track(u);
if (r < 0)
return r;
@@ -1557,7 +1554,7 @@ int bus_unit_track_add_sender(Unit *u, sd_bus_message *m) {
assert(u);
- r = allocate_bus_track(u);
+ r = bus_unit_allocate_bus_track(u);
if (r < 0)
return r;
diff --git a/src/core/dbus.c b/src/core/dbus.c
index 070974fe66..cfc045d282 100644
--- a/src/core/dbus.c
+++ b/src/core/dbus.c
@@ -175,7 +175,7 @@ static int signal_activation_request(sd_bus_message *message, void *userdata, sd
goto failed;
if (u->refuse_manual_start) {
- r = sd_bus_error_setf(&error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, %s may be requested by dependency only.", u->id);
+ r = sd_bus_error_setf(&error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, %s may be requested by dependency only (it is configured to refuse manual start/stop).", u->id);
goto failed;
}
@@ -298,7 +298,7 @@ static int bus_job_find(sd_bus *bus, const char *path, const char *interface, vo
}
static int find_unit(Manager *m, sd_bus *bus, const char *path, Unit **unit, sd_bus_error *error) {
- Unit *u;
+ Unit *u = NULL; /* just to appease gcc, initialization is not really necessary */
int r;
assert(m);
@@ -323,15 +323,15 @@ static int find_unit(Manager *m, sd_bus *bus, const char *path, Unit **unit, sd_
return r;
u = manager_get_unit_by_pid(m, pid);
+ if (!u)
+ return 0;
} else {
r = manager_load_unit_from_dbus_path(m, path, error, &u);
if (r < 0)
return 0;
+ assert(u);
}
- if (!u)
- return 0;
-
*unit = u;
return 1;
}
@@ -477,7 +477,7 @@ static int bus_kill_context_find(sd_bus *bus, const char *path, const char *inte
}
static int bus_job_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
- _cleanup_free_ char **l = NULL;
+ _cleanup_strv_free_ char **l = NULL;
Manager *m = userdata;
unsigned k = 0;
Iterator i;
@@ -504,7 +504,7 @@ static int bus_job_enumerate(sd_bus *bus, const char *path, void *userdata, char
}
static int bus_unit_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
- _cleanup_free_ char **l = NULL;
+ _cleanup_strv_free_ char **l = NULL;
Manager *m = userdata;
unsigned k = 0;
Iterator i;
@@ -753,13 +753,13 @@ int manager_sync_bus_names(Manager *m, sd_bus *bus) {
/* If it is, determine its current owner */
r = sd_bus_get_name_creds(bus, name, SD_BUS_CREDS_UNIQUE_NAME, &creds);
if (r < 0) {
- log_error_errno(r, "Failed to get bus name owner %s: %m", name);
+ log_full_errno(r == -ENXIO ? LOG_DEBUG : LOG_ERR, r, "Failed to get bus name owner %s: %m", name);
continue;
}
r = sd_bus_creds_get_unique_name(creds, &unique);
if (r < 0) {
- log_error_errno(r, "Failed to get unique name for %s: %m", name);
+ log_full_errno(r == -ENXIO ? LOG_DEBUG : LOG_ERR, r, "Failed to get unique name for %s: %m", name);
continue;
}
@@ -1041,6 +1041,7 @@ int bus_init(Manager *m, bool try_bus_connect) {
static void destroy_bus(Manager *m, sd_bus **bus) {
Iterator i;
+ Unit *u;
Job *j;
assert(m);
@@ -1049,13 +1050,24 @@ static void destroy_bus(Manager *m, sd_bus **bus) {
if (!*bus)
return;
+ /* Make sure all bus slots watching names are released. */
+ HASHMAP_FOREACH(u, m->watch_bus, i) {
+ if (!u->match_bus_slot)
+ continue;
+
+ if (sd_bus_slot_get_bus(u->match_bus_slot) != *bus)
+ continue;
+
+ u->match_bus_slot = sd_bus_slot_unref(u->match_bus_slot);
+ }
+
/* Get rid of tracked clients on this bus */
if (m->subscribed && sd_bus_track_get_bus(m->subscribed) == *bus)
m->subscribed = sd_bus_track_unref(m->subscribed);
HASHMAP_FOREACH(j, m->jobs, i)
- if (j->clients && sd_bus_track_get_bus(j->clients) == *bus)
- j->clients = sd_bus_track_unref(j->clients);
+ if (j->bus_track && sd_bus_track_get_bus(j->bus_track) == *bus)
+ j->bus_track = sd_bus_track_unref(j->bus_track);
/* Get rid of queued message on this bus */
if (m->queued_message && sd_bus_message_get_bus(m->queued_message) == *bus)
@@ -1185,7 +1197,6 @@ void bus_track_serialize(sd_bus_track *t, FILE *f, const char *prefix) {
}
int bus_track_coldplug(Manager *m, sd_bus_track **t, bool recursive, char **l) {
- char **i;
int r = 0;
assert(m);
@@ -1207,16 +1218,7 @@ int bus_track_coldplug(Manager *m, sd_bus_track **t, bool recursive, char **l) {
if (r < 0)
return r;
- r = 0;
- STRV_FOREACH(i, l) {
- int k;
-
- k = sd_bus_track_add_name(*t, *i);
- if (k < 0)
- r = k;
- }
-
- return r;
+ return bus_track_add_name_many(*t, l);
}
int bus_verify_manage_units_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
diff --git a/src/core/device.c b/src/core/device.c
index 4b9e84aeb6..0e67c96552 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -239,7 +239,7 @@ static int device_update_description(Unit *u, struct udev_device *dev, const cha
if (label) {
_cleanup_free_ char *j;
- j = strjoin(model, " ", label, NULL);
+ j = strjoin(model, " ", label);
if (j)
r = unit_set_description(u, j);
else
@@ -256,38 +256,63 @@ static int device_update_description(Unit *u, struct udev_device *dev, const cha
}
static int device_add_udev_wants(Unit *u, struct udev_device *dev) {
- const char *wants;
- const char *word, *state;
- size_t l;
+ const char *wants, *property, *p;
int r;
- const char *property;
assert(u);
assert(dev);
property = MANAGER_IS_USER(u->manager) ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS";
wants = udev_device_get_property_value(dev, property);
- if (!wants)
- return 0;
-
- FOREACH_WORD_QUOTED(word, l, wants, state) {
- _cleanup_free_ char *n = NULL;
- char e[l+1];
+ for (p = wants;;) {
+ _cleanup_free_ char *word = NULL, *k = NULL;
- memcpy(e, word, l);
- e[l] = 0;
+ r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
+ if (r == 0)
+ return 0;
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r < 0)
+ return log_unit_error_errno(u, r, "Failed to add parse %s: %m", property);
- r = unit_name_mangle(e, UNIT_NAME_NOGLOB, &n);
+ r = unit_name_mangle(word, UNIT_NAME_NOGLOB, &k);
if (r < 0)
- return log_unit_error_errno(u, r, "Failed to mangle unit name: %m");
+ return log_unit_error_errno(u, r, "Failed to mangle unit name \"%s\": %m", word);
- r = unit_add_dependency_by_name(u, UNIT_WANTS, n, NULL, true);
+ r = unit_add_dependency_by_name(u, UNIT_WANTS, k, NULL, true);
if (r < 0)
return log_unit_error_errno(u, r, "Failed to add wants dependency: %m");
}
- if (!isempty(state))
- log_unit_warning(u, "Property %s on %s has trailing garbage, ignoring.", property, strna(udev_device_get_syspath(dev)));
+}
+
+static bool device_is_bound_by_mounts(Unit *d, struct udev_device *dev) {
+ const char *bound_by;
+ int r = false;
+
+ assert(d);
+ assert(dev);
+
+ bound_by = udev_device_get_property_value(dev, "SYSTEMD_MOUNT_DEVICE_BOUND");
+ if (bound_by)
+ r = parse_boolean(bound_by) > 0;
+
+ DEVICE(d)->bind_mounts = r;
+ return r;
+}
+
+static int device_upgrade_mount_deps(Unit *u) {
+ Unit *other;
+ Iterator i;
+ int r;
+
+ SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i) {
+ if (other->type != UNIT_MOUNT)
+ continue;
+ r = unit_add_dependency(other, UNIT_BINDS_TO, u, true);
+ if (r < 0)
+ return r;
+ }
return 0;
}
@@ -355,6 +380,13 @@ static int device_setup_unit(Manager *m, struct udev_device *dev, const char *pa
(void) device_add_udev_wants(u, dev);
}
+ /* So the user wants the mount units to be bound to the device but a
+ * mount unit might has been seen by systemd before the device appears
+ * on its radar. In this case the device unit is partially initialized
+ * and includes the deps on the mount unit but at that time the "bind
+ * mounts" flag wasn't not present. Fix this up now. */
+ if (dev && device_is_bound_by_mounts(u, dev))
+ device_upgrade_mount_deps(u);
/* Note that this won't dispatch the load queue, the caller
* has to do that if needed and appropriate */
@@ -365,7 +397,7 @@ static int device_setup_unit(Manager *m, struct udev_device *dev, const char *pa
fail:
log_unit_warning_errno(u, r, "Failed to set up device unit: %m");
- if (delete && u)
+ if (delete)
unit_free(u);
return r;
@@ -423,26 +455,22 @@ static int device_process_new(Manager *m, struct udev_device *dev) {
/* Add additional units for all explicitly configured
* aliases */
alias = udev_device_get_property_value(dev, "SYSTEMD_ALIAS");
- if (alias) {
- const char *word, *state;
- size_t l;
-
- FOREACH_WORD_QUOTED(word, l, alias, state) {
- char e[l+1];
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
- memcpy(e, word, l);
- e[l] = 0;
+ r = extract_first_word(&alias, &word, NULL, EXTRACT_QUOTES);
+ if (r == 0)
+ return 0;
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r < 0)
+ return log_warning_errno(r, "Failed to add parse SYSTEMD_ALIAS for %s: %m", sysfs);
- if (path_is_absolute(e))
- (void) device_setup_unit(m, dev, e, false);
- else
- log_warning("SYSTEMD_ALIAS for %s is not an absolute path, ignoring: %s", sysfs, e);
- }
- if (!isempty(state))
- log_warning("SYSTEMD_ALIAS for %s has trailing garbage, ignoring.", sysfs);
+ if (path_is_absolute(word))
+ (void) device_setup_unit(m, dev, word, false);
+ else
+ log_warning("SYSTEMD_ALIAS for %s is not an absolute path, ignoring: %s", sysfs, word);
}
-
- return 0;
}
static void device_update_found_one(Device *d, bool add, DeviceFound found, bool now) {
@@ -834,6 +862,14 @@ int device_found_node(Manager *m, const char *node, bool add, DeviceFound found,
return device_update_found_by_name(m, node, add, found, now);
}
+bool device_shall_be_bound_by(Unit *device, Unit *u) {
+
+ if (u->type != UNIT_MOUNT)
+ return false;
+
+ return DEVICE(device)->bind_mounts;
+}
+
const UnitVTable device_vtable = {
.object_size = sizeof(Device),
.sections =
@@ -841,6 +877,8 @@ const UnitVTable device_vtable = {
"Device\0"
"Install\0",
+ .gc_jobs = true,
+
.init = device_init,
.done = device_done,
.load = unit_load_fragment_and_dropin_optional,
diff --git a/src/core/device.h b/src/core/device.h
index 184a1a349b..dd372fb695 100644
--- a/src/core/device.h
+++ b/src/core/device.h
@@ -40,8 +40,11 @@ struct Device {
LIST_FIELDS(struct Device, same_sysfs);
DeviceState state, deserialized_state;
+
+ bool bind_mounts;
};
extern const UnitVTable device_vtable;
int device_found_node(Manager *m, const char *node, bool add, DeviceFound found, bool now);
+bool device_shall_be_bound_by(Unit *device, Unit *u);
diff --git a/src/core/execute.c b/src/core/execute.c
index 85ee82c3e1..08b95f7d4f 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -71,7 +71,7 @@
#include "exit-status.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "fs-util.h"
#include "glob-util.h"
#include "io-util.h"
@@ -624,7 +624,7 @@ static int chown_terminal(int fd, uid_t uid) {
return 0;
}
-static int setup_confirm_stdio(int *_saved_stdin, int *_saved_stdout) {
+static int setup_confirm_stdio(const char *vc, int *_saved_stdin, int *_saved_stdout) {
_cleanup_close_ int fd = -1, saved_stdin = -1, saved_stdout = -1;
int r;
@@ -639,12 +639,7 @@ static int setup_confirm_stdio(int *_saved_stdin, int *_saved_stdout) {
if (saved_stdout < 0)
return -errno;
- fd = acquire_terminal(
- "/dev/console",
- false,
- false,
- false,
- DEFAULT_CONFIRM_USEC);
+ fd = acquire_terminal(vc, false, false, false, DEFAULT_CONFIRM_USEC);
if (fd < 0)
return fd;
@@ -674,21 +669,27 @@ static int setup_confirm_stdio(int *_saved_stdin, int *_saved_stdout) {
return 0;
}
-_printf_(1, 2) static int write_confirm_message(const char *format, ...) {
+static void write_confirm_error_fd(int err, int fd, const Unit *u) {
+ assert(err < 0);
+
+ if (err == -ETIMEDOUT)
+ dprintf(fd, "Confirmation question timed out for %s, assuming positive response.\n", u->id);
+ else {
+ errno = -err;
+ dprintf(fd, "Couldn't ask confirmation for %s: %m, assuming positive response.\n", u->id);
+ }
+}
+
+static void write_confirm_error(int err, const char *vc, const Unit *u) {
_cleanup_close_ int fd = -1;
- va_list ap;
- assert(format);
+ assert(vc);
- fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
+ fd = open_terminal(vc, O_WRONLY|O_NOCTTY|O_CLOEXEC);
if (fd < 0)
- return fd;
-
- va_start(ap, format);
- vdprintf(fd, format, ap);
- va_end(ap);
+ return;
- return 0;
+ write_confirm_error_fd(err, fd, u);
}
static int restore_confirm_stdio(int *saved_stdin, int *saved_stdout) {
@@ -713,22 +714,96 @@ static int restore_confirm_stdio(int *saved_stdin, int *saved_stdout) {
return r;
}
-static int ask_for_confirmation(char *response, char **argv) {
+enum {
+ CONFIRM_PRETEND_FAILURE = -1,
+ CONFIRM_PRETEND_SUCCESS = 0,
+ CONFIRM_EXECUTE = 1,
+};
+
+static int ask_for_confirmation(const char *vc, Unit *u, const char *cmdline) {
int saved_stdout = -1, saved_stdin = -1, r;
- _cleanup_free_ char *line = NULL;
+ _cleanup_free_ char *e = NULL;
+ char c;
- r = setup_confirm_stdio(&saved_stdin, &saved_stdout);
- if (r < 0)
- return r;
+ /* For any internal errors, assume a positive response. */
+ r = setup_confirm_stdio(vc, &saved_stdin, &saved_stdout);
+ if (r < 0) {
+ write_confirm_error(r, vc, u);
+ return CONFIRM_EXECUTE;
+ }
- line = exec_command_line(argv);
- if (!line)
- return -ENOMEM;
+ /* confirm_spawn might have been disabled while we were sleeping. */
+ if (manager_is_confirm_spawn_disabled(u->manager)) {
+ r = 1;
+ goto restore_stdio;
+ }
+
+ e = ellipsize(cmdline, 60, 100);
+ if (!e) {
+ log_oom();
+ r = CONFIRM_EXECUTE;
+ goto restore_stdio;
+ }
- r = ask_char(response, "yns", "Execute %s? [Yes, No, Skip] ", line);
+ for (;;) {
+ r = ask_char(&c, "yfshiDjcn", "Execute %s? [y, f, s – h for help] ", e);
+ if (r < 0) {
+ write_confirm_error_fd(r, STDOUT_FILENO, u);
+ r = CONFIRM_EXECUTE;
+ goto restore_stdio;
+ }
- restore_confirm_stdio(&saved_stdin, &saved_stdout);
+ switch (c) {
+ case 'c':
+ printf("Resuming normal execution.\n");
+ manager_disable_confirm_spawn();
+ r = 1;
+ break;
+ case 'D':
+ unit_dump(u, stdout, " ");
+ continue; /* ask again */
+ case 'f':
+ printf("Failing execution.\n");
+ r = CONFIRM_PRETEND_FAILURE;
+ break;
+ case 'h':
+ printf(" c - continue, proceed without asking anymore\n"
+ " D - dump, show the state of the unit\n"
+ " f - fail, don't execute the command and pretend it failed\n"
+ " h - help\n"
+ " i - info, show a short summary of the unit\n"
+ " j - jobs, show jobs that are in progress\n"
+ " s - skip, don't execute the command and pretend it succeeded\n"
+ " y - yes, execute the command\n");
+ continue; /* ask again */
+ case 'i':
+ printf(" Description: %s\n"
+ " Unit: %s\n"
+ " Command: %s\n",
+ u->id, u->description, cmdline);
+ continue; /* ask again */
+ case 'j':
+ manager_dump_jobs(u->manager, stdout, " ");
+ continue; /* ask again */
+ case 'n':
+ /* 'n' was removed in favor of 'f'. */
+ printf("Didn't understand 'n', did you mean 'f'?\n");
+ continue; /* ask again */
+ case 's':
+ printf("Skipping execution.\n");
+ r = CONFIRM_PRETEND_SUCCESS;
+ break;
+ case 'y':
+ r = CONFIRM_EXECUTE;
+ break;
+ default:
+ assert_not_reached("Unhandled choice");
+ }
+ break;
+ }
+restore_stdio:
+ restore_confirm_stdio(&saved_stdin, &saved_stdout);
return r;
}
@@ -1069,11 +1144,13 @@ static int setup_pam(
/* Tell the parent that our setup is done. This is especially
* important regarding dropping privileges. Otherwise, unit
- * setup might race against our setresuid(2) call. */
- barrier_place(&barrier);
+ * setup might race against our setresuid(2) call.
+ *
+ * If the parent aborted, we'll detect this below, hence ignore
+ * return failure here. */
+ (void) barrier_place(&barrier);
- /* Check if our parent process might already have
- * died? */
+ /* Check if our parent process might already have died? */
if (getppid() == parent_pid) {
sigset_t ss;
@@ -1184,6 +1261,41 @@ static void rename_process_from_path(const char *path) {
rename_process(process_name);
}
+static bool context_has_address_families(const ExecContext *c) {
+ assert(c);
+
+ return c->address_families_whitelist ||
+ !set_isempty(c->address_families);
+}
+
+static bool context_has_syscall_filters(const ExecContext *c) {
+ assert(c);
+
+ return c->syscall_whitelist ||
+ !set_isempty(c->syscall_filter);
+}
+
+static bool context_has_no_new_privileges(const ExecContext *c) {
+ assert(c);
+
+ if (c->no_new_privileges)
+ return true;
+
+ if (have_effective_cap(CAP_SYS_ADMIN)) /* if we are privileged, we don't need NNP */
+ return false;
+
+ /* We need NNP if we have any form of seccomp and are unprivileged */
+ return context_has_address_families(c) ||
+ c->memory_deny_write_execute ||
+ c->restrict_realtime ||
+ exec_context_restrict_namespaces_set(c) ||
+ c->protect_kernel_tunables ||
+ c->protect_kernel_modules ||
+ c->private_devices ||
+ context_has_syscall_filters(c) ||
+ !set_isempty(c->syscall_archs);
+}
+
#ifdef HAVE_SECCOMP
static bool skip_seccomp_unavailable(const Unit* u, const char* msg) {
@@ -1197,345 +1309,140 @@ static bool skip_seccomp_unavailable(const Unit* u, const char* msg) {
return true;
}
-static int apply_seccomp(const Unit* u, const ExecContext *c) {
- uint32_t negative_action, action;
- scmp_filter_ctx seccomp;
- Iterator i;
- void *id;
- int r;
+static int apply_syscall_filter(const Unit* u, const ExecContext *c) {
+ uint32_t negative_action, default_action, action;
+ assert(u);
assert(c);
- if (skip_seccomp_unavailable(u, "syscall filtering"))
+ if (!context_has_syscall_filters(c))
return 0;
- negative_action = c->syscall_errno == 0 ? SCMP_ACT_KILL : SCMP_ACT_ERRNO(c->syscall_errno);
-
- seccomp = seccomp_init(c->syscall_whitelist ? negative_action : SCMP_ACT_ALLOW);
- if (!seccomp)
- return -ENOMEM;
-
- if (c->syscall_archs) {
+ if (skip_seccomp_unavailable(u, "SystemCallFilter="))
+ return 0;
- SET_FOREACH(id, c->syscall_archs, i) {
- r = seccomp_arch_add(seccomp, PTR_TO_UINT32(id) - 1);
- if (r == -EEXIST)
- continue;
- if (r < 0)
- goto finish;
- }
+ negative_action = c->syscall_errno == 0 ? SCMP_ACT_KILL : SCMP_ACT_ERRNO(c->syscall_errno);
+ if (c->syscall_whitelist) {
+ default_action = negative_action;
+ action = SCMP_ACT_ALLOW;
} else {
- r = seccomp_add_secondary_archs(seccomp);
- if (r < 0)
- goto finish;
- }
-
- action = c->syscall_whitelist ? SCMP_ACT_ALLOW : negative_action;
- SET_FOREACH(id, c->syscall_filter, i) {
- r = seccomp_rule_add(seccomp, action, PTR_TO_INT(id) - 1, 0);
- if (r < 0)
- goto finish;
+ default_action = SCMP_ACT_ALLOW;
+ action = negative_action;
}
- r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
- if (r < 0)
- goto finish;
-
- r = seccomp_load(seccomp);
-
-finish:
- seccomp_release(seccomp);
- return r;
+ return seccomp_load_syscall_filter_set_raw(default_action, c->syscall_filter, action);
}
-static int apply_address_families(const Unit* u, const ExecContext *c) {
- scmp_filter_ctx seccomp;
- Iterator i;
- int r;
-
-#if defined(__i386__)
- return 0;
-#endif
-
+static int apply_syscall_archs(const Unit *u, const ExecContext *c) {
+ assert(u);
assert(c);
- if (skip_seccomp_unavailable(u, "RestrictAddressFamilies="))
+ if (set_isempty(c->syscall_archs))
return 0;
- r = seccomp_init_conservative(&seccomp, SCMP_ACT_ALLOW);
- if (r < 0)
- return r;
-
- if (c->address_families_whitelist) {
- int af, first = 0, last = 0;
- void *afp;
-
- /* If this is a whitelist, we first block the address
- * families that are out of range and then everything
- * that is not in the set. First, we find the lowest
- * and highest address family in the set. */
-
- SET_FOREACH(afp, c->address_families, i) {
- af = PTR_TO_INT(afp);
-
- if (af <= 0 || af >= af_max())
- continue;
-
- if (first == 0 || af < first)
- first = af;
-
- if (last == 0 || af > last)
- last = af;
- }
-
- assert((first == 0) == (last == 0));
-
- if (first == 0) {
-
- /* No entries in the valid range, block everything */
- r = seccomp_rule_add(
- seccomp,
- SCMP_ACT_ERRNO(EPROTONOSUPPORT),
- SCMP_SYS(socket),
- 0);
- if (r < 0)
- goto finish;
-
- } else {
-
- /* Block everything below the first entry */
- r = seccomp_rule_add(
- seccomp,
- SCMP_ACT_ERRNO(EPROTONOSUPPORT),
- SCMP_SYS(socket),
- 1,
- SCMP_A0(SCMP_CMP_LT, first));
- if (r < 0)
- goto finish;
-
- /* Block everything above the last entry */
- r = seccomp_rule_add(
- seccomp,
- SCMP_ACT_ERRNO(EPROTONOSUPPORT),
- SCMP_SYS(socket),
- 1,
- SCMP_A0(SCMP_CMP_GT, last));
- if (r < 0)
- goto finish;
-
- /* Block everything between the first and last
- * entry */
- for (af = 1; af < af_max(); af++) {
-
- if (set_contains(c->address_families, INT_TO_PTR(af)))
- continue;
-
- r = seccomp_rule_add(
- seccomp,
- SCMP_ACT_ERRNO(EPROTONOSUPPORT),
- SCMP_SYS(socket),
- 1,
- SCMP_A0(SCMP_CMP_EQ, af));
- if (r < 0)
- goto finish;
- }
- }
-
- } else {
- void *af;
+ if (skip_seccomp_unavailable(u, "SystemCallArchitectures="))
+ return 0;
- /* If this is a blacklist, then generate one rule for
- * each address family that are then combined in OR
- * checks. */
+ return seccomp_restrict_archs(c->syscall_archs);
+}
- SET_FOREACH(af, c->address_families, i) {
+static int apply_address_families(const Unit* u, const ExecContext *c) {
+ assert(u);
+ assert(c);
- r = seccomp_rule_add(
- seccomp,
- SCMP_ACT_ERRNO(EPROTONOSUPPORT),
- SCMP_SYS(socket),
- 1,
- SCMP_A0(SCMP_CMP_EQ, PTR_TO_INT(af)));
- if (r < 0)
- goto finish;
- }
- }
+ if (!context_has_address_families(c))
+ return 0;
- r = seccomp_load(seccomp);
+ if (skip_seccomp_unavailable(u, "RestrictAddressFamilies="))
+ return 0;
-finish:
- seccomp_release(seccomp);
- return r;
+ return seccomp_restrict_address_families(c->address_families, c->address_families_whitelist);
}
static int apply_memory_deny_write_execute(const Unit* u, const ExecContext *c) {
- scmp_filter_ctx seccomp;
- int r;
-
+ assert(u);
assert(c);
- if (skip_seccomp_unavailable(u, "MemoryDenyWriteExecute="))
+ if (!c->memory_deny_write_execute)
return 0;
- r = seccomp_init_conservative(&seccomp, SCMP_ACT_ALLOW);
- if (r < 0)
- return r;
-
- r = seccomp_rule_add(
- seccomp,
- SCMP_ACT_ERRNO(EPERM),
- SCMP_SYS(mmap),
- 1,
- SCMP_A2(SCMP_CMP_MASKED_EQ, PROT_EXEC|PROT_WRITE, PROT_EXEC|PROT_WRITE));
- if (r < 0)
- goto finish;
-
- r = seccomp_rule_add(
- seccomp,
- SCMP_ACT_ERRNO(EPERM),
- SCMP_SYS(mprotect),
- 1,
- SCMP_A2(SCMP_CMP_MASKED_EQ, PROT_EXEC, PROT_EXEC));
- if (r < 0)
- goto finish;
-
- r = seccomp_rule_add(
- seccomp,
- SCMP_ACT_ERRNO(EPERM),
- SCMP_SYS(shmat),
- 1,
- SCMP_A2(SCMP_CMP_MASKED_EQ, SHM_EXEC, SHM_EXEC));
- if (r < 0)
- goto finish;
-
- r = seccomp_load(seccomp);
+ if (skip_seccomp_unavailable(u, "MemoryDenyWriteExecute="))
+ return 0;
-finish:
- seccomp_release(seccomp);
- return r;
+ return seccomp_memory_deny_write_execute();
}
static int apply_restrict_realtime(const Unit* u, const ExecContext *c) {
- static const int permitted_policies[] = {
- SCHED_OTHER,
- SCHED_BATCH,
- SCHED_IDLE,
- };
-
- scmp_filter_ctx seccomp;
- unsigned i;
- int r, p, max_policy = 0;
-
+ assert(u);
assert(c);
- if (skip_seccomp_unavailable(u, "RestrictRealtime="))
+ if (!c->restrict_realtime)
return 0;
- r = seccomp_init_conservative(&seccomp, SCMP_ACT_ALLOW);
- if (r < 0)
- return r;
-
- /* Determine the highest policy constant we want to allow */
- for (i = 0; i < ELEMENTSOF(permitted_policies); i++)
- if (permitted_policies[i] > max_policy)
- max_policy = permitted_policies[i];
-
- /* Go through all policies with lower values than that, and block them -- unless they appear in the
- * whitelist. */
- for (p = 0; p < max_policy; p++) {
- bool good = false;
-
- /* Check if this is in the whitelist. */
- for (i = 0; i < ELEMENTSOF(permitted_policies); i++)
- if (permitted_policies[i] == p) {
- good = true;
- break;
- }
-
- if (good)
- continue;
-
- /* Deny this policy */
- r = seccomp_rule_add(
- seccomp,
- SCMP_ACT_ERRNO(EPERM),
- SCMP_SYS(sched_setscheduler),
- 1,
- SCMP_A1(SCMP_CMP_EQ, p));
- if (r < 0)
- goto finish;
- }
-
- /* Blacklist all other policies, i.e. the ones with higher values. Note that all comparisons are unsigned here,
- * hence no need no check for < 0 values. */
- r = seccomp_rule_add(
- seccomp,
- SCMP_ACT_ERRNO(EPERM),
- SCMP_SYS(sched_setscheduler),
- 1,
- SCMP_A1(SCMP_CMP_GT, max_policy));
- if (r < 0)
- goto finish;
-
- r = seccomp_load(seccomp);
+ if (skip_seccomp_unavailable(u, "RestrictRealtime="))
+ return 0;
-finish:
- seccomp_release(seccomp);
- return r;
+ return seccomp_restrict_realtime();
}
static int apply_protect_sysctl(const Unit *u, const ExecContext *c) {
- scmp_filter_ctx seccomp;
- int r;
-
+ assert(u);
assert(c);
/* Turn off the legacy sysctl() system call. Many distributions turn this off while building the kernel, but
* let's protect even those systems where this is left on in the kernel. */
- if (skip_seccomp_unavailable(u, "ProtectKernelTunables="))
+ if (!c->protect_kernel_tunables)
return 0;
- r = seccomp_init_conservative(&seccomp, SCMP_ACT_ALLOW);
- if (r < 0)
- return r;
-
- r = seccomp_rule_add(
- seccomp,
- SCMP_ACT_ERRNO(EPERM),
- SCMP_SYS(_sysctl),
- 0);
- if (r < 0)
- goto finish;
-
- r = seccomp_load(seccomp);
+ if (skip_seccomp_unavailable(u, "ProtectKernelTunables="))
+ return 0;
-finish:
- seccomp_release(seccomp);
- return r;
+ return seccomp_protect_sysctl();
}
static int apply_protect_kernel_modules(const Unit *u, const ExecContext *c) {
+ assert(u);
assert(c);
/* Turn off module syscalls on ProtectKernelModules=yes */
+ if (!c->protect_kernel_modules)
+ return 0;
+
if (skip_seccomp_unavailable(u, "ProtectKernelModules="))
return 0;
- return seccomp_load_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_MODULE, SCMP_ACT_ERRNO(EPERM));
+ return seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_MODULE, SCMP_ACT_ERRNO(EPERM));
}
static int apply_private_devices(const Unit *u, const ExecContext *c) {
+ assert(u);
assert(c);
/* If PrivateDevices= is set, also turn off iopl and all @raw-io syscalls. */
+ if (!c->private_devices)
+ return 0;
+
if (skip_seccomp_unavailable(u, "PrivateDevices="))
return 0;
- return seccomp_load_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_RAW_IO, SCMP_ACT_ERRNO(EPERM));
+ return seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_RAW_IO, SCMP_ACT_ERRNO(EPERM));
+}
+
+static int apply_restrict_namespaces(Unit *u, const ExecContext *c) {
+ assert(u);
+ assert(c);
+
+ if (!exec_context_restrict_namespaces_set(c))
+ return 0;
+
+ if (skip_seccomp_unavailable(u, "RestrictNamespaces="))
+ return 0;
+
+ return seccomp_restrict_namespaces(c->restrict_namespaces);
}
#endif
@@ -1607,7 +1514,7 @@ static int build_environment(
if (!joined)
return -ENOMEM;
- x = strjoin("LISTEN_FDNAMES=", joined, NULL);
+ x = strjoin("LISTEN_FDNAMES=", joined);
if (!x)
return -ENOMEM;
our_env[n_env++] = x;
@@ -1714,7 +1621,7 @@ static int build_pass_environment(const ExecContext *c, char ***ret) {
v = getenv(*i);
if (!v)
continue;
- x = strjoin(*i, "=", v, NULL);
+ x = strjoin(*i, "=", v);
if (!x)
return -ENOMEM;
if (!GREEDY_REALLOC(pass_env, n_bufsize, n_env + 2))
@@ -1738,11 +1645,17 @@ static bool exec_needs_mount_namespace(
assert(context);
assert(params);
+ if (context->root_image)
+ return true;
+
if (!strv_isempty(context->read_write_paths) ||
!strv_isempty(context->read_only_paths) ||
!strv_isempty(context->inaccessible_paths))
return true;
+ if (context->n_bind_mounts > 0)
+ return true;
+
if (context->mount_flags != 0)
return true;
@@ -1757,6 +1670,9 @@ static bool exec_needs_mount_namespace(
context->protect_control_groups)
return true;
+ if (context->mount_apivfs)
+ return true;
+
return false;
}
@@ -1777,25 +1693,31 @@ static int setup_private_users(uid_t uid, gid_t gid) {
* child then writes the UID mapping, under full privileges. The parent waits for the child to finish and
* continues execution normally. */
- if (uid != 0 && uid_is_valid(uid))
- asprintf(&uid_map,
- "0 0 1\n" /* Map root → root */
- UID_FMT " " UID_FMT " 1\n", /* Map $UID → $UID */
- uid, uid);
- else
+ if (uid != 0 && uid_is_valid(uid)) {
+ r = asprintf(&uid_map,
+ "0 0 1\n" /* Map root → root */
+ UID_FMT " " UID_FMT " 1\n", /* Map $UID → $UID */
+ uid, uid);
+ if (r < 0)
+ return -ENOMEM;
+ } else {
uid_map = strdup("0 0 1\n"); /* The case where the above is the same */
- if (!uid_map)
- return -ENOMEM;
+ if (!uid_map)
+ return -ENOMEM;
+ }
- if (gid != 0 && gid_is_valid(gid))
- asprintf(&gid_map,
- "0 0 1\n" /* Map root → root */
- GID_FMT " " GID_FMT " 1\n", /* Map $GID → $GID */
- gid, gid);
- else
+ if (gid != 0 && gid_is_valid(gid)) {
+ r = asprintf(&gid_map,
+ "0 0 1\n" /* Map root → root */
+ GID_FMT " " GID_FMT " 1\n", /* Map $GID → $GID */
+ gid, gid);
+ if (r < 0)
+ return -ENOMEM;
+ } else {
gid_map = strdup("0 0 1\n"); /* The case where the above is the same */
- if (!gid_map)
- return -ENOMEM;
+ if (!gid_map)
+ return -ENOMEM;
+ }
/* Create a communication channel so that the parent can tell the child when it finished creating the user
* namespace. */
@@ -1928,7 +1850,7 @@ static int setup_runtime_directory(
STRV_FOREACH(rt, context->runtime_directory) {
_cleanup_free_ char *p;
- p = strjoin(params->runtime_prefix, "/", *rt, NULL);
+ p = strjoin(params->runtime_prefix, "/", *rt);
if (!p)
return -ENOMEM;
@@ -1988,8 +1910,8 @@ static int compile_read_write_paths(
_cleanup_strv_free_ char **l = NULL;
char **rt;
- /* Compile the list of writable paths. This is the combination of the explicitly configured paths, plus all
- * runtime directories. */
+ /* Compile the list of writable paths. This is the combination of
+ * the explicitly configured paths, plus all runtime directories. */
if (strv_isempty(context->read_write_paths) &&
strv_isempty(context->runtime_directory)) {
@@ -2004,7 +1926,7 @@ static int compile_read_write_paths(
STRV_FOREACH(rt, context->runtime_directory) {
char *s;
- s = strjoin(params->runtime_prefix, "/", *rt, NULL);
+ s = strjoin(params->runtime_prefix, "/", *rt);
if (!s)
return -ENOMEM;
@@ -2018,19 +1940,26 @@ static int compile_read_write_paths(
return 0;
}
-static int apply_mount_namespace(Unit *u, const ExecContext *context,
- const ExecParameters *params,
- ExecRuntime *runtime) {
- int r;
- _cleanup_free_ char **rw = NULL;
+static int apply_mount_namespace(
+ Unit *u,
+ ExecCommand *command,
+ const ExecContext *context,
+ const ExecParameters *params,
+ ExecRuntime *runtime) {
+
+ _cleanup_strv_free_ char **rw = NULL;
char *tmp = NULL, *var = NULL;
- const char *root_dir = NULL;
+ const char *root_dir = NULL, *root_image = NULL;
NameSpaceInfo ns_info = {
+ .ignore_protect_paths = false,
.private_dev = context->private_devices,
.protect_control_groups = context->protect_control_groups,
.protect_kernel_tunables = context->protect_kernel_tunables,
.protect_kernel_modules = context->protect_kernel_modules,
+ .mount_apivfs = context->mount_apivfs,
};
+ bool apply_restrictions;
+ int r;
assert(context);
@@ -2049,17 +1978,35 @@ static int apply_mount_namespace(Unit *u, const ExecContext *context,
if (r < 0)
return r;
- if (params->flags & EXEC_APPLY_CHROOT)
- root_dir = context->root_directory;
+ if (params->flags & EXEC_APPLY_CHROOT) {
+ root_image = context->root_image;
+
+ if (!root_image)
+ root_dir = context->root_directory;
+ }
- r = setup_namespace(root_dir, &ns_info, rw,
- context->read_only_paths,
- context->inaccessible_paths,
+ /*
+ * If DynamicUser=no and RootDirectory= is set then lets pass a relaxed
+ * sandbox info, otherwise enforce it, don't ignore protected paths and
+ * fail if we are enable to apply the sandbox inside the mount namespace.
+ */
+ if (!context->dynamic_user && root_dir)
+ ns_info.ignore_protect_paths = true;
+
+ apply_restrictions = (params->flags & EXEC_APPLY_PERMISSIONS) && !command->privileged;
+
+ r = setup_namespace(root_dir, root_image,
+ &ns_info, rw,
+ apply_restrictions ? context->read_only_paths : NULL,
+ apply_restrictions ? context->inaccessible_paths : NULL,
+ context->bind_mounts,
+ context->n_bind_mounts,
tmp,
var,
- context->protect_home,
- context->protect_system,
- context->mount_flags);
+ apply_restrictions ? context->protect_home : PROTECT_HOME_NO,
+ apply_restrictions ? context->protect_system : PROTECT_SYSTEM_NO,
+ context->mount_flags,
+ DISSECT_IMAGE_DISCARD_ON_LOOP);
/* If we couldn't set up the namespace this is probably due to a
* missing capability. In this case, silently proceeed. */
@@ -2073,33 +2020,47 @@ static int apply_mount_namespace(Unit *u, const ExecContext *context,
return r;
}
-static int apply_working_directory(const ExecContext *context,
- const ExecParameters *params,
- const char *home,
- const bool needs_mount_ns) {
- const char *d;
- const char *wd;
+static int apply_working_directory(
+ const ExecContext *context,
+ const ExecParameters *params,
+ const char *home,
+ const bool needs_mount_ns,
+ int *exit_status) {
+
+ const char *d, *wd;
assert(context);
+ assert(exit_status);
+
+ if (context->working_directory_home) {
+
+ if (!home) {
+ *exit_status = EXIT_CHDIR;
+ return -ENXIO;
+ }
- if (context->working_directory_home)
wd = home;
- else if (context->working_directory)
+
+ } else if (context->working_directory)
wd = context->working_directory;
else
wd = "/";
if (params->flags & EXEC_APPLY_CHROOT) {
if (!needs_mount_ns && context->root_directory)
- if (chroot(context->root_directory) < 0)
+ if (chroot(context->root_directory) < 0) {
+ *exit_status = EXIT_CHROOT;
return -errno;
+ }
d = wd;
} else
- d = strjoina(strempty(context->root_directory), "/", strempty(wd));
+ d = prefix_roota(context->root_directory, wd);
- if (chdir(d) < 0 && !context->working_directory_missing_ok)
+ if (chdir(d) < 0 && !context->working_directory_missing_ok) {
+ *exit_status = EXIT_CHDIR;
return -errno;
+ }
return 0;
}
@@ -2160,39 +2121,6 @@ static int close_remaining_fds(
return close_all_fds(dont_close, n_dont_close);
}
-static bool context_has_address_families(const ExecContext *c) {
- assert(c);
-
- return c->address_families_whitelist ||
- !set_isempty(c->address_families);
-}
-
-static bool context_has_syscall_filters(const ExecContext *c) {
- assert(c);
-
- return c->syscall_whitelist ||
- !set_isempty(c->syscall_filter) ||
- !set_isempty(c->syscall_archs);
-}
-
-static bool context_has_no_new_privileges(const ExecContext *c) {
- assert(c);
-
- if (c->no_new_privileges)
- return true;
-
- if (have_effective_cap(CAP_SYS_ADMIN)) /* if we are privileged, we don't need NNP */
- return false;
-
- return context_has_address_families(c) || /* we need NNP if we have any form of seccomp and are unprivileged */
- c->memory_deny_write_execute ||
- c->restrict_realtime ||
- c->protect_kernel_tunables ||
- c->protect_kernel_modules ||
- c->private_devices ||
- context_has_syscall_filters(c);
-}
-
static int send_user_lookup(
Unit *unit,
int user_lookup_fd,
@@ -2221,6 +2149,35 @@ static int send_user_lookup(
return 0;
}
+static int acquire_home(const ExecContext *c, uid_t uid, const char** home, char **buf) {
+ int r;
+
+ assert(c);
+ assert(home);
+ assert(buf);
+
+ /* If WorkingDirectory=~ is set, try to acquire a usable home directory. */
+
+ if (*home)
+ return 0;
+
+ if (!c->working_directory_home)
+ return 0;
+
+ if (uid == 0) {
+ /* Hardcode /root as home directory for UID 0 */
+ *home = "/root";
+ return 1;
+ }
+
+ r = get_home_dir(buf);
+ if (r < 0)
+ return r;
+
+ *home = *buf;
+ return 1;
+}
+
static int exec_child(
Unit *unit,
ExecCommand *command,
@@ -2234,10 +2191,11 @@ static int exec_child(
int *fds, unsigned n_fds,
char **files_env,
int user_lookup_fd,
- int *exit_status) {
+ int *exit_status,
+ char **error_message) {
_cleanup_strv_free_ char **our_env = NULL, **pass_env = NULL, **accum_env = NULL, **final_argv = NULL;
- _cleanup_free_ char *mac_selinux_context_net = NULL;
+ _cleanup_free_ char *mac_selinux_context_net = NULL, *home_buffer = NULL;
_cleanup_free_ gid_t *supplementary_gids = NULL;
const char *username = NULL, *groupname = NULL;
const char *home = NULL, *shell = NULL;
@@ -2253,6 +2211,9 @@ static int exec_child(
assert(context);
assert(params);
assert(exit_status);
+ assert(error_message);
+ /* We don't always set error_message, hence it must be initialized */
+ assert(*error_message == NULL);
rename_process_from_path(command->path);
@@ -2270,6 +2231,8 @@ static int exec_child(
r = reset_signal_mask();
if (r < 0) {
*exit_status = EXIT_SIGNAL_MASK;
+ *error_message = strdup("Failed to reset signal mask");
+ /* If strdup fails, here and below, we will just print the generic error message. */
return r;
}
@@ -2285,6 +2248,7 @@ static int exec_child(
r = close_remaining_fds(params, runtime, dcreds, user_lookup_fd, socket_fd, fds, n_fds);
if (r < 0) {
*exit_status = EXIT_FDS;
+ *error_message = strdup("Failed to close remaining fds");
return r;
}
@@ -2296,22 +2260,25 @@ static int exec_child(
exec_context_tty_reset(context, params);
- if (params->flags & EXEC_CONFIRM_SPAWN) {
- char response;
+ if (unit_shall_confirm_spawn(unit)) {
+ const char *vc = params->confirm_spawn;
+ _cleanup_free_ char *cmdline = NULL;
- r = ask_for_confirmation(&response, argv);
- if (r == -ETIMEDOUT)
- write_confirm_message("Confirmation question timed out, assuming positive response.\n");
- else if (r < 0)
- write_confirm_message("Couldn't ask confirmation question, assuming positive response: %s\n", strerror(-r));
- else if (response == 's') {
- write_confirm_message("Skipping execution.\n");
+ cmdline = exec_command_line(argv);
+ if (!cmdline) {
*exit_status = EXIT_CONFIRM;
+ return -ENOMEM;
+ }
+
+ r = ask_for_confirmation(vc, unit, cmdline);
+ if (r != CONFIRM_EXECUTE) {
+ if (r == CONFIRM_PRETEND_SUCCESS) {
+ *exit_status = EXIT_SUCCESS;
+ return 0;
+ }
+ *exit_status = EXIT_CONFIRM;
+ *error_message = strdup("Execution cancelled");
return -ECANCELED;
- } else if (response == 'n') {
- write_confirm_message("Failing execution.\n");
- *exit_status = 0;
- return 0;
}
}
@@ -2320,17 +2287,27 @@ static int exec_child(
/* Make sure we bypass our own NSS module for any NSS checks */
if (putenv((char*) "SYSTEMD_NSS_DYNAMIC_BYPASS=1") != 0) {
*exit_status = EXIT_USER;
+ *error_message = strdup("Failed to update environment");
return -errno;
}
r = dynamic_creds_realize(dcreds, &uid, &gid);
if (r < 0) {
*exit_status = EXIT_USER;
+ *error_message = strdup("Failed to update dynamic user credentials");
return r;
}
- if (!uid_is_valid(uid) || !gid_is_valid(gid)) {
+ if (!uid_is_valid(uid)) {
+ *exit_status = EXIT_USER;
+ (void) asprintf(error_message, "UID validation failed for \""UID_FMT"\"", uid);
+ /* If asprintf fails, here and below, we will just print the generic error message. */
+ return -ESRCH;
+ }
+
+ if (!gid_is_valid(gid)) {
*exit_status = EXIT_USER;
+ (void) asprintf(error_message, "GID validation failed for \""GID_FMT"\"", gid);
return -ESRCH;
}
@@ -2341,12 +2318,14 @@ static int exec_child(
r = get_fixed_user(context, &username, &uid, &gid, &home, &shell);
if (r < 0) {
*exit_status = EXIT_USER;
+ *error_message = strdup("Failed to determine user credentials");
return r;
}
r = get_fixed_group(context, &groupname, &gid);
if (r < 0) {
*exit_status = EXIT_GROUP;
+ *error_message = strdup("Failed to determine group credentials");
return r;
}
}
@@ -2356,17 +2335,26 @@ static int exec_child(
&supplementary_gids, &ngids);
if (r < 0) {
*exit_status = EXIT_GROUP;
+ *error_message = strdup("Failed to determine supplementary groups");
return r;
}
r = send_user_lookup(unit, user_lookup_fd, uid, gid);
if (r < 0) {
*exit_status = EXIT_USER;
+ *error_message = strdup("Failed to send user credentials to PID1");
return r;
}
user_lookup_fd = safe_close(user_lookup_fd);
+ r = acquire_home(context, uid, &home, &home_buffer);
+ if (r < 0) {
+ *exit_status = EXIT_CHDIR;
+ *error_message = strdup("Failed to determine $HOME for user");
+ return r;
+ }
+
/* If a socket is connected to STDIN/STDOUT/STDERR, we
* must sure to drop O_NONBLOCK */
if (socket_fd >= 0)
@@ -2375,18 +2363,21 @@ static int exec_child(
r = setup_input(context, params, socket_fd, named_iofds);
if (r < 0) {
*exit_status = EXIT_STDIN;
+ *error_message = strdup("Failed to set up stdin");
return r;
}
r = setup_output(unit, context, params, STDOUT_FILENO, socket_fd, named_iofds, basename(command->path), uid, gid, &journal_stream_dev, &journal_stream_ino);
if (r < 0) {
*exit_status = EXIT_STDOUT;
+ *error_message = strdup("Failed to set up stdout");
return r;
}
r = setup_output(unit, context, params, STDERR_FILENO, socket_fd, named_iofds, basename(command->path), uid, gid, &journal_stream_dev, &journal_stream_ino);
if (r < 0) {
*exit_status = EXIT_STDERR;
+ *error_message = strdup("Failed to set up stderr");
return r;
}
@@ -2394,6 +2385,7 @@ static int exec_child(
r = cg_attach_everywhere(params->cgroup_supported, params->cgroup_path, 0, NULL, NULL);
if (r < 0) {
*exit_status = EXIT_CGROUP;
+ (void) asprintf(error_message, "Failed to attach to cgroup %s", params->cgroup_path);
return r;
}
}
@@ -2414,6 +2406,7 @@ static int exec_child(
log_close();
} else if (r < 0) {
*exit_status = EXIT_OOM_ADJUST;
+ *error_message = strdup("Failed to write /proc/self/oom_score_adj");
return -errno;
}
}
@@ -2465,11 +2458,12 @@ static int exec_child(
}
if (context->utmp_id)
- utmp_put_init_process(context->utmp_id, getpid(), getsid(0), context->tty_path,
+ utmp_put_init_process(context->utmp_id, getpid(), getsid(0),
+ context->tty_path,
context->utmp_mode == EXEC_UTMP_INIT ? INIT_PROCESS :
context->utmp_mode == EXEC_UTMP_LOGIN ? LOGIN_PROCESS :
USER_PROCESS,
- username ? "root" : context->user);
+ username);
if (context->user) {
r = chown_terminal(STDIN_FILENO, uid);
@@ -2562,7 +2556,7 @@ static int exec_child(
needs_mount_namespace = exec_needs_mount_namespace(context, params, runtime);
if (needs_mount_namespace) {
- r = apply_mount_namespace(unit, context, params, runtime);
+ r = apply_mount_namespace(unit, command, context, params, runtime);
if (r < 0) {
*exit_status = EXIT_NAMESPACE;
return r;
@@ -2570,11 +2564,9 @@ static int exec_child(
}
/* Apply just after mount namespace setup */
- r = apply_working_directory(context, params, home, needs_mount_namespace);
- if (r < 0) {
- *exit_status = EXIT_CHROOT;
+ r = apply_working_directory(context, params, home, needs_mount_namespace, exit_status);
+ if (r < 0)
return r;
- }
/* Drop groups as early as possbile */
if ((params->flags & EXEC_APPLY_PERMISSIONS) && !command->privileged) {
@@ -2652,6 +2644,7 @@ static int exec_child(
r = capability_bounding_set_drop(context->capability_bounding_set, false);
if (r < 0) {
*exit_status = EXIT_CAPABILITIES;
+ *error_message = strdup("Failed to drop capabilities");
return r;
}
}
@@ -2662,6 +2655,7 @@ static int exec_child(
r = capability_ambient_set_apply(context->capability_ambient_set, true);
if (r < 0) {
*exit_status = EXIT_CAPABILITIES;
+ *error_message = strdup("Failed to apply ambient capabilities (before UID change)");
return r;
}
}
@@ -2670,6 +2664,7 @@ static int exec_child(
r = enforce_user(context, uid);
if (r < 0) {
*exit_status = EXIT_USER;
+ (void) asprintf(error_message, "Failed to change UID to "UID_FMT, uid);
return r;
}
if (context->capability_ambient_set != 0) {
@@ -2678,6 +2673,7 @@ static int exec_child(
r = capability_ambient_set_apply(context->capability_ambient_set, false);
if (r < 0) {
*exit_status = EXIT_CAPABILITIES;
+ *error_message = strdup("Failed to apply ambient capabilities (after UID change)");
return r;
}
@@ -2705,6 +2701,7 @@ static int exec_child(
r = setexeccon(exec_context);
if (r < 0) {
*exit_status = EXIT_SELINUX_CONTEXT;
+ (void) asprintf(error_message, "Failed to set SELinux context to %s", exec_context);
return r;
}
}
@@ -2714,6 +2711,7 @@ static int exec_child(
r = setup_smack(context, command);
if (r < 0) {
*exit_status = EXIT_SMACK_PROCESS_LABEL;
+ *error_message = strdup("Failed to set SMACK process label");
return r;
}
@@ -2722,6 +2720,9 @@ static int exec_child(
r = aa_change_onexec(context->apparmor_profile);
if (r < 0 && !context->apparmor_profile_ignore) {
*exit_status = EXIT_APPARMOR_PROFILE;
+ (void) asprintf(error_message,
+ "Failed to prepare AppArmor profile change to %s",
+ context->apparmor_profile);
return -errno;
}
}
@@ -2734,72 +2735,81 @@ static int exec_child(
if (prctl(PR_GET_SECUREBITS) != secure_bits)
if (prctl(PR_SET_SECUREBITS, secure_bits) < 0) {
*exit_status = EXIT_SECUREBITS;
+ *error_message = strdup("Failed to set secure bits");
return -errno;
}
if (context_has_no_new_privileges(context))
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
*exit_status = EXIT_NO_NEW_PRIVILEGES;
+ *error_message = strdup("Failed to disable new privileges");
return -errno;
}
#ifdef HAVE_SECCOMP
- if (context_has_address_families(context)) {
- r = apply_address_families(unit, context);
- if (r < 0) {
- *exit_status = EXIT_ADDRESS_FAMILIES;
- return r;
- }
+ r = apply_address_families(unit, context);
+ if (r < 0) {
+ *exit_status = EXIT_ADDRESS_FAMILIES;
+ *error_message = strdup("Failed to restrict address families");
+ return r;
}
- if (context->memory_deny_write_execute) {
- r = apply_memory_deny_write_execute(unit, context);
- if (r < 0) {
- *exit_status = EXIT_SECCOMP;
- return r;
- }
+ r = apply_memory_deny_write_execute(unit, context);
+ if (r < 0) {
+ *exit_status = EXIT_SECCOMP;
+ *error_message = strdup("Failed to disable writing to executable memory");
+ return r;
}
- if (context->restrict_realtime) {
- r = apply_restrict_realtime(unit, context);
- if (r < 0) {
- *exit_status = EXIT_SECCOMP;
- return r;
- }
+ r = apply_restrict_realtime(unit, context);
+ if (r < 0) {
+ *exit_status = EXIT_SECCOMP;
+ *error_message = strdup("Failed to apply realtime restrictions");
+ return r;
}
- if (context->protect_kernel_tunables) {
- r = apply_protect_sysctl(unit, context);
- if (r < 0) {
- *exit_status = EXIT_SECCOMP;
- return r;
- }
+ r = apply_restrict_namespaces(unit, context);
+ if (r < 0) {
+ *exit_status = EXIT_SECCOMP;
+ *error_message = strdup("Failed to apply namespace restrictions");
+ return r;
}
- if (context->protect_kernel_modules) {
- r = apply_protect_kernel_modules(unit, context);
- if (r < 0) {
- *exit_status = EXIT_SECCOMP;
- return r;
- }
+ r = apply_protect_sysctl(unit, context);
+ if (r < 0) {
+ *exit_status = EXIT_SECCOMP;
+ *error_message = strdup("Failed to apply sysctl restrictions");
+ return r;
}
- if (context->private_devices) {
- r = apply_private_devices(unit, context);
- if (r < 0) {
- *exit_status = EXIT_SECCOMP;
- return r;
- }
+ r = apply_protect_kernel_modules(unit, context);
+ if (r < 0) {
+ *exit_status = EXIT_SECCOMP;
+ *error_message = strdup("Failed to apply module loading restrictions");
+ return r;
+ }
+
+ r = apply_private_devices(unit, context);
+ if (r < 0) {
+ *exit_status = EXIT_SECCOMP;
+ *error_message = strdup("Failed to set up private devices");
+ return r;
+ }
+
+ r = apply_syscall_archs(unit, context);
+ if (r < 0) {
+ *exit_status = EXIT_SECCOMP;
+ *error_message = strdup("Failed to apply syscall architecture restrictions");
+ return r;
}
/* This really should remain the last step before the execve(), to make sure our own code is unaffected
* by the filter as little as possible. */
- if (context_has_syscall_filters(context)) {
- r = apply_seccomp(unit, context);
- if (r < 0) {
- *exit_status = EXIT_SECCOMP;
- return r;
- }
+ r = apply_syscall_filter(unit, context);
+ if (r < 0) {
+ *exit_status = EXIT_SECCOMP;
+ *error_message = strdup("Failed to apply syscall filters");
+ return r;
}
#endif
}
@@ -2807,6 +2817,7 @@ static int exec_child(
final_argv = replace_env_argv(argv, accum_env);
if (!final_argv) {
*exit_status = EXIT_MEMORY;
+ *error_message = strdup("Failed to prepare process arguments");
return -ENOMEM;
}
@@ -2857,11 +2868,16 @@ int exec_spawn(Unit *unit,
context->std_output == EXEC_OUTPUT_SOCKET ||
context->std_error == EXEC_OUTPUT_SOCKET) {
- if (params->n_fds != 1) {
+ if (params->n_fds > 1) {
log_unit_error(unit, "Got more than one socket.");
return -EINVAL;
}
+ if (params->n_fds == 0) {
+ log_unit_error(unit, "Got no socket.");
+ return -EINVAL;
+ }
+
socket_fd = params->fds[0];
} else {
socket_fd = -1;
@@ -2893,6 +2909,7 @@ int exec_spawn(Unit *unit,
if (pid == 0) {
int exit_status;
+ _cleanup_free_ char *error_message = NULL;
r = exec_child(unit,
command,
@@ -2906,17 +2923,27 @@ int exec_spawn(Unit *unit,
fds, n_fds,
files_env,
unit->manager->user_lookup_fds[1],
- &exit_status);
+ &exit_status,
+ &error_message);
if (r < 0) {
log_open();
- log_struct_errno(LOG_ERR, r,
- LOG_MESSAGE_ID(SD_MESSAGE_SPAWN_FAILED),
- LOG_UNIT_ID(unit),
- LOG_UNIT_MESSAGE(unit, "Failed at step %s spawning %s: %m",
- exit_status_to_string(exit_status, EXIT_STATUS_SYSTEMD),
- command->path),
- "EXECUTABLE=%s", command->path,
- NULL);
+ if (error_message)
+ log_struct_errno(LOG_ERR, r,
+ "MESSAGE_ID=" SD_MESSAGE_SPAWN_FAILED_STR,
+ LOG_UNIT_ID(unit),
+ LOG_UNIT_MESSAGE(unit, "%s: %m",
+ error_message),
+ "EXECUTABLE=%s", command->path,
+ NULL);
+ else
+ log_struct_errno(LOG_ERR, r,
+ "MESSAGE_ID=" SD_MESSAGE_SPAWN_FAILED_STR,
+ LOG_UNIT_ID(unit),
+ LOG_UNIT_MESSAGE(unit, "Failed at step %s spawning %s: %m",
+ exit_status_to_string(exit_status, EXIT_STATUS_SYSTEMD),
+ command->path),
+ "EXECUTABLE=%s", command->path,
+ NULL);
}
_exit(exit_status);
@@ -2951,6 +2978,7 @@ void exec_context_init(ExecContext *c) {
c->personality = PERSONALITY_INVALID;
c->runtime_directory_mode = 0755;
c->capability_bounding_set = CAP_ALL;
+ c->restrict_namespaces = NAMESPACE_FLAGS_ALL;
}
void exec_context_done(ExecContext *c) {
@@ -2970,6 +2998,7 @@ void exec_context_done(ExecContext *c) {
c->working_directory = mfree(c->working_directory);
c->root_directory = mfree(c->root_directory);
+ c->root_image = mfree(c->root_image);
c->tty_path = mfree(c->tty_path);
c->syslog_identifier = mfree(c->syslog_identifier);
c->user = mfree(c->user);
@@ -2983,6 +3012,8 @@ void exec_context_done(ExecContext *c) {
c->read_write_paths = strv_free(c->read_write_paths);
c->inaccessible_paths = strv_free(c->inaccessible_paths);
+ bind_mount_free_many(c->bind_mounts, c->n_bind_mounts);
+
if (c->cpuset)
CPU_FREE(c->cpuset);
@@ -3008,7 +3039,7 @@ int exec_context_destroy_runtime_directory(ExecContext *c, const char *runtime_p
STRV_FOREACH(i, c->runtime_directory) {
_cleanup_free_ char *p;
- p = strjoin(runtime_prefix, "/", *i, NULL);
+ p = strjoin(runtime_prefix, "/", *i);
if (!p)
return -ENOMEM;
@@ -3089,7 +3120,7 @@ const char* exec_context_fdname(const ExecContext *c, int fd_index) {
int exec_context_named_iofds(Unit *unit, const ExecContext *c, const ExecParameters *p, int named_iofds[3]) {
unsigned i, targets;
- const char *stdio_fdname[3];
+ const char* stdio_fdname[3];
assert(c);
assert(p);
@@ -3102,18 +3133,32 @@ int exec_context_named_iofds(Unit *unit, const ExecContext *c, const ExecParamet
stdio_fdname[i] = exec_context_fdname(c, i);
for (i = 0; i < p->n_fds && targets > 0; i++)
- if (named_iofds[STDIN_FILENO] < 0 && c->std_input == EXEC_INPUT_NAMED_FD && stdio_fdname[STDIN_FILENO] && streq(p->fd_names[i], stdio_fdname[STDIN_FILENO])) {
+ if (named_iofds[STDIN_FILENO] < 0 &&
+ c->std_input == EXEC_INPUT_NAMED_FD &&
+ stdio_fdname[STDIN_FILENO] &&
+ streq(p->fd_names[i], stdio_fdname[STDIN_FILENO])) {
+
named_iofds[STDIN_FILENO] = p->fds[i];
targets--;
- } else if (named_iofds[STDOUT_FILENO] < 0 && c->std_output == EXEC_OUTPUT_NAMED_FD && stdio_fdname[STDOUT_FILENO] && streq(p->fd_names[i], stdio_fdname[STDOUT_FILENO])) {
+
+ } else if (named_iofds[STDOUT_FILENO] < 0 &&
+ c->std_output == EXEC_OUTPUT_NAMED_FD &&
+ stdio_fdname[STDOUT_FILENO] &&
+ streq(p->fd_names[i], stdio_fdname[STDOUT_FILENO])) {
+
named_iofds[STDOUT_FILENO] = p->fds[i];
targets--;
- } else if (named_iofds[STDERR_FILENO] < 0 && c->std_error == EXEC_OUTPUT_NAMED_FD && stdio_fdname[STDERR_FILENO] && streq(p->fd_names[i], stdio_fdname[STDERR_FILENO])) {
+
+ } else if (named_iofds[STDERR_FILENO] < 0 &&
+ c->std_error == EXEC_OUTPUT_NAMED_FD &&
+ stdio_fdname[STDERR_FILENO] &&
+ streq(p->fd_names[i], stdio_fdname[STDERR_FILENO])) {
+
named_iofds[STDERR_FILENO] = p->fds[i];
targets--;
}
- return (targets == 0 ? 0 : -ENOENT);
+ return targets == 0 ? 0 : -ENOENT;
}
int exec_context_load_environment(Unit *unit, const ExecContext *c, char ***l) {
@@ -3248,6 +3293,7 @@ static void strv_fprintf(FILE *f, char **l) {
void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
char **e, **d;
unsigned i;
+ int r;
assert(c);
assert(f);
@@ -3268,6 +3314,7 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
"%sPrivateUsers: %s\n"
"%sProtectHome: %s\n"
"%sProtectSystem: %s\n"
+ "%sMountAPIVFS: %s\n"
"%sIgnoreSIGPIPE: %s\n"
"%sMemoryDenyWriteExecute: %s\n"
"%sRestrictRealtime: %s\n",
@@ -3284,10 +3331,14 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
prefix, yes_no(c->private_users),
prefix, protect_home_to_string(c->protect_home),
prefix, protect_system_to_string(c->protect_system),
+ prefix, yes_no(c->mount_apivfs),
prefix, yes_no(c->ignore_sigpipe),
prefix, yes_no(c->memory_deny_write_execute),
prefix, yes_no(c->restrict_realtime));
+ if (c->root_image)
+ fprintf(f, "%sRootImage: %s\n", prefix, c->root_image);
+
STRV_FOREACH(e, c->environment)
fprintf(f, "%sEnvironment: %s\n", prefix, *e);
@@ -3465,6 +3516,15 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
fputs("\n", f);
}
+ if (c->n_bind_mounts > 0)
+ for (i = 0; i < c->n_bind_mounts; i++) {
+ fprintf(f, "%s%s: %s:%s:%s\n", prefix,
+ c->bind_mounts[i].read_only ? "BindReadOnlyPaths" : "BindPaths",
+ c->bind_mounts[i].source,
+ c->bind_mounts[i].destination,
+ c->bind_mounts[i].recursive ? "rbind" : "norbind");
+ }
+
if (c->utmp_id)
fprintf(f,
"%sUtmpIdentifier: %s\n",
@@ -3528,6 +3588,15 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
fputc('\n', f);
}
+ if (exec_context_restrict_namespaces_set(c)) {
+ _cleanup_free_ char *s = NULL;
+
+ r = namespace_flag_to_string_many(c->restrict_namespaces, &s);
+ if (r >= 0)
+ fprintf(f, "%sRestrictNamespaces: %s\n",
+ prefix, s);
+ }
+
if (c->syscall_errno > 0)
fprintf(f,
"%sSystemCallErrorNumber: %s\n",
diff --git a/src/core/execute.h b/src/core/execute.h
index c7d0f7761e..c2e41f3695 100644
--- a/src/core/execute.h
+++ b/src/core/execute.h
@@ -35,6 +35,7 @@ typedef struct ExecParameters ExecParameters;
#include "list.h"
#include "missing.h"
#include "namespace.h"
+#include "nsflags.h"
typedef enum ExecUtmpMode {
EXEC_UTMP_INIT,
@@ -105,7 +106,7 @@ struct ExecContext {
char **pass_environment;
struct rlimit *rlimit[_RLIMIT_MAX];
- char *working_directory, *root_directory;
+ char *working_directory, *root_directory, *root_image;
bool working_directory_missing_ok;
bool working_directory_home;
@@ -160,6 +161,8 @@ struct ExecContext {
char **read_write_paths, **read_only_paths, **inaccessible_paths;
unsigned long mount_flags;
+ BindMount *bind_mounts;
+ unsigned n_bind_mounts;
uint64_t capability_bounding_set;
uint64_t capability_ambient_set;
@@ -180,6 +183,7 @@ struct ExecContext {
bool protect_kernel_tunables;
bool protect_kernel_modules;
bool protect_control_groups;
+ bool mount_apivfs;
bool no_new_privileges;
@@ -195,6 +199,8 @@ struct ExecContext {
unsigned long personality;
+ unsigned long restrict_namespaces; /* The CLONE_NEWxyz flags permitted to the unit's processes */
+
Set *syscall_filter;
Set *syscall_archs;
int syscall_errno;
@@ -213,20 +219,24 @@ struct ExecContext {
bool nice_set:1;
bool ioprio_set:1;
bool cpu_sched_set:1;
- bool no_new_privileges_set:1;
};
+static inline bool exec_context_restrict_namespaces_set(const ExecContext *c) {
+ assert(c);
+
+ return (c->restrict_namespaces & NAMESPACE_FLAGS_ALL) != NAMESPACE_FLAGS_ALL;
+}
+
typedef enum ExecFlags {
- EXEC_CONFIRM_SPAWN = 1U << 0,
- EXEC_APPLY_PERMISSIONS = 1U << 1,
- EXEC_APPLY_CHROOT = 1U << 2,
- EXEC_APPLY_TTY_STDIN = 1U << 3,
+ EXEC_APPLY_PERMISSIONS = 1U << 0,
+ EXEC_APPLY_CHROOT = 1U << 1,
+ EXEC_APPLY_TTY_STDIN = 1U << 2,
/* The following are not used by execute.c, but by consumers internally */
- EXEC_PASS_FDS = 1U << 4,
- EXEC_IS_CONTROL = 1U << 5,
- EXEC_SETENV_RESULT = 1U << 6,
- EXEC_SET_WATCHDOG = 1U << 7,
+ EXEC_PASS_FDS = 1U << 3,
+ EXEC_IS_CONTROL = 1U << 4,
+ EXEC_SETENV_RESULT = 1U << 5,
+ EXEC_SET_WATCHDOG = 1U << 6,
} ExecFlags;
struct ExecParameters {
@@ -246,6 +256,8 @@ struct ExecParameters {
const char *runtime_prefix;
+ const char *confirm_spawn;
+
usec_t watchdog_usec;
int *idle_pipe;
diff --git a/src/core/hostname-setup.c b/src/core/hostname-setup.c
index 68be52856b..845e31e1c5 100644
--- a/src/core/hostname-setup.c
+++ b/src/core/hostname-setup.c
@@ -31,10 +31,10 @@
#include "util.h"
int hostname_setup(void) {
- int r;
_cleanup_free_ char *b = NULL;
- const char *hn;
bool enoent = false;
+ const char *hn;
+ int r;
r = read_hostname_config("/etc/hostname", &b);
if (r < 0) {
@@ -56,7 +56,7 @@ int hostname_setup(void) {
if (enoent)
log_info("No hostname configured.");
- hn = "localhost";
+ hn = FALLBACK_HOSTNAME;
}
r = sethostname_idempotent(hn);
diff --git a/src/core/ima-setup.c b/src/core/ima-setup.c
index d1b0ce76ef..94ae429f46 100644
--- a/src/core/ima-setup.c
+++ b/src/core/ima-setup.c
@@ -44,6 +44,22 @@ int ima_setup(void) {
return 0;
}
+ if (access(IMA_SECFS_POLICY, W_OK) < 0) {
+ log_warning("Another IMA custom policy has already been loaded, ignoring.");
+ return 0;
+ }
+
+ imafd = open(IMA_SECFS_POLICY, O_WRONLY|O_CLOEXEC);
+ if (imafd < 0) {
+ log_error_errno(errno, "Failed to open the IMA kernel interface "IMA_SECFS_POLICY", ignoring: %m");
+ return 0;
+ }
+
+ /* attempt to write the name of the policy file into sysfs file */
+ if (write(imafd, IMA_POLICY_PATH, strlen(IMA_POLICY_PATH)) > 0)
+ goto done;
+
+ /* fall back to copying the policy line-by-line */
input = fopen(IMA_POLICY_PATH, "re");
if (!input) {
log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
@@ -51,10 +67,7 @@ int ima_setup(void) {
return 0;
}
- if (access(IMA_SECFS_POLICY, F_OK) < 0) {
- log_warning("Another IMA custom policy has already been loaded, ignoring.");
- return 0;
- }
+ close(imafd);
imafd = open(IMA_SECFS_POLICY, O_WRONLY|O_CLOEXEC);
if (imafd < 0) {
@@ -74,6 +87,7 @@ int ima_setup(void) {
lineno);
}
+done:
log_info("Successfully loaded the IMA custom policy "IMA_POLICY_PATH".");
#endif /* HAVE_IMA */
return 0;
diff --git a/src/core/job.c b/src/core/job.c
index ac6910a906..82c0ed80b4 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -90,9 +90,12 @@ void job_free(Job *j) {
if (j->in_dbus_queue)
LIST_REMOVE(dbus_queue, j->manager->dbus_job_queue, j);
+ if (j->in_gc_queue)
+ LIST_REMOVE(gc_queue, j->manager->gc_job_queue, j);
+
sd_event_source_unref(j->timer_event_source);
- sd_bus_track_unref(j->clients);
+ sd_bus_track_unref(j->bus_track);
strv_free(j->deserialized_clients);
free(j);
@@ -226,6 +229,9 @@ Job* job_install(Job *j) {
log_unit_debug(j->unit,
"Installed new job %s/%s as %u",
j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
+
+ job_add_to_gc_queue(j);
+
return j;
}
@@ -267,7 +273,8 @@ JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool
* this means the 'anchor' job (i.e. the one the user
* explicitly asked for) is the requester. */
- if (!(l = new0(JobDependency, 1)))
+ l = new0(JobDependency, 1);
+ if (!l)
return NULL;
l->subject = subject;
@@ -457,9 +464,7 @@ static bool job_is_runnable(Job *j) {
if (j->type == JOB_NOP)
return true;
- if (j->type == JOB_START ||
- j->type == JOB_VERIFY_ACTIVE ||
- j->type == JOB_RELOAD) {
+ if (IN_SET(j->type, JOB_START, JOB_VERIFY_ACTIVE, JOB_RELOAD)) {
/* Immediate result is that the job is or might be
* started. In this case let's wait for the
@@ -476,8 +481,7 @@ static bool job_is_runnable(Job *j) {
SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i)
if (other->job &&
- (other->job->type == JOB_STOP ||
- other->job->type == JOB_RESTART))
+ IN_SET(other->job->type, JOB_STOP, JOB_RESTART))
return false;
/* This means that for a service a and a service b where b
@@ -623,6 +627,8 @@ int job_run_and_invalidate(Job *j) {
r = job_finish_and_invalidate(j, JOB_ASSERT, true, false);
else if (r == -EOPNOTSUPP)
r = job_finish_and_invalidate(j, JOB_UNSUPPORTED, true, false);
+ else if (r == -ENOLINK)
+ r = job_finish_and_invalidate(j, JOB_DEPENDENCY, true, false);
else if (r == -EAGAIN)
job_set_state(j, JOB_WAITING);
else if (r < 0)
@@ -641,6 +647,7 @@ _pure_ static const char *job_get_status_message_format(Unit *u, JobType t, JobR
[JOB_DEPENDENCY] = "Dependency failed for %s.",
[JOB_ASSERT] = "Assertion failed for %s.",
[JOB_UNSUPPORTED] = "Starting of %s not supported.",
+ [JOB_COLLECTED] = "Unnecessary job for %s was removed.",
};
static const char *const generic_finished_stop_job[_JOB_RESULT_MAX] = {
[JOB_DONE] = "Stopped %s.",
@@ -689,19 +696,20 @@ _pure_ static const char *job_get_status_message_format(Unit *u, JobType t, JobR
return NULL;
}
-static void job_print_status_message(Unit *u, JobType t, JobResult result) {
- static const struct {
- const char *color, *word;
- } const statuses[_JOB_RESULT_MAX] = {
- [JOB_DONE] = { ANSI_GREEN, " OK " },
- [JOB_TIMEOUT] = { ANSI_HIGHLIGHT_RED, " TIME " },
- [JOB_FAILED] = { ANSI_HIGHLIGHT_RED, "FAILED" },
- [JOB_DEPENDENCY] = { ANSI_HIGHLIGHT_YELLOW, "DEPEND" },
- [JOB_SKIPPED] = { ANSI_HIGHLIGHT, " INFO " },
- [JOB_ASSERT] = { ANSI_HIGHLIGHT_YELLOW, "ASSERT" },
- [JOB_UNSUPPORTED] = { ANSI_HIGHLIGHT_YELLOW, "UNSUPP" },
- };
+static const struct {
+ const char *color, *word;
+} job_print_status_messages [_JOB_RESULT_MAX] = {
+ [JOB_DONE] = { ANSI_GREEN, " OK " },
+ [JOB_TIMEOUT] = { ANSI_HIGHLIGHT_RED, " TIME " },
+ [JOB_FAILED] = { ANSI_HIGHLIGHT_RED, "FAILED" },
+ [JOB_DEPENDENCY] = { ANSI_HIGHLIGHT_YELLOW, "DEPEND" },
+ [JOB_SKIPPED] = { ANSI_HIGHLIGHT, " INFO " },
+ [JOB_ASSERT] = { ANSI_HIGHLIGHT_YELLOW, "ASSERT" },
+ [JOB_UNSUPPORTED] = { ANSI_HIGHLIGHT_YELLOW, "UNSUPP" },
+ /* JOB_COLLECTED */
+};
+static void job_print_status_message(Unit *u, JobType t, JobResult result) {
const char *format;
const char *status;
@@ -713,14 +721,19 @@ static void job_print_status_message(Unit *u, JobType t, JobResult result) {
if (t == JOB_RELOAD)
return;
+ if (!job_print_status_messages[result].word)
+ return;
+
format = job_get_status_message_format(u, t, result);
if (!format)
return;
if (log_get_show_color())
- status = strjoina(statuses[result].color, statuses[result].word, ANSI_NORMAL);
+ status = strjoina(job_print_status_messages[result].color,
+ job_print_status_messages[result].word,
+ ANSI_NORMAL);
else
- status = statuses[result].word;
+ status = job_print_status_messages[result].word;
if (result != JOB_DONE)
manager_flip_auto_status(u->manager, true);
@@ -738,9 +751,8 @@ static void job_print_status_message(Unit *u, JobType t, JobResult result) {
}
static void job_log_status_message(Unit *u, JobType t, JobResult result) {
- const char *format;
+ const char *format, *mid;
char buf[LINE_MAX];
- sd_id128_t mid;
static const int job_result_log_level[_JOB_RESULT_MAX] = {
[JOB_DONE] = LOG_INFO,
[JOB_CANCELED] = LOG_INFO,
@@ -751,16 +763,16 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
[JOB_INVALID] = LOG_INFO,
[JOB_ASSERT] = LOG_WARNING,
[JOB_UNSUPPORTED] = LOG_WARNING,
+ [JOB_COLLECTED] = LOG_INFO,
};
assert(u);
assert(t >= 0);
assert(t < _JOB_TYPE_MAX);
- /* Skip this if it goes to the console. since we already print
- * to the console anyway... */
-
- if (log_on_console())
+ /* Skip printing if output goes to the console, and job_print_status_message()
+ will actually print something to the console. */
+ if (log_on_console() && job_print_status_messages[result].word)
return;
format = job_get_status_message_format(u, t, result);
@@ -775,16 +787,19 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
switch (t) {
case JOB_START:
- mid = result == JOB_DONE ? SD_MESSAGE_UNIT_STARTED : SD_MESSAGE_UNIT_FAILED;
+ if (result == JOB_DONE)
+ mid = "MESSAGE_ID=" SD_MESSAGE_UNIT_STARTED_STR;
+ else
+ mid = "MESSAGE_ID=" SD_MESSAGE_UNIT_FAILED_STR;
break;
case JOB_RELOAD:
- mid = SD_MESSAGE_UNIT_RELOADED;
+ mid = "MESSAGE_ID=" SD_MESSAGE_UNIT_RELOADED_STR;
break;
case JOB_STOP:
case JOB_RESTART:
- mid = SD_MESSAGE_UNIT_STOPPED;
+ mid = "MESSAGE_ID=" SD_MESSAGE_UNIT_STOPPED_STR;
break;
default:
@@ -797,7 +812,7 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
}
log_struct(job_result_log_level[result],
- LOG_MESSAGE_ID(mid),
+ mid,
LOG_UNIT_ID(u),
LOG_MESSAGE("%s", buf),
"RESULT=%s", job_result_to_string(result),
@@ -862,6 +877,7 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool alr
job_set_state(j, JOB_WAITING);
job_add_to_run_queue(j);
+ job_add_to_gc_queue(j);
goto finish;
}
@@ -905,11 +921,15 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool alr
finish:
/* Try to start the next jobs that can be started */
SET_FOREACH(other, u->dependencies[UNIT_AFTER], i)
- if (other->job)
+ if (other->job) {
job_add_to_run_queue(other->job);
+ job_add_to_gc_queue(other->job);
+ }
SET_FOREACH(other, u->dependencies[UNIT_BEFORE], i)
- if (other->job)
+ if (other->job) {
job_add_to_run_queue(other->job);
+ job_add_to_gc_queue(other->job);
+ }
manager_check_finished(u->manager);
@@ -1012,7 +1032,7 @@ int job_serialize(Job *j, FILE *f) {
if (j->begin_usec > 0)
fprintf(f, "job-begin="USEC_FMT"\n", j->begin_usec);
- bus_track_serialize(j->clients, f, "subscribed");
+ bus_track_serialize(j->bus_track, f, "subscribed");
/* End marker */
fputc('\n', f);
@@ -1123,12 +1143,14 @@ int job_coldplug(Job *j) {
/* After deserialization is complete and the bus connection
* set up again, let's start watching our subscribers again */
- (void) bus_track_coldplug(j->manager, &j->clients, false, j->deserialized_clients);
- j->deserialized_clients = strv_free(j->deserialized_clients);
+ (void) bus_job_coldplug_bus_track(j);
if (j->state == JOB_WAITING)
job_add_to_run_queue(j);
+ /* Maybe due to new dependencies we don't actually need this job anymore? */
+ job_add_to_gc_queue(j);
+
if (j->begin_usec == 0 || j->unit->job_timeout == USEC_INFINITY)
return 0;
@@ -1203,9 +1225,223 @@ int job_get_timeout(Job *j, usec_t *timeout) {
return 1;
}
+bool job_check_gc(Job *j) {
+ Unit *other;
+ Iterator i;
+
+ assert(j);
+
+ /* Checks whether this job should be GC'ed away. We only do this for jobs of units that have no effect on their
+ * own and just track external state. For now the only unit type that qualifies for this are .device units. */
+
+ if (!UNIT_VTABLE(j->unit)->gc_jobs)
+ return true;
+
+ if (sd_bus_track_count(j->bus_track) > 0)
+ return true;
+
+ /* FIXME: So this is a bit ugly: for now we don't properly track references made via private bus connections
+ * (because it's nasty, as sd_bus_track doesn't apply to it). We simply remember that the job was once
+ * referenced by one, and reset this whenever we notice that no private bus connections are around. This means
+ * the GC is a bit too conservative when it comes to jobs created by private bus connections. */
+ if (j->ref_by_private_bus) {
+ if (set_isempty(j->unit->manager->private_buses))
+ j->ref_by_private_bus = false;
+ else
+ return true;
+ }
+
+ if (j->type == JOB_NOP)
+ return true;
+
+ /* If a job is ordered after ours, and is to be started, then it needs to wait for us, regardless if we stop or
+ * start, hence let's not GC in that case. */
+ SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i) {
+ if (!other->job)
+ continue;
+
+ if (other->job->ignore_order)
+ continue;
+
+ if (IN_SET(other->job->type, JOB_START, JOB_VERIFY_ACTIVE, JOB_RELOAD))
+ return true;
+ }
+
+ /* If we are going down, but something else is ordered After= us, then it needs to wait for us */
+ if (IN_SET(j->type, JOB_STOP, JOB_RESTART))
+ SET_FOREACH(other, j->unit->dependencies[UNIT_AFTER], i) {
+ if (!other->job)
+ continue;
+
+ if (other->job->ignore_order)
+ continue;
+
+ return true;
+ }
+
+ /* The logic above is kinda the inverse of the job_is_runnable() logic. Specifically, if the job "we" is
+ * ordered before the job "other":
+ *
+ * we start + other start → stay
+ * we start + other stop → gc
+ * we stop + other start → stay
+ * we stop + other stop → gc
+ *
+ * "we" are ordered after "other":
+ *
+ * we start + other start → gc
+ * we start + other stop → gc
+ * we stop + other start → stay
+ * we stop + other stop → stay
+ *
+ */
+
+ return false;
+}
+
+void job_add_to_gc_queue(Job *j) {
+ assert(j);
+
+ if (j->in_gc_queue)
+ return;
+
+ if (job_check_gc(j))
+ return;
+
+ LIST_PREPEND(gc_queue, j->unit->manager->gc_job_queue, j);
+ j->in_gc_queue = true;
+}
+
+static int job_compare(const void *a, const void *b) {
+ Job *x = *(Job**) a, *y = *(Job**) b;
+
+ if (x->id < y->id)
+ return -1;
+ if (x->id > y->id)
+ return 1;
+
+ return 0;
+}
+
+static size_t sort_job_list(Job **list, size_t n) {
+ Job *previous = NULL;
+ size_t a, b;
+
+ /* Order by numeric IDs */
+ qsort_safe(list, n, sizeof(Job*), job_compare);
+
+ /* Filter out duplicates */
+ for (a = 0, b = 0; a < n; a++) {
+
+ if (previous == list[a])
+ continue;
+
+ previous = list[b++] = list[a];
+ }
+
+ return b;
+}
+
+int job_get_before(Job *j, Job*** ret) {
+ _cleanup_free_ Job** list = NULL;
+ size_t n = 0, n_allocated = 0;
+ Unit *other = NULL;
+ Iterator i;
+
+ /* Returns a list of all pending jobs that need to finish before this job may be started. */
+
+ assert(j);
+ assert(ret);
+
+ if (j->ignore_order) {
+ *ret = NULL;
+ return 0;
+ }
+
+ if (IN_SET(j->type, JOB_START, JOB_VERIFY_ACTIVE, JOB_RELOAD)) {
+
+ SET_FOREACH(other, j->unit->dependencies[UNIT_AFTER], i) {
+ if (!other->job)
+ continue;
+
+ if (!GREEDY_REALLOC(list, n_allocated, n+1))
+ return -ENOMEM;
+ list[n++] = other->job;
+ }
+ }
+
+ SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i) {
+ if (!other->job)
+ continue;
+
+ if (!IN_SET(other->job->type, JOB_STOP, JOB_RESTART))
+ continue;
+
+ if (!GREEDY_REALLOC(list, n_allocated, n+1))
+ return -ENOMEM;
+ list[n++] = other->job;
+ }
+
+ n = sort_job_list(list, n);
+
+ *ret = list;
+ list = NULL;
+
+ return (int) n;
+}
+
+int job_get_after(Job *j, Job*** ret) {
+ _cleanup_free_ Job** list = NULL;
+ size_t n = 0, n_allocated = 0;
+ Unit *other = NULL;
+ Iterator i;
+
+ assert(j);
+ assert(ret);
+
+ /* Returns a list of all pending jobs that are waiting for this job to finish. */
+
+ SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i) {
+ if (!other->job)
+ continue;
+
+ if (other->job->ignore_order)
+ continue;
+
+ if (!IN_SET(other->job->type, JOB_START, JOB_VERIFY_ACTIVE, JOB_RELOAD))
+ continue;
+
+ if (!GREEDY_REALLOC(list, n_allocated, n+1))
+ return -ENOMEM;
+ list[n++] = other->job;
+ }
+
+ if (IN_SET(j->type, JOB_STOP, JOB_RESTART)) {
+
+ SET_FOREACH(other, j->unit->dependencies[UNIT_AFTER], i) {
+ if (!other->job)
+ continue;
+
+ if (other->job->ignore_order)
+ continue;
+
+ if (!GREEDY_REALLOC(list, n_allocated, n+1))
+ return -ENOMEM;
+ list[n++] = other->job;
+ }
+ }
+
+ n = sort_job_list(list, n);
+
+ *ret = list;
+ list = NULL;
+
+ return (int) n;
+}
+
static const char* const job_state_table[_JOB_STATE_MAX] = {
[JOB_WAITING] = "waiting",
- [JOB_RUNNING] = "running"
+ [JOB_RUNNING] = "running",
};
DEFINE_STRING_TABLE_LOOKUP(job_state, JobState);
@@ -1246,6 +1482,7 @@ static const char* const job_result_table[_JOB_RESULT_MAX] = {
[JOB_INVALID] = "invalid",
[JOB_ASSERT] = "assert",
[JOB_UNSUPPORTED] = "unsupported",
+ [JOB_COLLECTED] = "collected",
};
DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult);
diff --git a/src/core/job.h b/src/core/job.h
index 85368f0d30..bea743f462 100644
--- a/src/core/job.h
+++ b/src/core/job.h
@@ -107,6 +107,7 @@ enum JobResult {
JOB_INVALID, /* JOB_RELOAD of inactive unit */
JOB_ASSERT, /* Couldn't start a unit, because an assert didn't hold */
JOB_UNSUPPORTED, /* Couldn't start a unit, because the unit type is not supported on the system */
+ JOB_COLLECTED, /* Job was garbage collected, since nothing needed it anymore */
_JOB_RESULT_MAX,
_JOB_RESULT_INVALID = -1
};
@@ -122,8 +123,8 @@ struct JobDependency {
LIST_FIELDS(JobDependency, subject);
LIST_FIELDS(JobDependency, object);
- bool matters;
- bool conflicts;
+ bool matters:1;
+ bool conflicts:1;
};
struct Job {
@@ -133,6 +134,7 @@ struct Job {
LIST_FIELDS(Job, transaction);
LIST_FIELDS(Job, run_queue);
LIST_FIELDS(Job, dbus_queue);
+ LIST_FIELDS(Job, gc_queue);
LIST_HEAD(JobDependency, subject_list);
LIST_HEAD(JobDependency, object_list);
@@ -156,7 +158,7 @@ struct Job {
*
* There can be more than one client, because of job merging.
*/
- sd_bus_track *clients;
+ sd_bus_track *bus_track;
char **deserialized_clients;
JobResult result;
@@ -168,6 +170,8 @@ struct Job {
bool sent_dbus_new_signal:1;
bool ignore_order:1;
bool irreversible:1;
+ bool in_gc_queue:1;
+ bool ref_by_private_bus:1;
};
Job* job_new(Unit *unit, JobType type);
@@ -227,6 +231,12 @@ void job_shutdown_magic(Job *j);
int job_get_timeout(Job *j, usec_t *timeout) _pure_;
+bool job_check_gc(Job *j);
+void job_add_to_gc_queue(Job *j);
+
+int job_get_before(Job *j, Job*** ret);
+int job_get_after(Job *j, Job*** ret);
+
const char* job_type_to_string(JobType t) _const_;
JobType job_type_from_string(const char *s) _pure_;
diff --git a/src/core/killall.c b/src/core/killall.c
index a8b814e868..3fe9fa2ed0 100644
--- a/src/core/killall.c
+++ b/src/core/killall.c
@@ -24,8 +24,9 @@
#include "alloc-util.h"
#include "def.h"
+#include "dirent-util.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "killall.h"
#include "parse-util.h"
#include "process-util.h"
@@ -65,29 +66,26 @@ static bool ignore_proc(pid_t pid, bool warn_rootfs) {
if (count <= 0)
return true;
- /* Processes with argv[0][0] = '@' we ignore from the killing
- * spree.
+ /* Processes with argv[0][0] = '@' we ignore from the killing spree.
*
* http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons */
- if (c == '@' && warn_rootfs) {
- _cleanup_free_ char *comm = NULL;
+ if (c != '@')
+ return false;
- r = pid_from_same_root_fs(pid);
- if (r < 0)
- return true;
+ if (warn_rootfs &&
+ pid_from_same_root_fs(pid) == 0) {
+
+ _cleanup_free_ char *comm = NULL;
get_process_comm(pid, &comm);
- if (r)
- log_notice("Process " PID_FMT " (%s) has been marked to be excluded from killing. It is "
- "running from the root file system, and thus likely to block re-mounting of the "
- "root file system to read-only. Please consider moving it into an initrd file "
- "system instead.", pid, strna(comm));
- return true;
- } else if (c == '@')
- return true;
+ log_notice("Process " PID_FMT " (%s) has been marked to be excluded from killing. It is "
+ "running from the root file system, and thus likely to block re-mounting of the "
+ "root file system to read-only. Please consider moving it into an initrd file "
+ "system instead.", pid, strna(comm));
+ }
- return false;
+ return true;
}
static void wait_for_children(Set *pids, sigset_t *mask) {
@@ -172,7 +170,7 @@ static int killall(int sig, Set *pids, bool send_sighup) {
if (!dir)
return -errno;
- while ((d = readdir(dir))) {
+ FOREACH_DIRENT_ALL(d, dir, break) {
pid_t pid;
int r;
@@ -215,7 +213,8 @@ static int killall(int sig, Set *pids, bool send_sighup) {
if (get_ctty_devnr(pid, NULL) >= 0)
- kill(pid, SIGHUP);
+ /* it's OK if the process is gone, just ignore the result */
+ (void) kill(pid, SIGHUP);
}
}
diff --git a/src/core/load-dropin.c b/src/core/load-dropin.c
index f83fa09301..3180f911bb 100644
--- a/src/core/load-dropin.c
+++ b/src/core/load-dropin.c
@@ -19,51 +19,123 @@
#include "conf-parser.h"
+#include "fs-util.h"
#include "load-dropin.h"
#include "load-fragment.h"
#include "log.h"
+#include "stat-util.h"
+#include "string-util.h"
#include "strv.h"
#include "unit-name.h"
#include "unit.h"
-static int add_dependency_consumer(
- UnitDependency dependency,
- const char *entry,
- const char* filepath,
- void *arg) {
- Unit *u = arg;
+static bool unit_name_compatible(const char *a, const char *b) {
+ _cleanup_free_ char *prefix = NULL;
int r;
- assert(u);
+ /* the straightforward case: the symlink name matches the target */
+ if (streq(a, b))
+ return true;
+
+ r = unit_name_template(a, &prefix);
+ if (r == -EINVAL)
+ /* not a template */
+ return false;
+ if (r < 0)
+ /* oom, or some other failure. Just skip the warning. */
+ return true;
+
+ /* an instance name points to a target that is just the template name */
+ if (streq(prefix, b))
+ return true;
+
+ return false;
+}
+
+static int process_deps(Unit *u, UnitDependency dependency, const char *dir_suffix) {
+ _cleanup_strv_free_ char **paths = NULL;
+ char **p;
+ int r;
- r = unit_add_dependency_by_name(u, dependency, entry, filepath, true);
+ r = unit_file_find_dropin_paths(NULL,
+ u->manager->lookup_paths.search_path,
+ u->manager->unit_path_cache,
+ dir_suffix,
+ NULL,
+ u->names,
+ &paths);
if (r < 0)
- log_error_errno(r, "Cannot add dependency %s to %s, ignoring: %m", entry, u->id);
+ return r;
+
+ STRV_FOREACH(p, paths) {
+ const char *entry;
+ _cleanup_free_ char *target = NULL;
+
+ entry = basename(*p);
+
+ if (null_or_empty_path(*p) > 0) {
+ /* an error usually means an invalid symlink, which is not a mask */
+ log_unit_debug(u, "%s dependency on %s is masked by %s, ignoring.",
+ unit_dependency_to_string(dependency), entry, *p);
+ continue;
+ }
+
+ r = is_symlink(*p);
+ if (r < 0) {
+ log_unit_warning_errno(u, r, "%s dropin %s unreadable, ignoring: %m",
+ unit_dependency_to_string(dependency), *p);
+ continue;
+ }
+ if (r == 0) {
+ log_unit_warning(u, "%s dependency dropin %s is not a symlink, ignoring.",
+ unit_dependency_to_string(dependency), *p);
+ continue;
+ }
+
+ if (!unit_name_is_valid(entry, UNIT_NAME_ANY)) {
+ log_unit_warning(u, "%s dependency dropin %s is not a valid unit name, ignoring.",
+ unit_dependency_to_string(dependency), *p);
+ continue;
+ }
+
+ r = readlink_malloc(*p, &target);
+ if (r < 0) {
+ log_unit_warning_errno(u, r, "readlink(\"%s\") failed, ignoring: %m", *p);
+ continue;
+ }
+
+ /* We don't treat this as an error, especially because we didn't check this for a
+ * long time. Nevertheless, we warn, because such mismatch can be mighty confusing. */
+ if (!unit_name_compatible(entry, basename(target)))
+ log_unit_warning(u, "%s dependency dropin %s target %s has different name",
+ unit_dependency_to_string(dependency), *p, target);
+
+ r = unit_add_dependency_by_name(u, dependency, entry, *p, true);
+ if (r < 0)
+ log_unit_error_errno(u, r, "cannot add %s dependency on %s, ignoring: %m",
+ unit_dependency_to_string(dependency), entry);
+ }
return 0;
}
int unit_load_dropin(Unit *u) {
_cleanup_strv_free_ char **l = NULL;
- Iterator i;
- char *t, **f;
+ char **f;
int r;
assert(u);
- /* Load dependencies from supplementary drop-in directories */
-
- SET_FOREACH(t, u->names, i) {
- char **p;
+ /* Load dependencies from .wants and .requires directories */
+ r = process_deps(u, UNIT_WANTS, ".wants");
+ if (r < 0)
+ return r;
- STRV_FOREACH(p, u->manager->lookup_paths.search_path) {
- unit_file_process_dir(u->manager->unit_path_cache, *p, t, ".wants", UNIT_WANTS,
- add_dependency_consumer, u, NULL);
- unit_file_process_dir(u->manager->unit_path_cache, *p, t, ".requires", UNIT_REQUIRES,
- add_dependency_consumer, u, NULL);
- }
- }
+ r = process_deps(u, UNIT_REQUIRES, ".requires");
+ if (r < 0)
+ return r;
+ /* Load .conf dropins */
r = unit_find_dropin_paths(u, &l);
if (r <= 0)
return 0;
diff --git a/src/core/load-dropin.h b/src/core/load-dropin.h
index 942d26724e..5828a223ce 100644
--- a/src/core/load-dropin.h
+++ b/src/core/load-dropin.h
@@ -25,10 +25,11 @@
/* Read service data supplementary drop-in directories */
static inline int unit_find_dropin_paths(Unit *u, char ***paths) {
- return unit_file_find_dropin_paths(u->manager->lookup_paths.search_path,
- u->manager->unit_path_cache,
- u->names,
- paths);
+ return unit_file_find_dropin_conf_paths(NULL,
+ u->manager->lookup_paths.search_path,
+ u->manager->unit_path_cache,
+ u->names,
+ paths);
}
int unit_load_dropin(Unit *u);
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index af2f9d960b..3f7cbaa0d0 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -19,6 +19,7 @@ m4_dnl Define the context options only once
m4_define(`EXEC_CONTEXT_CONFIG_ITEMS',
`$1.WorkingDirectory, config_parse_working_directory, 0, offsetof($1, exec_context)
$1.RootDirectory, config_parse_unit_path_printf, 0, offsetof($1, exec_context.root_directory)
+$1.RootImage, config_parse_unit_path_printf, 0, offsetof($1, exec_context.root_image)
$1.User, config_parse_user_group, 0, offsetof($1, exec_context.user)
$1.Group, config_parse_user_group, 0, offsetof($1, exec_context.group)
$1.SupplementaryGroups, config_parse_user_group_strv, 0, offsetof($1, exec_context.supplementary_groups)
@@ -57,12 +58,14 @@ m4_ifdef(`HAVE_SECCOMP',
$1.SystemCallArchitectures, config_parse_syscall_archs, 0, offsetof($1, exec_context.syscall_archs)
$1.SystemCallErrorNumber, config_parse_syscall_errno, 0, offsetof($1, exec_context)
$1.MemoryDenyWriteExecute, config_parse_bool, 0, offsetof($1, exec_context.memory_deny_write_execute)
+$1.RestrictNamespaces, config_parse_restrict_namespaces, 0, offsetof($1, exec_context)
$1.RestrictRealtime, config_parse_bool, 0, offsetof($1, exec_context.restrict_realtime)
$1.RestrictAddressFamilies, config_parse_address_families, 0, offsetof($1, exec_context)',
`$1.SystemCallFilter, config_parse_warn_compat, DISABLED_CONFIGURATION, 0
$1.SystemCallArchitectures, config_parse_warn_compat, DISABLED_CONFIGURATION, 0
$1.SystemCallErrorNumber, config_parse_warn_compat, DISABLED_CONFIGURATION, 0
$1.MemoryDenyWriteExecute, config_parse_warn_compat, DISABLED_CONFIGURATION, 0
+$1.RestrictNamespaces, config_parse_warn_compat, DISABLED_CONFIGURATION, 0
$1.RestrictRealtime, config_parse_warn_compat, DISABLED_CONFIGURATION, 0
$1.RestrictAddressFamilies, config_parse_warn_compat, DISABLED_CONFIGURATION, 0')
$1.LimitCPU, config_parse_limit, RLIMIT_CPU, offsetof($1, exec_context.rlimit)
@@ -87,6 +90,8 @@ $1.InaccessibleDirectories, config_parse_namespace_path_strv, 0,
$1.ReadWritePaths, config_parse_namespace_path_strv, 0, offsetof($1, exec_context.read_write_paths)
$1.ReadOnlyPaths, config_parse_namespace_path_strv, 0, offsetof($1, exec_context.read_only_paths)
$1.InaccessiblePaths, config_parse_namespace_path_strv, 0, offsetof($1, exec_context.inaccessible_paths)
+$1.BindPaths, config_parse_bind_paths, 0, offsetof($1, exec_context)
+$1.BindReadOnlyPaths, config_parse_bind_paths, 0, offsetof($1, exec_context)
$1.PrivateTmp, config_parse_bool, 0, offsetof($1, exec_context.private_tmp)
$1.PrivateDevices, config_parse_bool, 0, offsetof($1, exec_context.private_devices)
$1.ProtectKernelTunables, config_parse_bool, 0, offsetof($1, exec_context.protect_kernel_tunables)
@@ -97,6 +102,7 @@ $1.PrivateUsers, config_parse_bool, 0,
$1.ProtectSystem, config_parse_protect_system, 0, offsetof($1, exec_context)
$1.ProtectHome, config_parse_protect_home, 0, offsetof($1, exec_context)
$1.MountFlags, config_parse_exec_mount_flags, 0, offsetof($1, exec_context)
+$1.MountAPIVFS, config_parse_bool, 0, offsetof($1, exec_context.mount_apivfs)
$1.Personality, config_parse_personality, 0, offsetof($1, exec_context.personality)
$1.RuntimeDirectoryMode, config_parse_mode, 0, offsetof($1, exec_context.runtime_directory_mode)
$1.RuntimeDirectory, config_parse_runtime_directory, 0, offsetof($1, exec_context.runtime_directory)
@@ -189,13 +195,13 @@ Unit.IgnoreOnIsolate, config_parse_bool, 0,
Unit.IgnoreOnSnapshot, config_parse_warn_compat, DISABLED_LEGACY, 0
Unit.JobTimeoutSec, config_parse_sec_fix_0, 0, offsetof(Unit, job_timeout)
Unit.JobTimeoutAction, config_parse_emergency_action, 0, offsetof(Unit, job_timeout_action)
-Unit.JobTimeoutRebootArgument, config_parse_string, 0, offsetof(Unit, job_timeout_reboot_arg)
+Unit.JobTimeoutRebootArgument, config_parse_unit_string_printf, 0, offsetof(Unit, job_timeout_reboot_arg)
Unit.StartLimitIntervalSec, config_parse_sec, 0, offsetof(Unit, start_limit.interval)
m4_dnl The following is a legacy alias name for compatibility
Unit.StartLimitInterval, config_parse_sec, 0, offsetof(Unit, start_limit.interval)
Unit.StartLimitBurst, config_parse_unsigned, 0, offsetof(Unit, start_limit.burst)
Unit.StartLimitAction, config_parse_emergency_action, 0, offsetof(Unit, start_limit_action)
-Unit.RebootArgument, config_parse_string, 0, offsetof(Unit, reboot_arg)
+Unit.RebootArgument, config_parse_unit_string_printf, 0, offsetof(Unit, reboot_arg)
Unit.ConditionPathExists, config_parse_unit_condition_path, CONDITION_PATH_EXISTS, offsetof(Unit, conditions)
Unit.ConditionPathExistsGlob, config_parse_unit_condition_path, CONDITION_PATH_EXISTS_GLOB, offsetof(Unit, conditions)
Unit.ConditionPathIsDirectory, config_parse_unit_condition_path, CONDITION_PATH_IS_DIRECTORY, offsetof(Unit, conditions)
@@ -252,7 +258,7 @@ m4_dnl The following three only exist for compatibility, they moved into Unit, s
Service.StartLimitInterval, config_parse_sec, 0, offsetof(Unit, start_limit.interval)
Service.StartLimitBurst, config_parse_unsigned, 0, offsetof(Unit, start_limit.burst)
Service.StartLimitAction, config_parse_emergency_action, 0, offsetof(Unit, start_limit_action)
-Service.RebootArgument, config_parse_string, 0, offsetof(Unit, reboot_arg)
+Service.RebootArgument, config_parse_unit_path_printf, 0, offsetof(Unit, reboot_arg)
Service.FailureAction, config_parse_emergency_action, 0, offsetof(Service, emergency_action)
Service.Type, config_parse_service_type, 0, offsetof(Service, type)
Service.Restart, config_parse_service_restart, 0, offsetof(Service, restart)
@@ -270,8 +276,8 @@ Service.FileDescriptorStoreMax, config_parse_unsigned, 0,
Service.NotifyAccess, config_parse_notify_access, 0, offsetof(Service, notify_access)
Service.Sockets, config_parse_service_sockets, 0, 0
Service.BusPolicy, config_parse_warn_compat, DISABLED_LEGACY, 0
-Service.USBFunctionDescriptors, config_parse_path, 0, offsetof(Service, usb_function_descriptors)
-Service.USBFunctionStrings, config_parse_path, 0, offsetof(Service, usb_function_strings)
+Service.USBFunctionDescriptors, config_parse_unit_path_printf, 0, offsetof(Service, usb_function_descriptors)
+Service.USBFunctionStrings, config_parse_unit_path_printf, 0, offsetof(Service, usb_function_strings)
EXEC_CONTEXT_CONFIG_ITEMS(Service)m4_dnl
CGROUP_CONTEXT_CONFIG_ITEMS(Service)m4_dnl
KILL_CONTEXT_CONFIG_ITEMS(Service)m4_dnl
@@ -292,7 +298,7 @@ Socket.ExecStartPre, config_parse_exec, SOCKET_EXEC
Socket.ExecStartPost, config_parse_exec, SOCKET_EXEC_START_POST, offsetof(Socket, exec_command)
Socket.ExecStopPre, config_parse_exec, SOCKET_EXEC_STOP_PRE, offsetof(Socket, exec_command)
Socket.ExecStopPost, config_parse_exec, SOCKET_EXEC_STOP_POST, offsetof(Socket, exec_command)
-Socket.TimeoutSec, config_parse_sec, 0, offsetof(Socket, timeout_usec)
+Socket.TimeoutSec, config_parse_sec_fix_0, 0, offsetof(Socket, timeout_usec)
Socket.SocketUser, config_parse_user_group, 0, offsetof(Socket, user)
Socket.SocketGroup, config_parse_user_group, 0, offsetof(Socket, group)
Socket.SocketMode, config_parse_mode, 0, offsetof(Socket, socket_mode)
@@ -330,9 +336,9 @@ Socket.Service, config_parse_socket_service, 0,
Socket.TriggerLimitIntervalSec, config_parse_sec, 0, offsetof(Socket, trigger_limit.interval)
Socket.TriggerLimitBurst, config_parse_unsigned, 0, offsetof(Socket, trigger_limit.burst)
m4_ifdef(`HAVE_SMACK',
-`Socket.SmackLabel, config_parse_string, 0, offsetof(Socket, smack)
-Socket.SmackLabelIPIn, config_parse_string, 0, offsetof(Socket, smack_ip_in)
-Socket.SmackLabelIPOut, config_parse_string, 0, offsetof(Socket, smack_ip_out)',
+`Socket.SmackLabel, config_parse_unit_string_printf, 0, offsetof(Socket, smack)
+Socket.SmackLabelIPIn, config_parse_unit_string_printf, 0, offsetof(Socket, smack_ip_in)
+Socket.SmackLabelIPOut, config_parse_unit_string_printf, 0, offsetof(Socket, smack_ip_out)',
`Socket.SmackLabel, config_parse_warn_compat, DISABLED_CONFIGURATION, 0
Socket.SmackLabelIPIn, config_parse_warn_compat, DISABLED_CONFIGURATION, 0
Socket.SmackLabelIPOut, config_parse_warn_compat, DISABLED_CONFIGURATION, 0')
@@ -352,11 +358,11 @@ BusName.AllowWorld, config_parse_bus_policy_world, 0,
BusName.SELinuxContext, config_parse_exec_selinux_context, 0, 0
BusName.AcceptFileDescriptors, config_parse_bool, 0, offsetof(BusName, accept_fd)
m4_dnl
-Mount.What, config_parse_string, 0, offsetof(Mount, parameters_fragment.what)
+Mount.What, config_parse_unit_string_printf, 0, offsetof(Mount, parameters_fragment.what)
Mount.Where, config_parse_path, 0, offsetof(Mount, where)
-Mount.Options, config_parse_string, 0, offsetof(Mount, parameters_fragment.options)
+Mount.Options, config_parse_unit_string_printf, 0, offsetof(Mount, parameters_fragment.options)
Mount.Type, config_parse_string, 0, offsetof(Mount, parameters_fragment.fstype)
-Mount.TimeoutSec, config_parse_sec, 0, offsetof(Mount, timeout_usec)
+Mount.TimeoutSec, config_parse_sec_fix_0, 0, offsetof(Mount, timeout_usec)
Mount.DirectoryMode, config_parse_mode, 0, offsetof(Mount, directory_mode)
Mount.SloppyOptions, config_parse_bool, 0, offsetof(Mount, sloppy_options)
Mount.LazyUnmount, config_parse_bool, 0, offsetof(Mount, lazy_unmount)
@@ -367,12 +373,12 @@ KILL_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl
m4_dnl
Automount.Where, config_parse_path, 0, offsetof(Automount, where)
Automount.DirectoryMode, config_parse_mode, 0, offsetof(Automount, directory_mode)
-Automount.TimeoutIdleSec, config_parse_sec, 0, offsetof(Automount, timeout_idle_usec)
+Automount.TimeoutIdleSec, config_parse_sec_fix_0, 0, offsetof(Automount, timeout_idle_usec)
m4_dnl
Swap.What, config_parse_path, 0, offsetof(Swap, parameters_fragment.what)
Swap.Priority, config_parse_int, 0, offsetof(Swap, parameters_fragment.priority)
-Swap.Options, config_parse_string, 0, offsetof(Swap, parameters_fragment.options)
-Swap.TimeoutSec, config_parse_sec, 0, offsetof(Swap, timeout_usec)
+Swap.Options, config_parse_unit_string_printf, 0, offsetof(Swap, parameters_fragment.options)
+Swap.TimeoutSec, config_parse_sec_fix_0, 0, offsetof(Swap, timeout_usec)
EXEC_CONTEXT_CONFIG_ITEMS(Swap)m4_dnl
CGROUP_CONTEXT_CONFIG_ITEMS(Swap)m4_dnl
KILL_CONTEXT_CONFIG_ITEMS(Swap)m4_dnl
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index cbc826809e..5b7471c0d0 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -49,6 +49,7 @@
#include "load-fragment.h"
#include "log.h"
#include "missing.h"
+#include "mount-util.h"
#include "parse-util.h"
#include "path-util.h"
#include "process-util.h"
@@ -269,26 +270,33 @@ int config_parse_unit_path_strv_printf(
void *userdata) {
char ***x = data;
- const char *word, *state;
Unit *u = userdata;
- size_t l;
int r;
+ const char *p;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(u);
- FOREACH_WORD_QUOTED(word, l, rvalue, state) {
- _cleanup_free_ char *k = NULL;
- char t[l+1];
+ for (p = rvalue;;) {
+ _cleanup_free_ char *word = NULL, *k = NULL;
- memcpy(t, word, l);
- t[l] = 0;
+ r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
+ if (r == 0)
+ return 0;
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r < 0) {
+ log_syntax(unit, LOG_WARNING, filename, line, r,
+ "Invalid syntax, ignoring: %s", rvalue);
+ return 0;
+ }
- r = unit_full_printf(u, t, &k);
+ r = unit_full_printf(u, word, &k);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s, ignoring: %m", t);
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to resolve unit specifiers on \"%s\", ignoring: %m", word);
return 0;
}
@@ -298,7 +306,8 @@ int config_parse_unit_path_strv_printf(
}
if (!path_is_absolute(k)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Symlink path %s is not absolute, ignoring: %m", k);
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Symlink path is not absolute: %s", k);
return 0;
}
@@ -307,13 +316,8 @@ int config_parse_unit_path_strv_printf(
r = strv_push(x, k);
if (r < 0)
return log_oom();
-
k = NULL;
}
- if (!isempty(state))
- log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid syntax, ignoring.");
-
- return 0;
}
int config_parse_socket_listen(const char *unit,
@@ -576,6 +580,7 @@ int config_parse_exec(
void *userdata) {
ExecCommand **e = data;
+ Unit *u = userdata;
const char *p;
bool semicolon;
int r;
@@ -601,22 +606,21 @@ int config_parse_exec(
_cleanup_free_ ExecCommand *nce = NULL;
_cleanup_strv_free_ char **n = NULL;
size_t nlen = 0, nbufsize = 0;
- char *f;
- int i;
+ const char *f;
semicolon = false;
- r = extract_first_word_and_warn(&p, &firstword, WHITESPACE, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, unit, filename, line, rvalue);
+ r = extract_first_word_and_warn(&p, &firstword, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, unit, filename, line, rvalue);
if (r <= 0)
return 0;
f = firstword;
- for (i = 0; i < 3; i++) {
+ for (;;) {
/* We accept an absolute path as first argument.
* If it's prefixed with - and the path doesn't exist,
* we ignore it instead of erroring out;
* if it's prefixed with @, we allow overriding of argv[0];
- * and if it's prefixed with !, it will be run with full privileges */
+ * and if it's prefixed with +, it will be run with full privileges */
if (*f == '-' && !ignore)
ignore = true;
else if (*f == '@' && !separate_argv0)
@@ -628,47 +632,47 @@ int config_parse_exec(
f++;
}
- if (isempty(f)) {
+ r = unit_full_printf(u, f, &path);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s, ignoring: %m", f);
+ return 0;
+ }
+
+ if (isempty(path)) {
/* First word is either "-" or "@" with no command. */
log_syntax(unit, LOG_ERR, filename, line, 0, "Empty path in command line, ignoring: \"%s\"", rvalue);
return 0;
}
- if (!string_is_safe(f)) {
+ if (!string_is_safe(path)) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path contains special characters, ignoring: %s", rvalue);
return 0;
}
- if (!path_is_absolute(f)) {
+ if (!path_is_absolute(path)) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path is not absolute, ignoring: %s", rvalue);
return 0;
}
- if (endswith(f, "/")) {
+ if (endswith(path, "/")) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path specifies a directory, ignoring: %s", rvalue);
return 0;
}
- if (f == firstword) {
- path = firstword;
- firstword = NULL;
- } else {
- path = strdup(f);
- if (!path)
- return log_oom();
- }
-
if (!separate_argv0) {
+ char *w = NULL;
+
if (!GREEDY_REALLOC(n, nbufsize, nlen + 2))
return log_oom();
- f = strdup(path);
- if (!f)
+
+ w = strdup(path);
+ if (!w)
return log_oom();
- n[nlen++] = f;
+ n[nlen++] = w;
n[nlen] = NULL;
}
path_kill_slashes(path);
while (!isempty(p)) {
- _cleanup_free_ char *word = NULL;
+ _cleanup_free_ char *word = NULL, *resolved = NULL;
/* Check explicitly for an unquoted semicolon as
* command separator token. */
@@ -679,33 +683,42 @@ int config_parse_exec(
break;
}
- /* Check for \; explicitly, to not confuse it with \\;
- * or "\;" or "\\;" etc. extract_first_word would
- * return the same for all of those. */
+ /* Check for \; explicitly, to not confuse it with \\; or "\;" or "\\;" etc.
+ * extract_first_word() would return the same for all of those. */
if (p[0] == '\\' && p[1] == ';' && (!p[2] || strchr(WHITESPACE, p[2]))) {
+ char *w;
+
p += 2;
p += strspn(p, WHITESPACE);
+
if (!GREEDY_REALLOC(n, nbufsize, nlen + 2))
return log_oom();
- f = strdup(";");
- if (!f)
+
+ w = strdup(";");
+ if (!w)
return log_oom();
- n[nlen++] = f;
+ n[nlen++] = w;
n[nlen] = NULL;
continue;
}
- r = extract_first_word_and_warn(&p, &word, WHITESPACE, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, unit, filename, line, rvalue);
+ r = extract_first_word_and_warn(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, unit, filename, line, rvalue);
if (r == 0)
break;
- else if (r < 0)
+ if (r < 0)
+ return 0;
+
+ r = unit_full_printf(u, word, &resolved);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to resolve unit specifiers on %s, ignoring: %m", word);
return 0;
+ }
if (!GREEDY_REALLOC(n, nbufsize, nlen + 2))
return log_oom();
- n[nlen++] = word;
+ n[nlen++] = resolved;
n[nlen] = NULL;
- word = NULL;
+ resolved = NULL;
}
if (!n || !n[0]) {
@@ -1062,8 +1075,8 @@ int config_parse_exec_secure_bits(const char *unit,
void *userdata) {
ExecContext *c = data;
- size_t l;
- const char *word, *state;
+ const char *p;
+ int r;
assert(filename);
assert(lvalue);
@@ -1076,28 +1089,38 @@ int config_parse_exec_secure_bits(const char *unit,
return 0;
}
- FOREACH_WORD_QUOTED(word, l, rvalue, state) {
- if (first_word(word, "keep-caps"))
+ for (p = rvalue;;) {
+ _cleanup_free_ char *word = NULL;
+
+ r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
+ if (r == 0)
+ return 0;
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r < 0) {
+ log_syntax(unit, LOG_WARNING, filename, line, r,
+ "Invalid syntax, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ if (streq(word, "keep-caps"))
c->secure_bits |= 1<<SECURE_KEEP_CAPS;
- else if (first_word(word, "keep-caps-locked"))
+ else if (streq(word, "keep-caps-locked"))
c->secure_bits |= 1<<SECURE_KEEP_CAPS_LOCKED;
- else if (first_word(word, "no-setuid-fixup"))
+ else if (streq(word, "no-setuid-fixup"))
c->secure_bits |= 1<<SECURE_NO_SETUID_FIXUP;
- else if (first_word(word, "no-setuid-fixup-locked"))
+ else if (streq(word, "no-setuid-fixup-locked"))
c->secure_bits |= 1<<SECURE_NO_SETUID_FIXUP_LOCKED;
- else if (first_word(word, "noroot"))
+ else if (streq(word, "noroot"))
c->secure_bits |= 1<<SECURE_NOROOT;
- else if (first_word(word, "noroot-locked"))
+ else if (streq(word, "noroot-locked"))
c->secure_bits |= 1<<SECURE_NOROOT_LOCKED;
else {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse secure bits, ignoring: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Failed to parse secure bit \"%s\", ignoring.", word);
return 0;
}
}
- if (!isempty(state))
- log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid syntax, garbage at the end, ignoring.");
-
- return 0;
}
int config_parse_capability_set(
@@ -1242,38 +1265,30 @@ int config_parse_sysv_priority(const char *unit,
DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_utmp_mode, exec_utmp_mode, ExecUtmpMode, "Failed to parse utmp mode");
DEFINE_CONFIG_PARSE_ENUM(config_parse_kill_mode, kill_mode, KillMode, "Failed to parse kill mode");
-int config_parse_exec_mount_flags(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
+int config_parse_exec_mount_flags(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
- unsigned long flags = 0;
ExecContext *c = data;
+ int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
- if (streq(rvalue, "shared"))
- flags = MS_SHARED;
- else if (streq(rvalue, "slave"))
- flags = MS_SLAVE;
- else if (streq(rvalue, "private"))
- flags = MS_PRIVATE;
- else {
+ r = mount_propagation_flags_from_string(rvalue, &c->mount_flags);
+ if (r < 0)
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse mount flag %s, ignoring.", rvalue);
- return 0;
- }
-
- c->mount_flags = flags;
return 0;
}
@@ -1313,7 +1328,7 @@ int config_parse_exec_selinux_context(
} else
ignore = false;
- r = unit_name_printf(u, rvalue, &k);
+ r = unit_full_printf(u, rvalue, &k);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m");
return 0;
@@ -1361,7 +1376,7 @@ int config_parse_exec_apparmor_profile(
} else
ignore = false;
- r = unit_name_printf(u, rvalue, &k);
+ r = unit_full_printf(u, rvalue, &k);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m");
return 0;
@@ -1409,7 +1424,7 @@ int config_parse_exec_smack_process_label(
} else
ignore = false;
- r = unit_name_printf(u, rvalue, &k);
+ r = unit_full_printf(u, rvalue, &k);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m");
return 0;
@@ -1676,7 +1691,7 @@ int config_parse_fdname(
return 0;
}
- r = unit_name_printf(UNIT(s), rvalue, &p);
+ r = unit_full_printf(UNIT(s), rvalue, &p);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %s", rvalue);
return 0;
@@ -1951,7 +1966,7 @@ int config_parse_user_group_strv(
for (;;) {
_cleanup_free_ char *word = NULL, *k = NULL;
- r = extract_first_word(&p, &word, WHITESPACE, 0);
+ r = extract_first_word(&p, &word, NULL, 0);
if (r == 0)
break;
if (r == -ENOMEM)
@@ -2210,10 +2225,8 @@ int config_parse_environ(const char *unit,
void *userdata) {
Unit *u = userdata;
- char*** env = data;
- const char *word, *state;
- size_t l;
- _cleanup_free_ char *k = NULL;
+ char ***env = data;
+ const char *p;
int r;
assert(filename);
@@ -2227,46 +2240,43 @@ int config_parse_environ(const char *unit,
return 0;
}
- if (u) {
- r = unit_full_printf(u, rvalue, &k);
+ for (p = rvalue;; ) {
+ _cleanup_free_ char *word = NULL, *k = NULL;
+
+ r = extract_first_word(&p, &word, NULL, EXTRACT_CUNESCAPE|EXTRACT_QUOTES);
+ if (r == 0)
+ return 0;
+ if (r == -ENOMEM)
+ return log_oom();
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %s", rvalue);
+ log_syntax(unit, LOG_WARNING, filename, line, r,
+ "Invalid syntax, ignoring: %s", rvalue);
return 0;
}
- }
-
- if (!k) {
- k = strdup(rvalue);
- if (!k)
- return log_oom();
- }
-
- FOREACH_WORD_QUOTED(word, l, k, state) {
- _cleanup_free_ char *n = NULL;
- char **x;
- r = cunescape_length(word, l, 0, &n);
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Couldn't unescape assignment, ignoring: %s", rvalue);
- continue;
+ if (u) {
+ r = unit_full_printf(u, word, &k);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to resolve specifiers, ignoring: %s", k);
+ continue;
+ }
+ } else {
+ k = word;
+ word = NULL;
}
- if (!env_assignment_is_valid(n)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid environment assignment, ignoring: %s", rvalue);
+ if (!env_assignment_is_valid(k)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Invalid environment assignment, ignoring: %s", k);
continue;
}
- x = strv_env_set(*env, n);
- if (!x)
+ r = strv_env_replace(env, k);
+ if (r < 0)
return log_oom();
-
- strv_free(*env);
- *env = x;
+ k = NULL;
}
- if (!isempty(state))
- log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring.");
-
- return 0;
}
int config_parse_pass_environ(const char *unit,
@@ -2300,7 +2310,7 @@ int config_parse_pass_environ(const char *unit,
for (;;) {
_cleanup_free_ char *word = NULL;
- r = extract_first_word(&rvalue, &word, WHITESPACE, EXTRACT_QUOTES);
+ r = extract_first_word(&rvalue, &word, NULL, EXTRACT_QUOTES);
if (r == 0)
break;
if (r == -ENOMEM)
@@ -2538,37 +2548,45 @@ int config_parse_unit_requires_mounts_for(
void *userdata) {
Unit *u = userdata;
- const char *word, *state;
- size_t l;
+ const char *p;
+ int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
- FOREACH_WORD_QUOTED(word, l, rvalue, state) {
- int r;
- _cleanup_free_ char *n;
+ for (p = rvalue;; ) {
+ _cleanup_free_ char *word = NULL, *resolved = NULL;
- n = strndup(word, l);
- if (!n)
+ r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
+ if (r == 0)
+ return 0;
+ if (r == -ENOMEM)
return log_oom();
+ if (r < 0) {
+ log_syntax(unit, LOG_WARNING, filename, line, r,
+ "Invalid syntax, ignoring: %s", rvalue);
+ return 0;
+ }
- if (!utf8_is_valid(n)) {
+ if (!utf8_is_valid(word)) {
log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue);
continue;
}
- r = unit_require_mounts_for(u, n);
+ r = unit_full_printf(u, word, &resolved);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to add required mount for, ignoring: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit name \"%s\", ignoring: %m", word);
continue;
}
- }
- if (!isempty(state))
- log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring.");
- return 0;
+ r = unit_require_mounts_for(u, resolved);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to add required mount \"%s\", ignoring: %m", resolved);
+ continue;
+ }
+ }
}
int config_parse_documentation(const char *unit,
@@ -2760,8 +2778,7 @@ int config_parse_syscall_archs(
void *userdata) {
Set **archs = data;
- const char *word, *state;
- size_t l;
+ const char *p;
int r;
if (isempty(rvalue)) {
@@ -2773,30 +2790,32 @@ int config_parse_syscall_archs(
if (r < 0)
return log_oom();
- FOREACH_WORD_QUOTED(word, l, rvalue, state) {
- _cleanup_free_ char *t = NULL;
+ for (p = rvalue;;) {
+ _cleanup_free_ char *word = NULL;
uint32_t a;
- t = strndup(word, l);
- if (!t)
+ r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
+ if (r == 0)
+ return 0;
+ if (r == -ENOMEM)
return log_oom();
+ if (r < 0) {
+ log_syntax(unit, LOG_WARNING, filename, line, r,
+ "Invalid syntax, ignoring: %s", rvalue);
+ return 0;
+ }
- r = seccomp_arch_from_string(t, &a);
+ r = seccomp_arch_from_string(word, &a);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse system call architecture, ignoring: %s", t);
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to parse system call architecture \"%s\", ignoring: %m", word);
continue;
}
r = set_put(*archs, UINT32_TO_PTR(a + 1));
- if (r == 0)
- continue;
if (r < 0)
return log_oom();
}
- if (!isempty(state))
- log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring.");
-
- return 0;
}
int config_parse_syscall_errno(
@@ -2848,8 +2867,7 @@ int config_parse_address_families(
ExecContext *c = data;
bool invert = false;
- const char *word, *state;
- size_t l;
+ const char *p;
int r;
assert(filename);
@@ -2876,34 +2894,84 @@ int config_parse_address_families(
c->address_families_whitelist = !invert;
}
- FOREACH_WORD_QUOTED(word, l, rvalue, state) {
- _cleanup_free_ char *t = NULL;
+ for (p = rvalue;;) {
+ _cleanup_free_ char *word = NULL;
int af;
- t = strndup(word, l);
- if (!t)
+ r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
+ if (r == 0)
+ return 0;
+ if (r == -ENOMEM)
return log_oom();
+ if (r < 0) {
+ log_syntax(unit, LOG_WARNING, filename, line, r,
+ "Invalid syntax, ignoring: %s", rvalue);
+ return 0;
+ }
- af = af_from_name(t);
+ af = af_from_name(word);
if (af <= 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse address family, ignoring: %s", t);
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Failed to parse address family \"%s\", ignoring: %m", word);
continue;
}
/* If we previously wanted to forbid an address family and now
- * we want to allow it, then remove it from the list
+ * we want to allow it, then just remove it from the list.
*/
if (!invert == c->address_families_whitelist) {
r = set_put(c->address_families, INT_TO_PTR(af));
- if (r == 0)
- continue;
if (r < 0)
return log_oom();
} else
set_remove(c->address_families, INT_TO_PTR(af));
}
- if (!isempty(state))
- log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring.");
+}
+
+int config_parse_restrict_namespaces(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ ExecContext *c = data;
+ bool invert = false;
+ int r;
+
+ if (isempty(rvalue)) {
+ /* Reset to the default. */
+ c->restrict_namespaces = NAMESPACE_FLAGS_ALL;
+ return 0;
+ }
+
+ if (rvalue[0] == '~') {
+ invert = true;
+ rvalue++;
+ }
+
+ r = parse_boolean(rvalue);
+ if (r > 0)
+ c->restrict_namespaces = 0;
+ else if (r == 0)
+ c->restrict_namespaces = NAMESPACE_FLAGS_ALL;
+ else {
+ /* Not a boolean argument, in this case it's a list of namespace types. */
+
+ r = namespace_flag_from_string_many(rvalue, &c->restrict_namespaces);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse namespace type string, ignoring: %s", rvalue);
+ return 0;
+ }
+ }
+
+ if (invert)
+ c->restrict_namespaces = (~c->restrict_namespaces) & NAMESPACE_FLAGS_ALL;
return 0;
}
@@ -3622,8 +3690,7 @@ int config_parse_runtime_directory(
char***rt = data;
Unit *u = userdata;
- const char *word, *state;
- size_t l;
+ const char *p;
int r;
assert(filename);
@@ -3637,34 +3704,38 @@ int config_parse_runtime_directory(
return 0;
}
- FOREACH_WORD_QUOTED(word, l, rvalue, state) {
- _cleanup_free_ char *t = NULL, *n = NULL;
+ for (p = rvalue;;) {
+ _cleanup_free_ char *word = NULL, *k = NULL;
- t = strndup(word, l);
- if (!t)
+ r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
+ if (r == 0)
+ return 0;
+ if (r == -ENOMEM)
return log_oom();
+ if (r < 0) {
+ log_syntax(unit, LOG_WARNING, filename, line, r,
+ "Invalid syntax, ignoring: %s", rvalue);
+ return 0;
+ }
- r = unit_name_printf(u, t, &n);
+ r = unit_full_printf(u, word, &k);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m");
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to resolve specifiers in \"%s\", ignoring: %m", word);
continue;
}
- if (!filename_is_valid(n)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Runtime directory is not valid, ignoring assignment: %s", rvalue);
+ if (!filename_is_valid(k)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Runtime directory is not valid, ignoring assignment: %s", rvalue);
continue;
}
- r = strv_push(rt, n);
+ r = strv_push(rt, k);
if (r < 0)
return log_oom();
-
- n = NULL;
+ k = NULL;
}
- if (!isempty(state))
- log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring.");
-
- return 0;
}
int config_parse_set_status(
@@ -3749,8 +3820,8 @@ int config_parse_namespace_path_strv(
void *data,
void *userdata) {
+ Unit *u = userdata;
char*** sv = data;
- const char *prev;
const char *cur;
int r;
@@ -3765,10 +3836,11 @@ int config_parse_namespace_path_strv(
return 0;
}
- prev = cur = rvalue;
+ cur = rvalue;
for (;;) {
- _cleanup_free_ char *word = NULL;
- int offset;
+ _cleanup_free_ char *word = NULL, *resolved = NULL, *joined = NULL;
+ const char *w;
+ bool ignore_enoent = false, shall_prefix = false;
r = extract_first_word(&cur, &word, NULL, EXTRACT_QUOTES);
if (r == 0)
@@ -3776,31 +3848,173 @@ int config_parse_namespace_path_strv(
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Trailing garbage, ignoring: %s", prev);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract first word, ignoring: %s", rvalue);
return 0;
}
if (!utf8_is_valid(word)) {
log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, word);
- prev = cur;
continue;
}
- offset = word[0] == '-';
- if (!path_is_absolute(word + offset)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute path, ignoring: %s", word);
- prev = cur;
+ w = word;
+ if (startswith(w, "-")) {
+ ignore_enoent = true;
+ w++;
+ }
+ if (startswith(w, "+")) {
+ shall_prefix = true;
+ w++;
+ }
+
+ r = unit_full_printf(u, w, &resolved);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers in %s: %m", word);
+ continue;
+ }
+
+ if (!path_is_absolute(resolved)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute path, ignoring: %s", resolved);
continue;
}
- path_kill_slashes(word + offset);
+ path_kill_slashes(resolved);
- r = strv_push(sv, word);
+ joined = strjoin(ignore_enoent ? "-" : "",
+ shall_prefix ? "+" : "",
+ resolved);
+
+ r = strv_push(sv, joined);
if (r < 0)
return log_oom();
- prev = cur;
- word = NULL;
+ joined = NULL;
+ }
+
+ return 0;
+}
+
+int config_parse_bind_paths(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ ExecContext *c = data;
+ const char *p;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if (isempty(rvalue)) {
+ /* Empty assignment resets the list */
+ bind_mount_free_many(c->bind_mounts, c->n_bind_mounts);
+ c->bind_mounts = NULL;
+ c->n_bind_mounts = 0;
+ return 0;
+ }
+
+ p = rvalue;
+ for (;;) {
+ _cleanup_free_ char *source = NULL, *destination = NULL;
+ char *s = NULL, *d = NULL;
+ bool rbind = true, ignore_enoent = false;
+
+ r = extract_first_word(&p, &source, ":" WHITESPACE, EXTRACT_QUOTES|EXTRACT_DONT_COALESCE_SEPARATORS);
+ if (r == 0)
+ break;
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse %s: %s", lvalue, rvalue);
+ return 0;
+ }
+
+ s = source;
+ if (s[0] == '-') {
+ ignore_enoent = true;
+ s++;
+ }
+
+ if (!utf8_is_valid(s)) {
+ log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, s);
+ return 0;
+ }
+ if (!path_is_absolute(s)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute source path, ignoring: %s", s);
+ return 0;
+ }
+
+ path_kill_slashes(s);
+
+ /* Optionally, the destination is specified. */
+ if (p && p[-1] == ':') {
+ r = extract_first_word(&p, &destination, ":" WHITESPACE, EXTRACT_QUOTES|EXTRACT_DONT_COALESCE_SEPARATORS);
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse %s: %s", lvalue, rvalue);
+ return 0;
+ }
+ if (r == 0) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Missing argument after ':': %s", rvalue);
+ return 0;
+ }
+
+ if (!utf8_is_valid(destination)) {
+ log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, destination);
+ return 0;
+ }
+ if (!path_is_absolute(destination)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute destination path, ignoring: %s", destination);
+ return 0;
+ }
+
+ d = path_kill_slashes(destination);
+
+ /* Optionally, there's also a short option string specified */
+ if (p && p[-1] == ':') {
+ _cleanup_free_ char *options = NULL;
+
+ r = extract_first_word(&p, &options, NULL, EXTRACT_QUOTES);
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse %s: %s", lvalue, rvalue);
+ return 0;
+ }
+
+ if (isempty(options) || streq(options, "rbind"))
+ rbind = true;
+ else if (streq(options, "norbind"))
+ rbind = false;
+ else {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid option string, ignoring setting: %s", options);
+ return 0;
+ }
+ }
+ } else
+ d = s;
+
+ r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
+ &(BindMount) {
+ .source = s,
+ .destination = d,
+ .read_only = !!strstr(lvalue, "ReadOnly"),
+ .recursive = rbind,
+ .ignore_enoent = ignore_enoent,
+ });
+ if (r < 0)
+ return log_oom();
}
return 0;
@@ -3833,7 +4047,6 @@ int config_parse_no_new_privileges(
}
c->no_new_privileges = k;
- c->no_new_privileges_set = true;
return 0;
}
@@ -4304,6 +4517,7 @@ void unit_dump_config_items(FILE *f) {
{ config_parse_sec, "SECONDS" },
{ config_parse_nsec, "NANOSECONDS" },
{ config_parse_namespace_path_strv, "PATH [...]" },
+ { config_parse_bind_paths, "PATH[:PATH[:OPTIONS]] [...]" },
{ config_parse_unit_requires_mounts_for, "PATH [...]" },
{ config_parse_exec_mount_flags, "MOUNTFLAG [...]" },
{ config_parse_unit_string_printf, "STRING" },
@@ -4327,6 +4541,7 @@ void unit_dump_config_items(FILE *f) {
{ config_parse_syscall_archs, "ARCHS" },
{ config_parse_syscall_errno, "ERRNO" },
{ config_parse_address_families, "FAMILIES" },
+ { config_parse_restrict_namespaces, "NAMESPACES" },
#endif
{ config_parse_cpu_shares, "SHARES" },
{ config_parse_cpu_weight, "WEIGHT" },
diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
index ede6b1f735..fc27a07955 100644
--- a/src/core/load-fragment.h
+++ b/src/core/load-fragment.h
@@ -116,6 +116,8 @@ int config_parse_fdname(const char *unit, const char *filename, unsigned line, c
int config_parse_sec_fix_0(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_user_group(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_user_group_strv(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_restrict_namespaces(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_bind_paths(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
/* gperf prototypes */
const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
diff --git a/src/core/locale-setup.c b/src/core/locale-setup.c
index ccf61d29fb..fdd847ee8b 100644
--- a/src/core/locale-setup.c
+++ b/src/core/locale-setup.c
@@ -87,7 +87,7 @@ int locale_setup(char ***environment) {
if (!variables[i])
continue;
- s = strjoin(locale_variable_to_string(i), "=", variables[i], NULL);
+ s = strjoin(locale_variable_to_string(i), "=", variables[i]);
if (!s) {
r = -ENOMEM;
goto finish;
diff --git a/src/core/machine-id-setup.c b/src/core/machine-id-setup.c
index 76dfcfa6d7..df3cc74b98 100644
--- a/src/core/machine-id-setup.c
+++ b/src/core/machine-id-setup.c
@@ -146,14 +146,18 @@ int machine_id_setup(const char *root, sd_id128_t machine_id, sd_id128_t *ret) {
r = generate_machine_id(root, &machine_id);
if (r < 0)
return r;
+ }
+ if (writable) {
if (lseek(fd, 0, SEEK_SET) == (off_t) -1)
- return log_error_errno(errno, "Failed to seek: %m");
- }
+ return log_error_errno(errno, "Failed to seek %s: %m", etc_machine_id);
+
+ if (ftruncate(fd, 0) < 0)
+ return log_error_errno(errno, "Failed to truncate %s: %m", etc_machine_id);
- if (writable)
if (id128_write_fd(fd, ID128_PLAIN, machine_id, true) >= 0)
goto finish;
+ }
fd = safe_close(fd);
@@ -199,7 +203,7 @@ int machine_id_commit(const char *root) {
etc_machine_id = prefix_roota(root, "/etc/machine-id");
- r = path_is_mount_point(etc_machine_id, 0);
+ r = path_is_mount_point(etc_machine_id, NULL, 0);
if (r < 0)
return log_error_errno(r, "Failed to determine whether %s is a mount point: %m", etc_machine_id);
if (r == 0) {
diff --git a/src/core/macros.systemd.in b/src/core/macros.systemd.in
index 6e8a3b3e3d..a2a7edd1ee 100644
--- a/src/core/macros.systemd.in
+++ b/src/core/macros.systemd.in
@@ -31,6 +31,8 @@
%_binfmtdir @binfmtdir@
%_systemdgeneratordir @systemgeneratordir@
%_systemdusergeneratordir @usergeneratordir@
+%_systemd_system_env_generator_dir @systemenvgeneratordir@
+%_systemd_user_env_generator_dir @userenvgeneratordir@
%systemd_requires \
Requires(post): systemd \
@@ -81,7 +83,7 @@ fi \
%systemd_user_postun_with_restart() %{nil}
%udev_hwdb_update() \
-udevadm hwdb --update >/dev/null 2>&1 || : \
+systemd-hwdb update >/dev/null 2>&1 || : \
%{nil}
%udev_rules_update() \
diff --git a/src/core/main.c b/src/core/main.c
index f07ed71b31..b660938271 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -49,11 +49,12 @@
#include "cpu-set-util.h"
#include "dbus-manager.h"
#include "def.h"
+#include "emergency-action.h"
#include "env-util.h"
#include "fd-util.h"
#include "fdset.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "fs-util.h"
#include "hostname-setup.h"
#include "ima-setup.h"
@@ -68,6 +69,7 @@
#include "mount-setup.h"
#include "pager.h"
#include "parse-util.h"
+#include "path-util.h"
#include "proc-cmdline.h"
#include "process-util.h"
#include "raw-clone.h"
@@ -89,7 +91,6 @@
#include "user-util.h"
#include "virt.h"
#include "watchdog.h"
-#include "emergency-action.h"
static enum {
ACTION_RUN,
@@ -104,7 +105,7 @@ static bool arg_dump_core = true;
static int arg_crash_chvt = -1;
static bool arg_crash_shell = false;
static bool arg_crash_reboot = false;
-static bool arg_confirm_spawn = false;
+static char *arg_confirm_spawn = NULL;
static ShowStatus arg_show_status = _SHOW_STATUS_UNSET;
static bool arg_switched_root = false;
static bool arg_no_pager = false;
@@ -294,6 +295,28 @@ static int parse_crash_chvt(const char *value) {
return 0;
}
+static int parse_confirm_spawn(const char *value, char **console) {
+ char *s;
+ int r;
+
+ r = value ? parse_boolean(value) : 1;
+ if (r == 0) {
+ *console = NULL;
+ return 0;
+ }
+
+ if (r > 0) /* on with default tty */
+ s = strdup("/dev/console");
+ else if (is_path(value)) /* on with fully qualified path */
+ s = strdup(value);
+ else /* on with only a tty file name, not a fully qualified path */
+ s = strjoin("/dev/", value);
+ if (!s)
+ return -ENOMEM;
+ *console = s;
+ return 0;
+}
+
static int set_machine_id(const char *m) {
sd_id128_t t;
assert(m);
@@ -314,60 +337,73 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
assert(key);
- if (streq(key, "systemd.unit") && value) {
-
- if (!in_initrd())
- return free_and_strdup(&arg_default_unit, value);
+ if (STR_IN_SET(key, "systemd.unit", "rd.systemd.unit")) {
- } else if (streq(key, "rd.systemd.unit") && value) {
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
- if (in_initrd())
- return free_and_strdup(&arg_default_unit, value);
+ if (!unit_name_is_valid(value, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE))
+ log_warning("Unit name specified on %s= is not valid, ignoring: %s", key, value);
+ else if (in_initrd() == !!startswith(key, "rd.")) {
+ if (free_and_strdup(&arg_default_unit, value) < 0)
+ return log_oom();
+ }
- } else if (streq(key, "systemd.dump_core") && value) {
+ } else if (proc_cmdline_key_streq(key, "systemd.dump_core")) {
- r = parse_boolean(value);
+ r = value ? parse_boolean(value) : true;
if (r < 0)
log_warning("Failed to parse dump core switch %s. Ignoring.", value);
else
arg_dump_core = r;
- } else if (streq(key, "systemd.crash_chvt") && value) {
+ } else if (proc_cmdline_key_streq(key, "systemd.crash_chvt")) {
- if (parse_crash_chvt(value) < 0)
+ if (!value)
+ arg_crash_chvt = 0; /* turn on */
+ else if (parse_crash_chvt(value) < 0)
log_warning("Failed to parse crash chvt switch %s. Ignoring.", value);
- } else if (streq(key, "systemd.crash_shell") && value) {
+ } else if (proc_cmdline_key_streq(key, "systemd.crash_shell")) {
- r = parse_boolean(value);
+ r = value ? parse_boolean(value) : true;
if (r < 0)
log_warning("Failed to parse crash shell switch %s. Ignoring.", value);
else
arg_crash_shell = r;
- } else if (streq(key, "systemd.crash_reboot") && value) {
+ } else if (proc_cmdline_key_streq(key, "systemd.crash_reboot")) {
- r = parse_boolean(value);
+ r = value ? parse_boolean(value) : true;
if (r < 0)
log_warning("Failed to parse crash reboot switch %s. Ignoring.", value);
else
arg_crash_reboot = r;
- } else if (streq(key, "systemd.confirm_spawn") && value) {
+ } else if (proc_cmdline_key_streq(key, "systemd.confirm_spawn")) {
+ char *s;
- r = parse_boolean(value);
+ r = parse_confirm_spawn(value, &s);
if (r < 0)
- log_warning("Failed to parse confirm spawn switch %s. Ignoring.", value);
- else
- arg_confirm_spawn = r;
+ log_warning_errno(r, "Failed to parse confirm_spawn switch %s. Ignoring.", value);
+ else {
+ free(arg_confirm_spawn);
+ arg_confirm_spawn = s;
+ }
- } else if (streq(key, "systemd.show_status") && value) {
+ } else if (proc_cmdline_key_streq(key, "systemd.show_status")) {
- r = parse_show_status(value, &arg_show_status);
- if (r < 0)
- log_warning("Failed to parse show status switch %s. Ignoring.", value);
+ if (value) {
+ r = parse_show_status(value, &arg_show_status);
+ if (r < 0)
+ log_warning("Failed to parse show status switch %s. Ignoring.", value);
+ } else
+ arg_show_status = SHOW_STATUS_YES;
+
+ } else if (proc_cmdline_key_streq(key, "systemd.default_standard_output")) {
- } else if (streq(key, "systemd.default_standard_output") && value) {
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
r = exec_output_from_string(value);
if (r < 0)
@@ -375,7 +411,10 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
else
arg_default_std_output = r;
- } else if (streq(key, "systemd.default_standard_error") && value) {
+ } else if (proc_cmdline_key_streq(key, "systemd.default_standard_error")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
r = exec_output_from_string(value);
if (r < 0)
@@ -383,24 +422,42 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
else
arg_default_std_error = r;
- } else if (streq(key, "systemd.setenv") && value) {
+ } else if (streq(key, "systemd.setenv")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
if (env_assignment_is_valid(value)) {
char **env;
env = strv_env_set(arg_default_environment, value);
- if (env)
- arg_default_environment = env;
- else
- log_warning_errno(ENOMEM, "Setting environment variable '%s' failed, ignoring: %m", value);
+ if (!env)
+ return log_oom();
+
+ arg_default_environment = env;
} else
log_warning("Environment variable name '%s' is not valid. Ignoring.", value);
- } else if (streq(key, "systemd.machine_id") && value) {
+ } else if (proc_cmdline_key_streq(key, "systemd.machine_id")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
+ r = set_machine_id(value);
+ if (r < 0)
+ log_warning("MachineID '%s' is not valid. Ignoring.", value);
- r = set_machine_id(value);
- if (r < 0)
- log_warning("MachineID '%s' is not valid. Ignoring.", value);
+ } else if (proc_cmdline_key_streq(key, "systemd.default_timeout_start_sec")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
+ r = parse_sec(value, &arg_default_timeout_start_usec);
+ if (r < 0)
+ log_warning_errno(r, "Failed to parse default start timeout: %s, ignoring.", value);
+
+ if (arg_default_timeout_start_usec <= 0)
+ arg_default_timeout_start_usec = USEC_INFINITY;
} else if (streq(key, "quiet") && !value) {
@@ -422,15 +479,6 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
target = runlevel_to_target(key);
if (target)
return free_and_strdup(&arg_default_unit, target);
-
- } else if (streq(key, "systemd.default_timeout_start_sec") && value) {
-
- r = parse_sec(value, &arg_default_timeout_start_usec);
- if (r < 0)
- log_warning_errno(r, "Failed to parse default start timeout: %s, ignoring.", value);
-
- if (arg_default_timeout_start_usec <= 0)
- arg_default_timeout_start_usec = USEC_INFINITY;
}
return 0;
@@ -574,7 +622,7 @@ static int config_parse_join_controllers(const char *unit,
char **l;
int r;
- r = extract_first_word(&rvalue, &word, WHITESPACE, EXTRACT_QUOTES);
+ r = extract_first_word(&rvalue, &word, NULL, EXTRACT_QUOTES);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid value for %s: %s", lvalue, whole_rvalue);
return r;
@@ -881,7 +929,6 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_UNIT:
-
r = free_and_strdup(&arg_default_unit, optarg);
if (r < 0)
return log_error_errno(r, "Failed to set default unit %s: %m", optarg);
@@ -952,12 +999,11 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_CONFIRM_SPAWN:
- r = optarg ? parse_boolean(optarg) : 1;
- if (r < 0) {
- log_error("Failed to parse confirm spawn boolean %s.", optarg);
- return r;
- }
- arg_confirm_spawn = r;
+ arg_confirm_spawn = mfree(arg_confirm_spawn);
+
+ r = parse_confirm_spawn(optarg, &arg_confirm_spawn);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse confirm spawn option: %m");
break;
case ARG_SHOW_STATUS:
@@ -1185,44 +1231,16 @@ oom:
static int enforce_syscall_archs(Set *archs) {
#ifdef HAVE_SECCOMP
- scmp_filter_ctx *seccomp;
- Iterator i;
- void *id;
int r;
if (!is_seccomp_available())
return 0;
- seccomp = seccomp_init(SCMP_ACT_ALLOW);
- if (!seccomp)
- return log_oom();
-
- SET_FOREACH(id, arg_syscall_archs, i) {
- r = seccomp_arch_add(seccomp, PTR_TO_UINT32(id) - 1);
- if (r == -EEXIST)
- continue;
- if (r < 0) {
- log_error_errno(r, "Failed to add architecture to seccomp: %m");
- goto finish;
- }
- }
-
- r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
- if (r < 0) {
- log_error_errno(r, "Failed to unset NO_NEW_PRIVS: %m");
- goto finish;
- }
-
- r = seccomp_load(seccomp);
+ r = seccomp_restrict_archs(arg_syscall_archs);
if (r < 0)
- log_error_errno(r, "Failed to add install architecture seccomp: %m");
-
-finish:
- seccomp_release(seccomp);
- return r;
-#else
- return 0;
+ return log_error_errno(r, "Failed to enforce system call architecture restrication: %m");
#endif
+ return 0;
}
static int status_welcome(void) {
@@ -1320,10 +1338,9 @@ static int fixup_environment(void) {
* However if TERM was configured through the kernel
* command line then leave it alone. */
- r = get_proc_cmdline_key("TERM=", &term);
+ r = proc_cmdline_get_key("TERM", 0, &term);
if (r < 0)
return r;
-
if (r == 0) {
term = strdup(default_term_for_tty("/dev/console"));
if (!term)
@@ -1390,17 +1407,24 @@ int main(int argc, char *argv[]) {
called 'systemd'. That is confusing, hence let's call us
systemd right-away. */
program_invocation_short_name = systemd;
- prctl(PR_SET_NAME, systemd);
+ (void) prctl(PR_SET_NAME, systemd);
saved_argv = argv;
saved_argc = argc;
log_set_upgrade_syslog_to_journal(true);
- /* Disable the umask logic */
- if (getpid() == 1)
+ if (getpid() == 1) {
+ /* Disable the umask logic */
umask(0);
+ /* Always reopen /dev/console when running as PID 1 or one of its pre-execve() children. This is
+ * important so that we never end up logging to any foreign stderr, for example if we have to log in a
+ * child process right before execve()'ing the actual binary, at a point in time where socket
+ * activation stderr/stdout area already set up. */
+ log_set_always_reopen_console(true);
+ }
+
if (getpid() == 1 && detect_container() <= 0) {
/* Running outside of a container as PID 1 */
@@ -1414,9 +1438,10 @@ int main(int argc, char *argv[]) {
if (!skip_setup) {
r = mount_setup_early();
if (r < 0) {
- error_message = "Failed to early mount API filesystems";
+ error_message = "Failed to mount early API filesystems";
goto finish;
}
+
dual_timestamp_get(&security_start_timestamp);
if (mac_selinux_setup(&loaded_policy) < 0) {
error_message = "Failed to load SELinux policy";
@@ -1492,7 +1517,7 @@ int main(int argc, char *argv[]) {
log_close_console(); /* force reopen of /dev/console */
log_open();
- /* For the later on, see above... */
+ /* For later on, see above... */
log_set_target(LOG_TARGET_JOURNAL);
/* clear the kernel timestamp,
@@ -1569,7 +1594,7 @@ int main(int argc, char *argv[]) {
}
if (arg_system) {
- r = parse_proc_cmdline(parse_proc_cmdline_item, NULL, false);
+ r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
if (r < 0)
log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
}
@@ -1812,8 +1837,10 @@ int main(int argc, char *argv[]) {
before_startup = now(CLOCK_MONOTONIC);
r = manager_startup(m, arg_serialization, fds);
- if (r < 0)
+ if (r < 0) {
log_error_errno(r, "Failed to fully start up daemon: %m");
+ goto finish;
+ }
/* This will close all file descriptors that were opened, but
* not claimed by any unit. */
@@ -1991,6 +2018,7 @@ finish:
arg_default_rlimit[j] = mfree(arg_default_rlimit[j]);
arg_default_unit = mfree(arg_default_unit);
+ arg_confirm_spawn = mfree(arg_confirm_spawn);
arg_join_controllers = strv_free_free(arg_join_controllers);
arg_default_environment = strv_free(arg_default_environment);
arg_syscall_archs = set_free(arg_syscall_archs);
diff --git a/src/core/manager.c b/src/core/manager.c
index ffccfdcd5e..cff38e28de 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -17,7 +17,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/kd.h>
@@ -53,6 +52,7 @@
#include "dirent-util.h"
#include "env-util.h"
#include "escape.h"
+#include "exec-util.h"
#include "exit-status.h"
#include "fd-util.h"
#include "fileio.h"
@@ -103,6 +103,7 @@ static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32
static int manager_dispatch_user_lookup_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata);
static int manager_dispatch_run_queue(sd_event_source *source, void *userdata);
+static int manager_run_environment_generators(Manager *m);
static int manager_run_generators(Manager *m);
static void manager_watch_jobs_in_progress(Manager *m) {
@@ -111,6 +112,12 @@ static void manager_watch_jobs_in_progress(Manager *m) {
assert(m);
+ /* We do not want to show the cylon animation if the user
+ * needs to confirm service executions otherwise confirmation
+ * messages will be screwed by the cylon animation. */
+ if (!manager_is_confirm_spawn_disabled(m))
+ return;
+
if (m->jobs_in_progress_event_source)
return;
@@ -227,6 +234,7 @@ static void manager_print_jobs_in_progress(Manager *m) {
static int have_ask_password(void) {
_cleanup_closedir_ DIR *dir;
+ struct dirent *de;
dir = opendir("/run/systemd/ask-password");
if (!dir) {
@@ -236,19 +244,11 @@ static int have_ask_password(void) {
return -errno;
}
- for (;;) {
- struct dirent *de;
-
- errno = 0;
- de = readdir(dir);
- if (!de && errno > 0)
- return -errno;
- if (!de)
- return false;
-
+ FOREACH_DIRENT_ALL(de, dir, return -errno) {
if (startswith(de->d_name, "ask."))
return true;
}
+ return false;
}
static int manager_dispatch_ask_password_fd(sd_event_source *source,
@@ -532,9 +532,9 @@ static int manager_default_environment(Manager *m) {
if (MANAGER_IS_SYSTEM(m)) {
/* The system manager always starts with a clean
* environment for its children. It does not import
- * the kernel or the parents exported variables.
+ * the kernel's or the parents' exported variables.
*
- * The initial passed environ is untouched to keep
+ * The initial passed environment is untouched to keep
* /proc/self/environ valid; it is used for tagging
* the init process inside containers. */
m->environment = strv_new("PATH=" DEFAULT_PATH,
@@ -542,11 +542,10 @@ static int manager_default_environment(Manager *m) {
/* Import locale variables LC_*= from configuration */
locale_setup(&m->environment);
- } else {
+ } else
/* The user manager passes its own environment
* along to its children. */
m->environment = strv_copy(environ);
- }
if (!m->environment)
return -ENOMEM;
@@ -777,7 +776,10 @@ static int manager_setup_cgroups_agent(Manager *m) {
if (!MANAGER_IS_SYSTEM(m))
return 0;
- if (cg_unified(SYSTEMD_CGROUP_CONTROLLER) > 0) /* We don't need this anymore on the unified hierarchy */
+ r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
+ if (r < 0)
+ return log_error_errno(r, "Failed to determine whether unified cgroups hierarchy is used: %m");
+ if (r > 0) /* We don't need this anymore on the unified hierarchy */
return 0;
if (m->cgroups_agent_fd < 0) {
@@ -981,10 +983,9 @@ good:
unit_gc_mark_good(u, gc_marker);
}
-static unsigned manager_dispatch_gc_queue(Manager *m) {
+static unsigned manager_dispatch_gc_unit_queue(Manager *m) {
+ unsigned n = 0, gc_marker;
Unit *u;
- unsigned n = 0;
- unsigned gc_marker;
assert(m);
@@ -996,12 +997,12 @@ static unsigned manager_dispatch_gc_queue(Manager *m) {
gc_marker = m->gc_marker;
- while ((u = m->gc_queue)) {
+ while ((u = m->gc_unit_queue)) {
assert(u->in_gc_queue);
unit_gc_sweep(u, gc_marker);
- LIST_REMOVE(gc_queue, m->gc_queue, u);
+ LIST_REMOVE(gc_queue, m->gc_unit_queue, u);
u->in_gc_queue = false;
n++;
@@ -1015,7 +1016,29 @@ static unsigned manager_dispatch_gc_queue(Manager *m) {
}
}
- m->n_in_gc_queue = 0;
+ return n;
+}
+
+static unsigned manager_dispatch_gc_job_queue(Manager *m) {
+ unsigned n = 0;
+ Job *j;
+
+ assert(m);
+
+ while ((j = m->gc_job_queue)) {
+ assert(j->in_gc_queue);
+
+ LIST_REMOVE(gc_queue, m->gc_job_queue, j);
+ j->in_gc_queue = false;
+
+ n++;
+
+ if (job_check_gc(j))
+ continue;
+
+ log_unit_debug(j->unit, "Collecting job.");
+ (void) job_finish_and_invalidate(j, JOB_COLLECTED, false, false);
+ }
return n;
}
@@ -1035,7 +1058,8 @@ static void manager_clear_jobs_and_units(Manager *m) {
assert(!m->dbus_unit_queue);
assert(!m->dbus_job_queue);
assert(!m->cleanup_queue);
- assert(!m->gc_queue);
+ assert(!m->gc_unit_queue);
+ assert(!m->gc_job_queue);
assert(hashmap_isempty(m->jobs));
assert(hashmap_isempty(m->units));
@@ -1196,7 +1220,7 @@ static void manager_build_unit_path_cache(Manager *m) {
FOREACH_DIRENT(de, d, r = -errno; goto fail) {
char *p;
- p = strjoin(streq(*i, "/") ? "" : *i, "/", de->d_name, NULL);
+ p = strjoin(streq(*i, "/") ? "" : *i, "/", de->d_name);
if (!p) {
r = -ENOMEM;
goto fail;
@@ -1242,6 +1266,10 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
if (r < 0)
return r;
+ r = manager_run_environment_generators(m);
+ if (r < 0)
+ return r;
+
/* Make sure the transient directory always exists, so that it remains in the search path */
if (!m->test_run) {
r = mkdir_p_label(m->lookup_paths.transient, 0755);
@@ -1378,7 +1406,7 @@ tr_abort:
}
int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, sd_bus_error *e, Job **ret) {
- Unit *unit;
+ Unit *unit = NULL; /* just to appease gcc, initialization is not really necessary */
int r;
assert(m);
@@ -1389,6 +1417,7 @@ int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode
r = manager_load_unit(m, name, NULL, NULL, &unit);
if (r < 0)
return r;
+ assert(unit);
return manager_add_job(m, type, unit, mode, e, ret);
}
@@ -1461,6 +1490,7 @@ int manager_load_unit_prepare(
assert(m);
assert(name || path);
+ assert(_ret);
/* This will prepare the unit for loading, but not actually
* load anything from disk. */
@@ -1508,8 +1538,7 @@ int manager_load_unit_prepare(
unit_add_to_dbus_queue(ret);
unit_add_to_gc_queue(ret);
- if (_ret)
- *_ret = ret;
+ *_ret = ret;
return 0;
}
@@ -1524,6 +1553,7 @@ int manager_load_unit(
int r;
assert(m);
+ assert(_ret);
/* This will load the service information files, but not actually
* start any services or anything. */
@@ -1534,8 +1564,7 @@ int manager_load_unit(
manager_dispatch_load_queue(m);
- if (_ret)
- *_ret = unit_follow_merge(*_ret);
+ *_ret = unit_follow_merge(*_ret);
return 0;
}
@@ -1964,7 +1993,9 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
if (MANAGER_IS_SYSTEM(m)) {
/* This is for compatibility with the
* original sysvinit */
- m->exit_code = MANAGER_REEXECUTE;
+ r = verify_run_space_and_log("Refusing to reexecute");
+ if (r >= 0)
+ m->exit_code = MANAGER_REEXECUTE;
break;
}
@@ -2041,7 +2072,9 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
}
case SIGHUP:
- m->exit_code = MANAGER_RELOAD;
+ r = verify_run_space_and_log("Refusing to reload");
+ if (r >= 0)
+ m->exit_code = MANAGER_RELOAD;
break;
default: {
@@ -2145,8 +2178,8 @@ static int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint
assert(m);
assert(m->time_change_fd == fd);
- log_struct(LOG_INFO,
- LOG_MESSAGE_ID(SD_MESSAGE_TIME_CHANGE),
+ log_struct(LOG_DEBUG,
+ "MESSAGE_ID=" SD_MESSAGE_TIME_CHANGE_STR,
LOG_MESSAGE("Time has been changed"),
NULL);
@@ -2228,7 +2261,10 @@ int manager_loop(Manager *m) {
if (manager_dispatch_load_queue(m) > 0)
continue;
- if (manager_dispatch_gc_queue(m) > 0)
+ if (manager_dispatch_gc_job_queue(m) > 0)
+ continue;
+
+ if (manager_dispatch_gc_unit_queue(m) > 0)
continue;
if (manager_dispatch_cleanup_queue(m) > 0)
@@ -2409,18 +2445,14 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) {
}
int manager_open_serialization(Manager *m, FILE **_f) {
- const char *path;
- int fd = -1;
+ int fd;
FILE *f;
assert(_f);
- path = MANAGER_IS_SYSTEM(m) ? "/run/systemd" : "/tmp";
- fd = open_tmpfile_unlinkable(path, O_RDWR|O_CLOEXEC);
+ fd = open_serialization_fd("systemd-state");
if (fd < 0)
- return -errno;
-
- log_debug("Serializing state to %s", path);
+ return fd;
f = fdopen(fd, "w+");
if (!f) {
@@ -2429,7 +2461,6 @@ int manager_open_serialization(Manager *m, FILE **_f) {
}
*_f = f;
-
return 0;
}
@@ -2437,7 +2468,6 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
Iterator i;
Unit *u;
const char *t;
- char **e;
int r;
assert(m);
@@ -2467,17 +2497,8 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
dual_timestamp_serialize(f, "units-load-finish-timestamp", &m->units_load_finish_timestamp);
}
- if (!switching_root) {
- STRV_FOREACH(e, m->environment) {
- _cleanup_free_ char *ce;
-
- ce = cescape(*e);
- if (!ce)
- return -ENOMEM;
-
- fprintf(f, "env=%s\n", *e);
- }
- }
+ if (!switching_root)
+ (void) serialize_environment(f, m->environment);
if (m->notify_fd >= 0) {
int copy;
@@ -2565,6 +2586,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
for (;;) {
char line[LINE_MAX], *l;
+ const char *val;
if (!fgets(line, sizeof(line), f)) {
if (feof(f))
@@ -2581,95 +2603,83 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
if (l[0] == 0)
break;
- if (startswith(l, "current-job-id=")) {
+ if ((val = startswith(l, "current-job-id="))) {
uint32_t id;
- if (safe_atou32(l+15, &id) < 0)
- log_debug("Failed to parse current job id value %s", l+15);
+ if (safe_atou32(val, &id) < 0)
+ log_debug("Failed to parse current job id value %s", val);
else
m->current_job_id = MAX(m->current_job_id, id);
- } else if (startswith(l, "n-installed-jobs=")) {
+ } else if ((val = startswith(l, "n-installed-jobs="))) {
uint32_t n;
- if (safe_atou32(l+17, &n) < 0)
- log_debug("Failed to parse installed jobs counter %s", l+17);
+ if (safe_atou32(val, &n) < 0)
+ log_debug("Failed to parse installed jobs counter %s", val);
else
m->n_installed_jobs += n;
- } else if (startswith(l, "n-failed-jobs=")) {
+ } else if ((val = startswith(l, "n-failed-jobs="))) {
uint32_t n;
- if (safe_atou32(l+14, &n) < 0)
- log_debug("Failed to parse failed jobs counter %s", l+14);
+ if (safe_atou32(val, &n) < 0)
+ log_debug("Failed to parse failed jobs counter %s", val);
else
m->n_failed_jobs += n;
- } else if (startswith(l, "taint-usr=")) {
+ } else if ((val = startswith(l, "taint-usr="))) {
int b;
- b = parse_boolean(l+10);
+ b = parse_boolean(val);
if (b < 0)
- log_debug("Failed to parse taint /usr flag %s", l+10);
+ log_debug("Failed to parse taint /usr flag %s", val);
else
m->taint_usr = m->taint_usr || b;
- } else if (startswith(l, "firmware-timestamp="))
- dual_timestamp_deserialize(l+19, &m->firmware_timestamp);
- else if (startswith(l, "loader-timestamp="))
- dual_timestamp_deserialize(l+17, &m->loader_timestamp);
- else if (startswith(l, "kernel-timestamp="))
- dual_timestamp_deserialize(l+17, &m->kernel_timestamp);
- else if (startswith(l, "initrd-timestamp="))
- dual_timestamp_deserialize(l+17, &m->initrd_timestamp);
- else if (startswith(l, "userspace-timestamp="))
- dual_timestamp_deserialize(l+20, &m->userspace_timestamp);
- else if (startswith(l, "finish-timestamp="))
- dual_timestamp_deserialize(l+17, &m->finish_timestamp);
- else if (startswith(l, "security-start-timestamp="))
- dual_timestamp_deserialize(l+25, &m->security_start_timestamp);
- else if (startswith(l, "security-finish-timestamp="))
- dual_timestamp_deserialize(l+26, &m->security_finish_timestamp);
- else if (startswith(l, "generators-start-timestamp="))
- dual_timestamp_deserialize(l+27, &m->generators_start_timestamp);
- else if (startswith(l, "generators-finish-timestamp="))
- dual_timestamp_deserialize(l+28, &m->generators_finish_timestamp);
- else if (startswith(l, "units-load-start-timestamp="))
- dual_timestamp_deserialize(l+27, &m->units_load_start_timestamp);
- else if (startswith(l, "units-load-finish-timestamp="))
- dual_timestamp_deserialize(l+28, &m->units_load_finish_timestamp);
+ } else if ((val = startswith(l, "firmware-timestamp=")))
+ dual_timestamp_deserialize(val, &m->firmware_timestamp);
+ else if ((val = startswith(l, "loader-timestamp=")))
+ dual_timestamp_deserialize(val, &m->loader_timestamp);
+ else if ((val = startswith(l, "kernel-timestamp=")))
+ dual_timestamp_deserialize(val, &m->kernel_timestamp);
+ else if ((val = startswith(l, "initrd-timestamp=")))
+ dual_timestamp_deserialize(val, &m->initrd_timestamp);
+ else if ((val = startswith(l, "userspace-timestamp=")))
+ dual_timestamp_deserialize(val, &m->userspace_timestamp);
+ else if ((val = startswith(l, "finish-timestamp=")))
+ dual_timestamp_deserialize(val, &m->finish_timestamp);
+ else if ((val = startswith(l, "security-start-timestamp=")))
+ dual_timestamp_deserialize(val, &m->security_start_timestamp);
+ else if ((val = startswith(l, "security-finish-timestamp=")))
+ dual_timestamp_deserialize(val, &m->security_finish_timestamp);
+ else if ((val = startswith(l, "generators-start-timestamp=")))
+ dual_timestamp_deserialize(val, &m->generators_start_timestamp);
+ else if ((val = startswith(l, "generators-finish-timestamp=")))
+ dual_timestamp_deserialize(val, &m->generators_finish_timestamp);
+ else if ((val = startswith(l, "units-load-start-timestamp=")))
+ dual_timestamp_deserialize(val, &m->units_load_start_timestamp);
+ else if ((val = startswith(l, "units-load-finish-timestamp=")))
+ dual_timestamp_deserialize(val, &m->units_load_finish_timestamp);
else if (startswith(l, "env=")) {
- _cleanup_free_ char *uce = NULL;
- char **e;
-
- r = cunescape(l + 4, UNESCAPE_RELAX, &uce);
+ r = deserialize_environment(&m->environment, l);
if (r < 0)
- goto finish;
+ return r;
- e = strv_env_set(m->environment, uce);
- if (!e) {
- r = -ENOMEM;
- goto finish;
- }
-
- strv_free(m->environment);
- m->environment = e;
-
- } else if (startswith(l, "notify-fd=")) {
+ } else if ((val = startswith(l, "notify-fd="))) {
int fd;
- if (safe_atoi(l + 10, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
- log_debug("Failed to parse notify fd: %s", l + 10);
+ if (safe_atoi(val, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
+ log_debug("Failed to parse notify fd: %s", val);
else {
m->notify_event_source = sd_event_source_unref(m->notify_event_source);
safe_close(m->notify_fd);
m->notify_fd = fdset_remove(fds, fd);
}
- } else if (startswith(l, "notify-socket=")) {
+ } else if ((val = startswith(l, "notify-socket="))) {
char *n;
- n = strdup(l+14);
+ n = strdup(val);
if (!n) {
r = -ENOMEM;
goto finish;
@@ -2678,22 +2688,22 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
free(m->notify_socket);
m->notify_socket = n;
- } else if (startswith(l, "cgroups-agent-fd=")) {
+ } else if ((val = startswith(l, "cgroups-agent-fd="))) {
int fd;
- if (safe_atoi(l + 17, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
- log_debug("Failed to parse cgroups agent fd: %s", l + 10);
+ if (safe_atoi(val, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
+ log_debug("Failed to parse cgroups agent fd: %s", val);
else {
m->cgroups_agent_event_source = sd_event_source_unref(m->cgroups_agent_event_source);
safe_close(m->cgroups_agent_fd);
m->cgroups_agent_fd = fdset_remove(fds, fd);
}
- } else if (startswith(l, "user-lookup=")) {
+ } else if ((val = startswith(l, "user-lookup="))) {
int fd0, fd1;
- if (sscanf(l + 12, "%i %i", &fd0, &fd1) != 2 || fd0 < 0 || fd1 < 0 || fd0 == fd1 || !fdset_contains(fds, fd0) || !fdset_contains(fds, fd1))
- log_debug("Failed to parse user lookup fd: %s", l + 12);
+ if (sscanf(val, "%i %i", &fd0, &fd1) != 2 || fd0 < 0 || fd1 < 0 || fd0 == fd1 || !fdset_contains(fds, fd0) || !fdset_contains(fds, fd1))
+ log_debug("Failed to parse user lookup fd: %s", val);
else {
m->user_lookup_event_source = sd_event_source_unref(m->user_lookup_event_source);
safe_close_pair(m->user_lookup_fds);
@@ -2701,15 +2711,15 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
m->user_lookup_fds[1] = fdset_remove(fds, fd1);
}
- } else if (startswith(l, "dynamic-user="))
- dynamic_user_deserialize_one(m, l + 13, fds);
- else if (startswith(l, "destroy-ipc-uid="))
- manager_deserialize_uid_refs_one(m, l + 16);
- else if (startswith(l, "destroy-ipc-gid="))
- manager_deserialize_gid_refs_one(m, l + 16);
- else if (startswith(l, "subscribed=")) {
+ } else if ((val = startswith(l, "dynamic-user=")))
+ dynamic_user_deserialize_one(m, val, fds);
+ else if ((val = startswith(l, "destroy-ipc-uid=")))
+ manager_deserialize_uid_refs_one(m, val);
+ else if ((val = startswith(l, "destroy-ipc-gid=")))
+ manager_deserialize_gid_refs_one(m, val);
+ else if ((val = startswith(l, "subscribed="))) {
- if (strv_extend(&m->deserialized_subscribed, l+11) < 0)
+ if (strv_extend(&m->deserialized_subscribed, val) < 0)
log_oom();
} else if (!startswith(l, "kdbus-fd=")) /* ignore this one */
@@ -2794,6 +2804,10 @@ int manager_reload(Manager *m) {
if (q < 0 && r >= 0)
r = q;
+ q = manager_run_environment_generators(m);
+ if (q < 0 && r >= 0)
+ r = q;
+
/* Find new unit paths */
q = manager_run_generators(m);
if (q < 0 && r >= 0)
@@ -2897,7 +2911,7 @@ static void manager_notify_finished(Manager *m) {
initrd_usec = m->userspace_timestamp.monotonic - m->initrd_timestamp.monotonic;
log_struct(LOG_INFO,
- LOG_MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
+ "MESSAGE_ID=" SD_MESSAGE_STARTUP_FINISHED_STR,
"KERNEL_USEC="USEC_FMT, kernel_usec,
"INITRD_USEC="USEC_FMT, initrd_usec,
"USERSPACE_USEC="USEC_FMT, userspace_usec,
@@ -2912,7 +2926,7 @@ static void manager_notify_finished(Manager *m) {
initrd_usec = 0;
log_struct(LOG_INFO,
- LOG_MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
+ "MESSAGE_ID=" SD_MESSAGE_STARTUP_FINISHED_STR,
"KERNEL_USEC="USEC_FMT, kernel_usec,
"USERSPACE_USEC="USEC_FMT, userspace_usec,
LOG_MESSAGE("Startup finished in %s (kernel) + %s (userspace) = %s.",
@@ -2926,7 +2940,7 @@ static void manager_notify_finished(Manager *m) {
total_usec = userspace_usec = m->finish_timestamp.monotonic - m->userspace_timestamp.monotonic;
log_struct(LOG_INFO,
- LOG_MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
+ "MESSAGE_ID=" SD_MESSAGE_USER_STARTUP_FINISHED_STR,
"USERSPACE_USEC="USEC_FMT, userspace_usec,
LOG_MESSAGE("Startup finished in %s.",
format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC)),
@@ -2967,7 +2981,7 @@ void manager_check_finished(Manager *m) {
manager_close_idle_pipe(m);
/* Turn off confirm spawn now */
- m->confirm_spawn = false;
+ m->confirm_spawn = NULL;
/* No need to update ask password status when we're going non-interactive */
manager_close_ask_password(m);
@@ -2985,10 +2999,56 @@ void manager_check_finished(Manager *m) {
manager_invalidate_startup_units(m);
}
+static bool generator_path_any(const char* const* paths) {
+ char **path;
+ bool found = false;
+
+ /* Optimize by skipping the whole process by not creating output directories
+ * if no generators are found. */
+ STRV_FOREACH(path, (char**) paths)
+ if (access(*path, F_OK) == 0)
+ found = true;
+ else if (errno != ENOENT)
+ log_warning_errno(errno, "Failed to open generator directory %s: %m", *path);
+
+ return found;
+}
+
+static const char* system_env_generator_binary_paths[] = {
+ "/run/systemd/system-environment-generators",
+ "/etc/systemd/system-environment-generators",
+ "/usr/local/lib/systemd/system-environment-generators",
+ SYSTEM_ENV_GENERATOR_PATH,
+ NULL
+};
+
+static const char* user_env_generator_binary_paths[] = {
+ "/run/systemd/user-environment-generators",
+ "/etc/systemd/user-environment-generators",
+ "/usr/local/lib/systemd/user-environment-generators",
+ USER_ENV_GENERATOR_PATH,
+ NULL
+};
+
+static int manager_run_environment_generators(Manager *m) {
+ char **tmp = NULL; /* this is only used in the forked process, no cleanup here */
+ const char **paths;
+ void* args[] = {&tmp, &tmp, &m->environment};
+
+ if (m->test_run)
+ return 0;
+
+ paths = MANAGER_IS_SYSTEM(m) ? system_env_generator_binary_paths : user_env_generator_binary_paths;
+
+ if (!generator_path_any(paths))
+ return 0;
+
+ return execute_directories(paths, DEFAULT_TIMEOUT_USEC, gather_environment, args, NULL);
+}
+
static int manager_run_generators(Manager *m) {
_cleanup_strv_free_ char **paths = NULL;
const char *argv[5];
- char **path;
int r;
assert(m);
@@ -3000,18 +3060,9 @@ static int manager_run_generators(Manager *m) {
if (!paths)
return log_oom();
- /* Optimize by skipping the whole process by not creating output directories
- * if no generators are found. */
- STRV_FOREACH(path, paths) {
- if (access(*path, F_OK) >= 0)
- goto found;
- if (errno != ENOENT)
- log_warning_errno(errno, "Failed to open generator directory %s: %m", *path);
- }
-
- return 0;
+ if (!generator_path_any((const char* const*) paths))
+ return 0;
- found:
r = lookup_paths_mkdir_generator(&m->lookup_paths);
if (r < 0)
goto finish;
@@ -3023,7 +3074,8 @@ static int manager_run_generators(Manager *m) {
argv[4] = NULL;
RUN_WITH_UMASK(0022)
- execute_directories((const char* const*) paths, DEFAULT_TIMEOUT_USEC, (char**) argv);
+ execute_directories((const char* const*) paths, DEFAULT_TIMEOUT_USEC,
+ NULL, NULL, (char**) argv);
finish:
lookup_paths_trim_generator(&m->lookup_paths);
@@ -3152,6 +3204,49 @@ static bool manager_get_show_status(Manager *m, StatusType type) {
return false;
}
+const char *manager_get_confirm_spawn(Manager *m) {
+ static int last_errno = 0;
+ const char *vc = m->confirm_spawn;
+ struct stat st;
+ int r;
+
+ /* Here's the deal: we want to test the validity of the console but don't want
+ * PID1 to go through the whole console process which might block. But we also
+ * want to warn the user only once if something is wrong with the console so we
+ * cannot do the sanity checks after spawning our children. So here we simply do
+ * really basic tests to hopefully trap common errors.
+ *
+ * If the console suddenly disappear at the time our children will really it
+ * then they will simply fail to acquire it and a positive answer will be
+ * assumed. New children will fallback to /dev/console though.
+ *
+ * Note: TTYs are devices that can come and go any time, and frequently aren't
+ * available yet during early boot (consider a USB rs232 dongle...). If for any
+ * reason the configured console is not ready, we fallback to the default
+ * console. */
+
+ if (!vc || path_equal(vc, "/dev/console"))
+ return vc;
+
+ r = stat(vc, &st);
+ if (r < 0)
+ goto fail;
+
+ if (!S_ISCHR(st.st_mode)) {
+ errno = ENOTTY;
+ goto fail;
+ }
+
+ last_errno = 0;
+ return vc;
+fail:
+ if (last_errno != errno) {
+ last_errno = errno;
+ log_warning_errno(errno, "Failed to open %s: %m, using default console", vc);
+ }
+ return "/dev/console";
+}
+
void manager_set_first_boot(Manager *m, bool b) {
assert(m);
@@ -3168,6 +3263,17 @@ void manager_set_first_boot(Manager *m, bool b) {
m->first_boot = b;
}
+void manager_disable_confirm_spawn(void) {
+ (void) touch("/run/systemd/confirm_spawn_disabled");
+}
+
+bool manager_is_confirm_spawn_disabled(Manager *m) {
+ if (!m->confirm_spawn)
+ return true;
+
+ return access("/run/systemd/confirm_spawn_disabled", F_OK) >= 0;
+}
+
void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) {
va_list ap;
diff --git a/src/core/manager.h b/src/core/manager.h
index 35172fdba9..4a9a37caff 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -104,8 +104,9 @@ struct Manager {
/* Units to remove */
LIST_HEAD(Unit, cleanup_queue);
- /* Units to check when doing GC */
- LIST_HEAD(Unit, gc_queue);
+ /* Units and jobs to check when doing GC */
+ LIST_HEAD(Unit, gc_unit_queue);
+ LIST_HEAD(Job, gc_job_queue);
/* Units that should be realized */
LIST_HEAD(Unit, cgroup_queue);
@@ -229,7 +230,6 @@ struct Manager {
int pin_cgroupfs_fd;
int gc_marker;
- unsigned n_in_gc_queue;
/* Flags */
ManagerExitCode exit_code:5;
@@ -246,7 +246,7 @@ struct Manager {
uint8_t return_value;
ShowStatus show_status;
- bool confirm_spawn;
+ char *confirm_spawn;
bool no_console_output;
ExecOutput default_std_output, default_std_error;
@@ -403,3 +403,7 @@ void manager_deserialize_gid_refs_one(Manager *m, const char *value);
const char *manager_state_to_string(ManagerState m) _const_;
ManagerState manager_state_from_string(const char *s) _pure_;
+
+const char *manager_get_confirm_spawn(Manager *m);
+bool manager_is_confirm_spawn_disabled(Manager *m);
+void manager_disable_confirm_spawn(void);
diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c
index ca63a93e8b..7295efbf31 100644
--- a/src/core/mount-setup.c
+++ b/src/core/mount-setup.c
@@ -96,15 +96,15 @@ static const MountPoint mount_table[] = {
{ "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME,
NULL, MNT_FATAL|MNT_IN_CONTAINER },
{ "cgroup", "/sys/fs/cgroup", "cgroup2", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV,
- cg_is_unified_wanted, MNT_FATAL|MNT_IN_CONTAINER },
+ cg_is_unified_wanted, MNT_IN_CONTAINER },
{ "tmpfs", "/sys/fs/cgroup", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME,
cg_is_legacy_wanted, MNT_FATAL|MNT_IN_CONTAINER },
- { "cgroup", "/sys/fs/cgroup/systemd", "cgroup2", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV,
- cg_is_unified_systemd_controller_wanted, MNT_IN_CONTAINER },
+ { "cgroup", "/sys/fs/cgroup/unified", "cgroup2", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV,
+ cg_is_hybrid_wanted, MNT_IN_CONTAINER },
{ "cgroup", "/sys/fs/cgroup/systemd", "cgroup", "none,name=systemd,xattr", MS_NOSUID|MS_NOEXEC|MS_NODEV,
- cg_is_legacy_systemd_controller_wanted, MNT_IN_CONTAINER },
+ cg_is_legacy_wanted, MNT_IN_CONTAINER },
{ "cgroup", "/sys/fs/cgroup/systemd", "cgroup", "none,name=systemd", MS_NOSUID|MS_NOEXEC|MS_NODEV,
- cg_is_legacy_systemd_controller_wanted, MNT_FATAL|MNT_IN_CONTAINER },
+ cg_is_legacy_wanted, MNT_FATAL|MNT_IN_CONTAINER },
{ "pstore", "/sys/fs/pstore", "pstore", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV,
NULL, MNT_NONE },
#ifdef ENABLE_EFI
@@ -159,7 +159,7 @@ static int mount_one(const MountPoint *p, bool relabel) {
if (relabel)
(void) label_fix(p->where, true, true);
- r = path_is_mount_point(p->where, AT_SYMLINK_FOLLOW);
+ r = path_is_mount_point(p->where, NULL, AT_SYMLINK_FOLLOW);
if (r < 0 && r != -ENOENT) {
log_full_errno((p->mode & MNT_FATAL) ? LOG_ERR : LOG_DEBUG, r, "Failed to determine whether %s is a mount point: %m", p->where);
return (p->mode & MNT_FATAL) ? r : 0;
@@ -360,7 +360,6 @@ int mount_setup(bool loaded_policy) {
int r = 0;
r = mount_points_setup(ELEMENTSOF(mount_table), loaded_policy);
-
if (r < 0)
return r;
@@ -391,25 +390,24 @@ int mount_setup(bool loaded_policy) {
* udevd. */
dev_setup(NULL, UID_INVALID, GID_INVALID);
- /* Mark the root directory as shared in regards to mount
- * propagation. The kernel defaults to "private", but we think
- * it makes more sense to have a default of "shared" so that
- * nspawn and the container tools work out of the box. If
- * specific setups need other settings they can reset the
- * propagation mode to private if needed. */
+ /* Mark the root directory as shared in regards to mount propagation. The kernel defaults to "private", but we
+ * think it makes more sense to have a default of "shared" so that nspawn and the container tools work out of
+ * the box. If specific setups need other settings they can reset the propagation mode to private if
+ * needed. Note that we set this only when we are invoked directly by the kernel. If we are invoked by a
+ * container manager we assume the container manager knows what it is doing (for example, because it set up
+ * some directories with different propagation modes). */
if (detect_container() <= 0)
if (mount(NULL, "/", NULL, MS_REC|MS_SHARED, NULL) < 0)
log_warning_errno(errno, "Failed to set up the root directory for shared mount propagation: %m");
- /* Create a few directories we always want around, Note that
- * sd_booted() checks for /run/systemd/system, so this mkdir
- * really needs to stay for good, otherwise software that
- * copied sd-daemon.c into their sources will misdetect
- * systemd. */
+ /* Create a few directories we always want around, Note that sd_booted() checks for /run/systemd/system, so
+ * this mkdir really needs to stay for good, otherwise software that copied sd-daemon.c into their sources will
+ * misdetect systemd. */
(void) mkdir_label("/run/systemd", 0755);
(void) mkdir_label("/run/systemd/system", 0755);
- (void) mkdir_label("/run/systemd/inaccessible", 0000);
+
/* Set up inaccessible items */
+ (void) mkdir_label("/run/systemd/inaccessible", 0000);
(void) mknod("/run/systemd/inaccessible/reg", S_IFREG | 0000, 0);
(void) mkdir_label("/run/systemd/inaccessible/dir", 0000);
(void) mknod("/run/systemd/inaccessible/chr", S_IFCHR | 0000, makedev(0, 0));
diff --git a/src/core/mount.c b/src/core/mount.c
index d749e49df5..214364d87d 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -28,7 +28,7 @@
#include "dbus-mount.h"
#include "escape.h"
#include "exit-status.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "fstab-util.h"
#include "log.h"
#include "manager.h"
@@ -135,6 +135,16 @@ static bool mount_state_active(MountState state) {
MOUNT_REMOUNTING_SIGKILL);
}
+static bool mount_is_bound_to_device(const Mount *m) {
+ const MountParameters *p;
+
+ if (m->from_fragment)
+ return true;
+
+ p = &m->parameters_proc_self_mountinfo;
+ return fstab_test_option(p->options, "x-systemd.device-bound\0");
+}
+
static bool needs_quota(const MountParameters *p) {
assert(p);
@@ -324,6 +334,7 @@ static int mount_add_mount_links(Mount *m) {
static int mount_add_device_links(Mount *m) {
MountParameters *p;
bool device_wants_mount = false;
+ UnitDependency dep;
int r;
assert(m);
@@ -353,7 +364,14 @@ static int mount_add_device_links(Mount *m) {
if (mount_is_auto(p) && !mount_is_automount(p) && MANAGER_IS_SYSTEM(UNIT(m)->manager))
device_wants_mount = true;
- r = unit_add_node_link(UNIT(m), p->what, device_wants_mount, m->from_fragment ? UNIT_BINDS_TO : UNIT_REQUIRES);
+ /* Mount units from /proc/self/mountinfo are not bound to devices
+ * by default since they're subject to races when devices are
+ * unplugged. But the user can still force this dep with an
+ * appropriate option (or udev property) so the mount units are
+ * automatically stopped when the device disappears suddenly. */
+ dep = mount_is_bound_to_device(m) ? UNIT_BINDS_TO : UNIT_REQUIRES;
+
+ r = unit_add_node_link(UNIT(m), p->what, device_wants_mount, dep);
if (r < 0)
return r;
@@ -387,19 +405,35 @@ static int mount_add_quota_links(Mount *m) {
return 0;
}
-static bool should_umount(Mount *m) {
+static bool mount_is_extrinsic(Mount *m) {
MountParameters *p;
+ assert(m);
- if (PATH_IN_SET(m->where, "/", "/usr") ||
- path_startswith(m->where, "/run/initramfs"))
- return false;
+ /* Returns true for all units that are "magic" and should be excluded from the usual start-up and shutdown
+ * dependencies. We call them "extrinsic" here, as they are generally mounted outside of the systemd dependency
+ * logic. We shouldn't attempt to manage them ourselves but it's fine if the user operates on them with us. */
+
+ if (!MANAGER_IS_SYSTEM(UNIT(m)->manager)) /* We only automatically manage mounts if we are in system mode */
+ return true;
+
+ if (PATH_IN_SET(m->where, /* Don't bother with the OS data itself */
+ "/",
+ "/usr"))
+ return true;
+
+ if (PATH_STARTSWITH_SET(m->where,
+ "/run/initramfs", /* This should stay around from before we boot until after we shutdown */
+ "/proc", /* All of this is API VFS */
+ "/sys", /* … dito … */
+ "/dev")) /* … dito … */
+ return true;
+ /* If this is an initrd mount, and we are not in the initrd, then leave this around forever, too. */
p = get_mount_parameters(m);
- if (p && fstab_test_option(p->options, "x-initrd.mount\0") &&
- !in_initrd())
- return false;
+ if (p && fstab_test_option(p->options, "x-initrd.mount\0") && !in_initrd())
+ return true;
- return true;
+ return false;
}
static int mount_add_default_dependencies(Mount *m) {
@@ -412,20 +446,10 @@ static int mount_add_default_dependencies(Mount *m) {
if (!UNIT(m)->default_dependencies)
return 0;
- if (!MANAGER_IS_SYSTEM(UNIT(m)->manager))
- return 0;
-
- /* We do not add any default dependencies to /, /usr or
- * /run/initramfs/, since they are guaranteed to stay
- * mounted the whole time, since our system is on it.
- * Also, don't bother with anything mounted below virtual
- * file systems, it's also going to be virtual, and hence
- * not worth the effort. */
- if (PATH_IN_SET(m->where, "/", "/usr") ||
- path_startswith(m->where, "/run/initramfs") ||
- path_startswith(m->where, "/proc") ||
- path_startswith(m->where, "/sys") ||
- path_startswith(m->where, "/dev"))
+ /* We do not add any default dependencies to /, /usr or /run/initramfs/, since they are guaranteed to stay
+ * mounted the whole time, since our system is on it. Also, don't bother with anything mounted below virtual
+ * file systems, it's also going to be virtual, and hence not worth the effort. */
+ if (mount_is_extrinsic(m))
return 0;
p = get_mount_parameters(m);
@@ -462,11 +486,9 @@ static int mount_add_default_dependencies(Mount *m) {
if (r < 0)
return r;
- if (should_umount(m)) {
- r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
- if (r < 0)
- return r;
- }
+ r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
+ if (r < 0)
+ return r;
return 0;
}
@@ -688,6 +710,7 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) {
"%sOptions: %s\n"
"%sFrom /proc/self/mountinfo: %s\n"
"%sFrom fragment: %s\n"
+ "%sExtrinsic: %s\n"
"%sDirectoryMode: %04o\n"
"%sSloppyOptions: %s\n"
"%sLazyUnmount: %s\n"
@@ -700,6 +723,7 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) {
prefix, p ? strna(p->options) : "n/a",
prefix, yes_no(m->from_proc_self_mountinfo),
prefix, yes_no(m->from_fragment),
+ prefix, yes_no(mount_is_extrinsic(m)),
prefix, m->directory_mode,
prefix, yes_no(m->sloppy_options),
prefix, yes_no(m->lazy_unmount),
@@ -747,7 +771,7 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
return r;
exec_params.environment = UNIT(m)->manager->environment;
- exec_params.flags |= UNIT(m)->manager->confirm_spawn ? EXEC_CONFIRM_SPAWN : 0;
+ exec_params.confirm_spawn = manager_get_confirm_spawn(UNIT(m)->manager);
exec_params.cgroup_supported = UNIT(m)->manager->cgroup_supported;
exec_params.cgroup_path = UNIT(m)->cgroup_path;
exec_params.cgroup_delegate = m->cgroup_context.delegate;
@@ -862,7 +886,7 @@ static void mount_enter_unmounting(Mount *m) {
m->control_command_id = MOUNT_EXEC_UNMOUNT;
m->control_command = m->exec_command + MOUNT_EXEC_UNMOUNT;
- r = exec_command_set(m->control_command, UMOUNT_PATH, m->where, NULL);
+ r = exec_command_set(m->control_command, UMOUNT_PATH, m->where, "-c", NULL);
if (r >= 0 && m->lazy_unmount)
r = exec_command_append(m->control_command, "-l", NULL);
if (r >= 0 && m->force_unmount)
@@ -1217,7 +1241,7 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
if (f == MOUNT_SUCCESS || m->from_proc_self_mountinfo)
/* If /bin/mount returned success, or if we see the mount point in /proc/self/mountinfo we are
- * happy. If we see the first condition first, we should see the the second condition
+ * happy. If we see the first condition first, we should see the second condition
* immediately after – or /bin/mount lies to us and is broken. */
mount_enter_mounted(m, f);
else
@@ -1363,6 +1387,129 @@ static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *user
return 0;
}
+typedef struct {
+ bool is_mounted;
+ bool just_mounted;
+ bool just_changed;
+} MountSetupFlags;
+
+static int mount_setup_new_unit(
+ Unit *u,
+ const char *what,
+ const char *where,
+ const char *options,
+ const char *fstype,
+ MountSetupFlags *flags) {
+
+ MountParameters *p;
+
+ assert(u);
+ assert(flags);
+
+ u->source_path = strdup("/proc/self/mountinfo");
+ MOUNT(u)->where = strdup(where);
+ if (!u->source_path || !MOUNT(u)->where)
+ return -ENOMEM;
+
+ /* Make sure to initialize those fields before mount_is_extrinsic(). */
+ MOUNT(u)->from_proc_self_mountinfo = true;
+ p = &MOUNT(u)->parameters_proc_self_mountinfo;
+
+ p->what = strdup(what);
+ p->options = strdup(options);
+ p->fstype = strdup(fstype);
+ if (!p->what || !p->options || !p->fstype)
+ return -ENOMEM;
+
+ if (!mount_is_extrinsic(MOUNT(u))) {
+ const char *target;
+ int r;
+
+ target = mount_is_network(p) ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET;
+ r = unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true);
+ if (r < 0)
+ return r;
+
+ r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
+ if (r < 0)
+ return r;
+ }
+
+ unit_add_to_load_queue(u);
+ flags->is_mounted = true;
+ flags->just_mounted = true;
+ flags->just_changed = true;
+
+ return 0;
+}
+
+static int mount_setup_existing_unit(
+ Unit *u,
+ const char *what,
+ const char *where,
+ const char *options,
+ const char *fstype,
+ MountSetupFlags *flags) {
+
+ MountParameters *p;
+ bool load_extras = false;
+ int r1, r2, r3;
+
+ assert(u);
+ assert(flags);
+
+ if (!MOUNT(u)->where) {
+ MOUNT(u)->where = strdup(where);
+ if (!MOUNT(u)->where)
+ return -ENOMEM;
+ }
+
+ /* Make sure to initialize those fields before mount_is_extrinsic(). */
+ p = &MOUNT(u)->parameters_proc_self_mountinfo;
+
+ r1 = free_and_strdup(&p->what, what);
+ r2 = free_and_strdup(&p->options, options);
+ r3 = free_and_strdup(&p->fstype, fstype);
+ if (r1 < 0 || r2 < 0 || r3 < 0)
+ return -ENOMEM;
+
+ flags->just_changed = r1 > 0 || r2 > 0 || r3 > 0;
+ flags->is_mounted = true;
+ flags->just_mounted = !MOUNT(u)->from_proc_self_mountinfo;
+
+ MOUNT(u)->from_proc_self_mountinfo = true;
+
+ if (!mount_is_extrinsic(MOUNT(u)) && mount_is_network(p)) {
+ /* _netdev option may have shown up late, or on a
+ * remount. Add remote-fs dependencies, even though
+ * local-fs ones may already be there.
+ *
+ * Note: due to a current limitation (we don't track
+ * in the dependency "Set*" objects who created a
+ * dependency), we can only add deps, never lose them,
+ * until the next full daemon-reload. */
+ unit_add_dependency_by_name(u, UNIT_BEFORE, SPECIAL_REMOTE_FS_TARGET, NULL, true);
+ load_extras = true;
+ }
+
+ if (u->load_state == UNIT_NOT_FOUND) {
+ u->load_state = UNIT_LOADED;
+ u->load_error = 0;
+
+ /* Load in the extras later on, after we
+ * finished initialization of the unit */
+
+ /* FIXME: since we're going to load the unit later on, why setting load_extras=true ? */
+ load_extras = true;
+ flags->just_changed = true;
+ }
+
+ if (load_extras)
+ return mount_add_extras(MOUNT(u));
+
+ return 0;
+}
+
static int mount_setup_unit(
Manager *m,
const char *what,
@@ -1371,10 +1518,8 @@ static int mount_setup_unit(
const char *fstype,
bool set_flags) {
- _cleanup_free_ char *e = NULL, *w = NULL, *o = NULL, *f = NULL;
- bool load_extras = false;
- MountParameters *p;
- bool delete, changed = false;
+ _cleanup_free_ char *e = NULL;
+ MountSetupFlags flags;
Unit *u;
int r;
@@ -1402,116 +1547,34 @@ static int mount_setup_unit(
u = manager_get_unit(m, e);
if (!u) {
- delete = true;
-
+ /* First time we see this mount point meaning that it's
+ * not been initiated by a mount unit but rather by the
+ * sysadmin having called mount(8) directly. */
r = unit_new_for_name(m, sizeof(Mount), e, &u);
if (r < 0)
goto fail;
- MOUNT(u)->where = strdup(where);
- if (!MOUNT(u)->where) {
- r = -ENOMEM;
- goto fail;
- }
-
- u->source_path = strdup("/proc/self/mountinfo");
- if (!u->source_path) {
- r = -ENOMEM;
- goto fail;
- }
-
- if (MANAGER_IS_SYSTEM(m)) {
- const char* target;
-
- target = mount_needs_network(options, fstype) ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET;
- r = unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true);
- if (r < 0)
- goto fail;
-
- if (should_umount(MOUNT(u))) {
- r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
- if (r < 0)
- goto fail;
- }
- }
-
- unit_add_to_load_queue(u);
- changed = true;
- } else {
- delete = false;
-
- if (!MOUNT(u)->where) {
- MOUNT(u)->where = strdup(where);
- if (!MOUNT(u)->where) {
- r = -ENOMEM;
- goto fail;
- }
- }
-
- if (MANAGER_IS_SYSTEM(m) &&
- mount_needs_network(options, fstype)) {
- /* _netdev option may have shown up late, or on a
- * remount. Add remote-fs dependencies, even though
- * local-fs ones may already be there. */
- unit_add_dependency_by_name(u, UNIT_BEFORE, SPECIAL_REMOTE_FS_TARGET, NULL, true);
- load_extras = true;
- }
-
- if (u->load_state == UNIT_NOT_FOUND) {
- u->load_state = UNIT_LOADED;
- u->load_error = 0;
-
- /* Load in the extras later on, after we
- * finished initialization of the unit */
- load_extras = true;
- changed = true;
- }
- }
+ r = mount_setup_new_unit(u, what, where, options, fstype, &flags);
+ if (r < 0)
+ unit_free(u);
+ } else
+ r = mount_setup_existing_unit(u, what, where, options, fstype, &flags);
- w = strdup(what);
- o = strdup(options);
- f = strdup(fstype);
- if (!w || !o || !f) {
- r = -ENOMEM;
+ if (r < 0)
goto fail;
- }
-
- p = &MOUNT(u)->parameters_proc_self_mountinfo;
-
- changed = changed ||
- !streq_ptr(p->options, options) ||
- !streq_ptr(p->what, what) ||
- !streq_ptr(p->fstype, fstype);
if (set_flags) {
- MOUNT(u)->is_mounted = true;
- MOUNT(u)->just_mounted = !MOUNT(u)->from_proc_self_mountinfo;
- MOUNT(u)->just_changed = changed;
- }
-
- MOUNT(u)->from_proc_self_mountinfo = true;
-
- free_and_replace(p->what, w);
- free_and_replace(p->options, o);
- free_and_replace(p->fstype, f);
-
- if (load_extras) {
- r = mount_add_extras(MOUNT(u));
- if (r < 0)
- goto fail;
+ MOUNT(u)->is_mounted = flags.is_mounted;
+ MOUNT(u)->just_mounted = flags.just_mounted;
+ MOUNT(u)->just_changed = flags.just_changed;
}
- if (changed)
+ if (flags.just_changed)
unit_add_to_dbus_queue(u);
return 0;
-
fail:
log_warning_errno(r, "Failed to set up mount unit: %m");
-
- if (delete && u)
- unit_free(u);
-
return r;
}
diff --git a/src/core/namespace.c b/src/core/namespace.c
index 1195e9a854..4f29217bc4 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -30,6 +30,7 @@
#include "dev-setup.h"
#include "fd-util.h"
#include "fs-util.h"
+#include "loop-util.h"
#include "loopback-setup.h"
#include "missing.h"
#include "mkdir.h"
@@ -50,91 +51,94 @@
typedef enum MountMode {
/* This is ordered by priority! */
INACCESSIBLE,
- READONLY,
+ BIND_MOUNT,
+ BIND_MOUNT_RECURSIVE,
PRIVATE_TMP,
PRIVATE_VAR_TMP,
PRIVATE_DEV,
+ BIND_DEV,
+ SYSFS,
+ PROCFS,
+ READONLY,
READWRITE,
} MountMode;
-typedef struct BindMount {
- const char *path; /* stack memory, doesn't need to be freed explicitly */
- char *chased; /* malloc()ed memory, needs to be freed */
- MountMode mode;
- bool ignore; /* Ignore if path does not exist */
-} BindMount;
-
-typedef struct TargetMount {
- const char *path;
- MountMode mode;
- bool ignore; /* Ignore if path does not exist */
-} TargetMount;
-
-/*
- * The following Protect tables are to protect paths and mark some of them
- * READONLY, in case a path is covered by an option from another table, then
- * it is marked READWRITE in the current one, and the more restrictive mode is
- * applied from that other table. This way all options can be combined in a
- * safe and comprehensible way for users.
- */
+typedef struct MountEntry {
+ const char *path_const; /* Memory allocated on stack or static */
+ MountMode mode:5;
+ bool ignore:1; /* Ignore if path does not exist? */
+ bool has_prefix:1; /* Already is prefixed by the root dir? */
+ bool read_only:1; /* Shall this mount point be read-only? */
+ char *path_malloc; /* Use this instead of 'path' if we had to allocate memory */
+ const char *source_const; /* The source path, for bind mounts */
+ char *source_malloc;
+} MountEntry;
+
+/* If MountAPIVFS= is used, let's mount /sys and /proc into the it, but only as a fallback if the user hasn't mounted
+ * something there already. These mounts are hence overriden by any other explicitly configured mounts. */
+static const MountEntry apivfs_table[] = {
+ { "/proc", PROCFS, false },
+ { "/dev", BIND_DEV, false },
+ { "/sys", SYSFS, false },
+};
/* ProtectKernelTunables= option and the related filesystem APIs */
-static const TargetMount protect_kernel_tunables_table[] = {
- { "/proc/sys", READONLY, false },
- { "/proc/sysrq-trigger", READONLY, true },
- { "/proc/latency_stats", READONLY, true },
- { "/proc/mtrr", READONLY, true },
- { "/proc/apm", READONLY, true },
- { "/proc/acpi", READONLY, true },
- { "/proc/timer_stats", READONLY, true },
- { "/proc/asound", READONLY, true },
- { "/proc/bus", READONLY, true },
- { "/proc/fs", READONLY, true },
- { "/proc/irq", READONLY, true },
- { "/sys", READONLY, false },
- { "/sys/kernel/debug", READONLY, true },
- { "/sys/kernel/tracing", READONLY, true },
- { "/sys/fs/cgroup", READWRITE, false }, /* READONLY is set by ProtectControlGroups= option */
+static const MountEntry protect_kernel_tunables_table[] = {
+ { "/proc/sys", READONLY, false },
+ { "/proc/sysrq-trigger", READONLY, true },
+ { "/proc/latency_stats", READONLY, true },
+ { "/proc/mtrr", READONLY, true },
+ { "/proc/apm", READONLY, true }, /* Obsolete API, there's no point in permitting access to this, ever */
+ { "/proc/acpi", READONLY, true },
+ { "/proc/timer_stats", READONLY, true },
+ { "/proc/asound", READONLY, true },
+ { "/proc/bus", READONLY, true },
+ { "/proc/fs", READONLY, true },
+ { "/proc/irq", READONLY, true },
+ { "/sys", READONLY, false },
+ { "/sys/kernel/debug", READONLY, true },
+ { "/sys/kernel/tracing", READONLY, true },
+ { "/sys/fs/cgroup", READWRITE, false }, /* READONLY is set by ProtectControlGroups= option */
};
/* ProtectKernelModules= option */
-static const TargetMount protect_kernel_modules_table[] = {
+static const MountEntry protect_kernel_modules_table[] = {
#ifdef HAVE_SPLIT_USR
- { "/lib/modules", INACCESSIBLE, true },
+ { "/lib/modules", INACCESSIBLE, true },
#endif
- { "/usr/lib/modules", INACCESSIBLE, true },
+ { "/usr/lib/modules", INACCESSIBLE, true },
};
/*
* ProtectHome=read-only table, protect $HOME and $XDG_RUNTIME_DIR and rest of
* system should be protected by ProtectSystem=
*/
-static const TargetMount protect_home_read_only_table[] = {
- { "/home", READONLY, true },
- { "/run/user", READONLY, true },
- { "/root", READONLY, true },
+static const MountEntry protect_home_read_only_table[] = {
+ { "/home", READONLY, true },
+ { "/run/user", READONLY, true },
+ { "/root", READONLY, true },
};
/* ProtectHome=yes table */
-static const TargetMount protect_home_yes_table[] = {
- { "/home", INACCESSIBLE, true },
- { "/run/user", INACCESSIBLE, true },
- { "/root", INACCESSIBLE, true },
+static const MountEntry protect_home_yes_table[] = {
+ { "/home", INACCESSIBLE, true },
+ { "/run/user", INACCESSIBLE, true },
+ { "/root", INACCESSIBLE, true },
};
/* ProtectSystem=yes table */
-static const TargetMount protect_system_yes_table[] = {
- { "/usr", READONLY, false },
- { "/boot", READONLY, true },
- { "/efi", READONLY, true },
+static const MountEntry protect_system_yes_table[] = {
+ { "/usr", READONLY, false },
+ { "/boot", READONLY, true },
+ { "/efi", READONLY, true },
};
/* ProtectSystem=full includes ProtectSystem=yes */
-static const TargetMount protect_system_full_table[] = {
- { "/usr", READONLY, false },
- { "/boot", READONLY, true },
- { "/efi", READONLY, true },
- { "/etc", READONLY, false },
+static const MountEntry protect_system_full_table[] = {
+ { "/usr", READONLY, false },
+ { "/boot", READONLY, true },
+ { "/efi", READONLY, true },
+ { "/etc", READONLY, false },
};
/*
@@ -145,143 +149,163 @@ static const TargetMount protect_system_full_table[] = {
* (And of course /home and friends are also left writable, as ProtectHome=
* shall manage those, orthogonally).
*/
-static const TargetMount protect_system_strict_table[] = {
- { "/", READONLY, false },
- { "/proc", READWRITE, false }, /* ProtectKernelTunables= */
- { "/sys", READWRITE, false }, /* ProtectKernelTunables= */
- { "/dev", READWRITE, false }, /* PrivateDevices= */
- { "/home", READWRITE, true }, /* ProtectHome= */
- { "/run/user", READWRITE, true }, /* ProtectHome= */
- { "/root", READWRITE, true }, /* ProtectHome= */
+static const MountEntry protect_system_strict_table[] = {
+ { "/", READONLY, false },
+ { "/proc", READWRITE, false }, /* ProtectKernelTunables= */
+ { "/sys", READWRITE, false }, /* ProtectKernelTunables= */
+ { "/dev", READWRITE, false }, /* PrivateDevices= */
+ { "/home", READWRITE, true }, /* ProtectHome= */
+ { "/run/user", READWRITE, true }, /* ProtectHome= */
+ { "/root", READWRITE, true }, /* ProtectHome= */
};
-static void set_bind_mount(BindMount **p, const char *path, MountMode mode, bool ignore) {
- (*p)->path = path;
- (*p)->mode = mode;
- (*p)->ignore = ignore;
+static const char *mount_entry_path(const MountEntry *p) {
+ assert(p);
+
+ /* Returns the path of this bind mount. If the malloc()-allocated ->path_buffer field is set we return that,
+ * otherwise the stack/static ->path field is returned. */
+
+ return p->path_malloc ?: p->path_const;
+}
+
+static bool mount_entry_read_only(const MountEntry *p) {
+ assert(p);
+
+ return p->read_only || IN_SET(p->mode, READONLY, INACCESSIBLE);
}
-static int append_mounts(BindMount **p, char **strv, MountMode mode) {
+static const char *mount_entry_source(const MountEntry *p) {
+ assert(p);
+
+ return p->source_malloc ?: p->source_const;
+}
+
+static void mount_entry_done(MountEntry *p) {
+ assert(p);
+
+ p->path_malloc = mfree(p->path_malloc);
+ p->source_malloc = mfree(p->source_malloc);
+}
+
+static int append_access_mounts(MountEntry **p, char **strv, MountMode mode) {
char **i;
assert(p);
+ /* Adds a list of user-supplied READWRITE/READONLY/INACCESSIBLE entries */
+
STRV_FOREACH(i, strv) {
- bool ignore = false;
+ bool ignore = false, needs_prefix = false;
+ const char *e = *i;
- if (IN_SET(mode, INACCESSIBLE, READONLY, READWRITE) && startswith(*i, "-")) {
- (*i)++;
+ /* Look for any prefixes */
+ if (startswith(e, "-")) {
+ e++;
ignore = true;
}
+ if (startswith(e, "+")) {
+ e++;
+ needs_prefix = true;
+ }
- if (!path_is_absolute(*i))
+ if (!path_is_absolute(e))
return -EINVAL;
- set_bind_mount(p, *i, mode, ignore);
- (*p)++;
+ *((*p)++) = (MountEntry) {
+ .path_const = e,
+ .mode = mode,
+ .ignore = ignore,
+ .has_prefix = !needs_prefix,
+ };
}
return 0;
}
-static int append_target_mounts(BindMount **p, const char *root_directory, const TargetMount *mounts, const size_t size) {
+static int append_bind_mounts(MountEntry **p, const BindMount *binds, unsigned n) {
unsigned i;
assert(p);
- assert(mounts);
- for (i = 0; i < size; i++) {
- /*
- * Here we assume that the ignore field is set during
- * declaration we do not support "-" at the beginning.
- */
- const TargetMount *m = &mounts[i];
- const char *path = prefix_roota(root_directory, m->path);
+ for (i = 0; i < n; i++) {
+ const BindMount *b = binds + i;
- if (!path_is_absolute(path))
- return -EINVAL;
-
- set_bind_mount(p, path, m->mode, m->ignore);
- (*p)++;
+ *((*p)++) = (MountEntry) {
+ .path_const = b->destination,
+ .mode = b->recursive ? BIND_MOUNT_RECURSIVE : BIND_MOUNT,
+ .read_only = b->read_only,
+ .source_const = b->source,
+ };
}
return 0;
}
-static int append_protect_kernel_tunables(BindMount **p, const char *root_directory) {
+static int append_static_mounts(MountEntry **p, const MountEntry *mounts, unsigned n, bool ignore_protect) {
+ unsigned i;
+
assert(p);
+ assert(mounts);
- return append_target_mounts(p, root_directory, protect_kernel_tunables_table,
- ELEMENTSOF(protect_kernel_tunables_table));
-}
+ /* Adds a list of static pre-defined entries */
-static int append_protect_kernel_modules(BindMount **p, const char *root_directory) {
- assert(p);
+ for (i = 0; i < n; i++)
+ *((*p)++) = (MountEntry) {
+ .path_const = mount_entry_path(mounts+i),
+ .mode = mounts[i].mode,
+ .ignore = mounts[i].ignore || ignore_protect,
+ };
- return append_target_mounts(p, root_directory, protect_kernel_modules_table,
- ELEMENTSOF(protect_kernel_modules_table));
+ return 0;
}
-static int append_protect_home(BindMount **p, const char *root_directory, ProtectHome protect_home) {
- int r = 0;
-
+static int append_protect_home(MountEntry **p, ProtectHome protect_home, bool ignore_protect) {
assert(p);
- if (protect_home == PROTECT_HOME_NO)
+ switch (protect_home) {
+
+ case PROTECT_HOME_NO:
return 0;
- switch (protect_home) {
case PROTECT_HOME_READ_ONLY:
- r = append_target_mounts(p, root_directory, protect_home_read_only_table,
- ELEMENTSOF(protect_home_read_only_table));
- break;
+ return append_static_mounts(p, protect_home_read_only_table, ELEMENTSOF(protect_home_read_only_table), ignore_protect);
+
case PROTECT_HOME_YES:
- r = append_target_mounts(p, root_directory, protect_home_yes_table,
- ELEMENTSOF(protect_home_yes_table));
- break;
+ return append_static_mounts(p, protect_home_yes_table, ELEMENTSOF(protect_home_yes_table), ignore_protect);
+
default:
- r = -EINVAL;
- break;
+ assert_not_reached("Unexpected ProtectHome= value");
}
-
- return r;
}
-static int append_protect_system(BindMount **p, const char *root_directory, ProtectSystem protect_system) {
- int r = 0;
-
+static int append_protect_system(MountEntry **p, ProtectSystem protect_system, bool ignore_protect) {
assert(p);
- if (protect_system == PROTECT_SYSTEM_NO)
+ switch (protect_system) {
+
+ case PROTECT_SYSTEM_NO:
return 0;
- switch (protect_system) {
case PROTECT_SYSTEM_STRICT:
- r = append_target_mounts(p, root_directory, protect_system_strict_table,
- ELEMENTSOF(protect_system_strict_table));
- break;
+ return append_static_mounts(p, protect_system_strict_table, ELEMENTSOF(protect_system_strict_table), ignore_protect);
+
case PROTECT_SYSTEM_YES:
- r = append_target_mounts(p, root_directory, protect_system_yes_table,
- ELEMENTSOF(protect_system_yes_table));
- break;
+ return append_static_mounts(p, protect_system_yes_table, ELEMENTSOF(protect_system_yes_table), ignore_protect);
+
case PROTECT_SYSTEM_FULL:
- r = append_target_mounts(p, root_directory, protect_system_full_table,
- ELEMENTSOF(protect_system_full_table));
- break;
+ return append_static_mounts(p, protect_system_full_table, ELEMENTSOF(protect_system_full_table), ignore_protect);
+
default:
- r = -EINVAL;
- break;
+ assert_not_reached("Unexpected ProtectSystem= value");
}
-
- return r;
}
static int mount_path_compare(const void *a, const void *b) {
- const BindMount *p = a, *q = b;
+ const MountEntry *p = a, *q = b;
int d;
/* If the paths are not equal, then order prefixes first */
- d = path_compare(p->path, q->path);
+ d = path_compare(mount_entry_path(p), mount_entry_path(q));
if (d != 0)
return d;
@@ -295,20 +319,50 @@ static int mount_path_compare(const void *a, const void *b) {
return 0;
}
-static void drop_duplicates(BindMount *m, unsigned *n) {
- BindMount *f, *t, *previous;
+static int prefix_where_needed(MountEntry *m, unsigned n, const char *root_directory) {
+ unsigned i;
+
+ /* Prefixes all paths in the bind mount table with the root directory if it is specified and the entry needs
+ * that. */
+
+ if (!root_directory)
+ return 0;
+
+ for (i = 0; i < n; i++) {
+ char *s;
+
+ if (m[i].has_prefix)
+ continue;
+
+ s = prefix_root(root_directory, mount_entry_path(m+i));
+ if (!s)
+ return -ENOMEM;
+
+ free(m[i].path_malloc);
+ m[i].path_malloc = s;
+
+ m[i].has_prefix = true;
+ }
+
+ return 0;
+}
+
+static void drop_duplicates(MountEntry *m, unsigned *n) {
+ MountEntry *f, *t, *previous;
assert(m);
assert(n);
/* Drops duplicate entries. Expects that the array is properly ordered already. */
- for (f = m, t = m, previous = NULL; f < m+*n; f++) {
+ for (f = m, t = m, previous = NULL; f < m + *n; f++) {
/* The first one wins (which is the one with the more restrictive mode), see mount_path_compare()
* above. */
- if (previous && path_equal(f->path, previous->path)) {
- log_debug("%s is duplicate.", f->path);
+ if (previous && path_equal(mount_entry_path(f), mount_entry_path(previous))) {
+ log_debug("%s is duplicate.", mount_entry_path(f));
+ previous->read_only = previous->read_only || mount_entry_read_only(f); /* Propagate the read-only flag to the remaining entry */
+ mount_entry_done(f);
continue;
}
@@ -320,8 +374,8 @@ static void drop_duplicates(BindMount *m, unsigned *n) {
*n = t - m;
}
-static void drop_inaccessible(BindMount *m, unsigned *n) {
- BindMount *f, *t;
+static void drop_inaccessible(MountEntry *m, unsigned *n) {
+ MountEntry *f, *t;
const char *clear = NULL;
assert(m);
@@ -330,16 +384,17 @@ static void drop_inaccessible(BindMount *m, unsigned *n) {
/* Drops all entries obstructed by another entry further up the tree. Expects that the array is properly
* ordered already. */
- for (f = m, t = m; f < m+*n; f++) {
+ for (f = m, t = m; f < m + *n; f++) {
/* If we found a path set for INACCESSIBLE earlier, and this entry has it as prefix we should drop
* it, as inaccessible paths really should drop the entire subtree. */
- if (clear && path_startswith(f->path, clear)) {
- log_debug("%s is masked by %s.", f->path, clear);
+ if (clear && path_startswith(mount_entry_path(f), clear)) {
+ log_debug("%s is masked by %s.", mount_entry_path(f), clear);
+ mount_entry_done(f);
continue;
}
- clear = f->mode == INACCESSIBLE ? f->path : NULL;
+ clear = f->mode == INACCESSIBLE ? mount_entry_path(f) : NULL;
*t = *f;
t++;
@@ -348,8 +403,8 @@ static void drop_inaccessible(BindMount *m, unsigned *n) {
*n = t - m;
}
-static void drop_nop(BindMount *m, unsigned *n) {
- BindMount *f, *t;
+static void drop_nop(MountEntry *m, unsigned *n) {
+ MountEntry *f, *t;
assert(m);
assert(n);
@@ -357,16 +412,16 @@ static void drop_nop(BindMount *m, unsigned *n) {
/* Drops all entries which have an immediate parent that has the same type, as they are redundant. Assumes the
* list is ordered by prefixes. */
- for (f = m, t = m; f < m+*n; f++) {
+ for (f = m, t = m; f < m + *n; f++) {
/* Only suppress such subtrees for READONLY and READWRITE entries */
if (IN_SET(f->mode, READONLY, READWRITE)) {
- BindMount *p;
+ MountEntry *p;
bool found = false;
/* Now let's find the first parent of the entry we are looking at. */
for (p = t-1; p >= m; p--) {
- if (path_startswith(f->path, p->path)) {
+ if (path_startswith(mount_entry_path(f), mount_entry_path(p))) {
found = true;
break;
}
@@ -374,7 +429,8 @@ static void drop_nop(BindMount *m, unsigned *n) {
/* We found it, let's see if it's the same mode, if so, we can drop this entry */
if (found && p->mode == f->mode) {
- log_debug("%s is redundant by %s", f->path, p->path);
+ log_debug("%s is redundant by %s", mount_entry_path(f), mount_entry_path(p));
+ mount_entry_done(f);
continue;
}
}
@@ -386,21 +442,23 @@ static void drop_nop(BindMount *m, unsigned *n) {
*n = t - m;
}
-static void drop_outside_root(const char *root_directory, BindMount *m, unsigned *n) {
- BindMount *f, *t;
+static void drop_outside_root(const char *root_directory, MountEntry *m, unsigned *n) {
+ MountEntry *f, *t;
assert(m);
assert(n);
+ /* Nothing to do */
if (!root_directory)
return;
/* Drops all mounts that are outside of the root directory. */
- for (f = m, t = m; f < m+*n; f++) {
+ for (f = m, t = m; f < m + *n; f++) {
- if (!path_startswith(f->path, root_directory)) {
- log_debug("%s is outside of root directory.", f->path);
+ if (!path_startswith(mount_entry_path(f), root_directory)) {
+ log_debug("%s is outside of root directory.", mount_entry_path(f));
+ mount_entry_done(f);
continue;
}
@@ -411,7 +469,7 @@ static void drop_outside_root(const char *root_directory, BindMount *m, unsigned
*n = t - m;
}
-static int mount_dev(BindMount *m) {
+static int mount_private_dev(MountEntry *m) {
static const char devnodes[] =
"/dev/null\0"
"/dev/zero\0"
@@ -516,11 +574,11 @@ static int mount_dev(BindMount *m) {
* missing when the service is started with RootDirectory. This is
* consistent with mount units creating the mount points when missing.
*/
- (void) mkdir_p_label(m->path, 0755);
+ (void) mkdir_p_label(mount_entry_path(m), 0755);
/* Unmount everything in old /dev */
- umount_recursive(m->path, 0);
- if (mount(dev, m->path, NULL, MS_MOVE, NULL) < 0) {
+ umount_recursive(mount_entry_path(m), 0);
+ if (mount(dev, mount_entry_path(m), NULL, MS_MOVE, NULL) < 0) {
r = -errno;
goto fail;
}
@@ -550,17 +608,110 @@ fail:
return r;
}
+static int mount_bind_dev(MountEntry *m) {
+ int r;
+
+ assert(m);
+
+ /* Implements the little brother of mount_private_dev(): simply bind mounts the host's /dev into the service's
+ * /dev. This is only used when RootDirectory= is set. */
+
+ r = path_is_mount_point(mount_entry_path(m), NULL, 0);
+ if (r < 0)
+ return log_debug_errno(r, "Unable to determine whether /dev is already mounted: %m");
+ if (r > 0) /* make this a NOP if /dev is already a mount point */
+ return 0;
+
+ if (mount("/dev", mount_entry_path(m), NULL, MS_BIND|MS_REC, NULL) < 0)
+ return log_debug_errno(errno, "Failed to bind mount %s: %m", mount_entry_path(m));
+
+ return 1;
+}
+
+static int mount_sysfs(MountEntry *m) {
+ int r;
+
+ assert(m);
+
+ r = path_is_mount_point(mount_entry_path(m), NULL, 0);
+ if (r < 0)
+ return log_debug_errno(r, "Unable to determine whether /sys is already mounted: %m");
+ if (r > 0) /* make this a NOP if /sys is already a mount point */
+ return 0;
+
+ /* Bind mount the host's version so that we get all child mounts of it, too. */
+ if (mount("/sys", mount_entry_path(m), NULL, MS_BIND|MS_REC, NULL) < 0)
+ return log_debug_errno(errno, "Failed to mount %s: %m", mount_entry_path(m));
+
+ return 1;
+}
+
+static int mount_procfs(MountEntry *m) {
+ int r;
+
+ assert(m);
+
+ r = path_is_mount_point(mount_entry_path(m), NULL, 0);
+ if (r < 0)
+ return log_debug_errno(r, "Unable to determine whether /proc is already mounted: %m");
+ if (r > 0) /* make this a NOP if /proc is already a mount point */
+ return 0;
+
+ /* Mount a new instance, so that we get the one that matches our user namespace, if we are running in one */
+ if (mount("proc", mount_entry_path(m), "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL) < 0)
+ return log_debug_errno(errno, "Failed to mount %s: %m", mount_entry_path(m));
+
+ return 1;
+}
+
+static int mount_entry_chase(
+ const char *root_directory,
+ MountEntry *m,
+ const char *path,
+ char **location) {
+
+ char *chased;
+ int r;
+
+ assert(m);
+
+ /* Since mount() will always follow symlinks and we need to take the different root directory into account we
+ * chase the symlinks on our own first. This is called for the destination path, as well as the source path (if
+ * that applies). The result is stored in "location". */
+
+ r = chase_symlinks(path, root_directory, 0, &chased);
+ if (r == -ENOENT && m->ignore) {
+ log_debug_errno(r, "Path %s does not exist, ignoring.", path);
+ return 0;
+ }
+ if (r < 0)
+ return log_debug_errno(r, "Failed to follow symlinks on %s: %m", path);
+
+ log_debug("Followed symlinks %s → %s.", path, chased);
+
+ free(*location);
+ *location = chased;
+
+ return 1;
+}
+
static int apply_mount(
- BindMount *m,
+ const char *root_directory,
+ MountEntry *m,
const char *tmp_dir,
const char *var_tmp_dir) {
const char *what;
+ bool rbind = true;
int r;
assert(m);
- log_debug("Applying namespace mount on %s", m->path);
+ r = mount_entry_chase(root_directory, m, mount_entry_path(m), &m->path_malloc);
+ if (r <= 0)
+ return r;
+
+ log_debug("Applying namespace mount on %s", mount_entry_path(m));
switch (m->mode) {
@@ -570,10 +721,10 @@ static int apply_mount(
/* First, get rid of everything that is below if there
* is anything... Then, overmount it with an
* inaccessible path. */
- (void) umount_recursive(m->path, 0);
+ (void) umount_recursive(mount_entry_path(m), 0);
- if (lstat(m->path, &target) < 0)
- return log_debug_errno(errno, "Failed to lstat() %s to determine what to mount over it: %m", m->path);
+ if (lstat(mount_entry_path(m), &target) < 0)
+ return log_debug_errno(errno, "Failed to lstat() %s to determine what to mount over it: %m", mount_entry_path(m));
what = mode_to_inaccessible_node(target.st_mode);
if (!what) {
@@ -585,15 +736,27 @@ static int apply_mount(
case READONLY:
case READWRITE:
-
- r = path_is_mount_point(m->path, 0);
+ r = path_is_mount_point(mount_entry_path(m), root_directory, 0);
if (r < 0)
- return log_debug_errno(r, "Failed to determine whether %s is already a mount point: %m", m->path);
+ return log_debug_errno(r, "Failed to determine whether %s is already a mount point: %m", mount_entry_path(m));
if (r > 0) /* Nothing to do here, it is already a mount. We just later toggle the MS_RDONLY bit for the mount point if needed. */
return 0;
-
/* This isn't a mount point yet, let's make it one. */
- what = m->path;
+ what = mount_entry_path(m);
+ break;
+
+ case BIND_MOUNT:
+ rbind = false;
+ /* fallthrough */
+
+ case BIND_MOUNT_RECURSIVE:
+ /* Also chase the source mount */
+
+ r = mount_entry_chase(root_directory, m, mount_entry_source(m), &m->source_malloc);
+ if (r <= 0)
+ return r;
+
+ what = mount_entry_source(m);
break;
case PRIVATE_TMP:
@@ -605,7 +768,16 @@ static int apply_mount(
break;
case PRIVATE_DEV:
- return mount_dev(m);
+ return mount_private_dev(m);
+
+ case BIND_DEV:
+ return mount_bind_dev(m);
+
+ case SYSFS:
+ return mount_sysfs(m);
+
+ case PROCFS:
+ return mount_procfs(m);
default:
assert_not_reached("Unknown mode");
@@ -613,22 +785,22 @@ static int apply_mount(
assert(what);
- if (mount(what, m->path, NULL, MS_BIND|MS_REC, NULL) < 0)
- return log_debug_errno(errno, "Failed to mount %s to %s: %m", what, m->path);
+ if (mount(what, mount_entry_path(m), NULL, MS_BIND|(rbind ? MS_REC : 0), NULL) < 0)
+ return log_debug_errno(errno, "Failed to mount %s to %s: %m", what, mount_entry_path(m));
- log_debug("Successfully mounted %s to %s", what, m->path);
+ log_debug("Successfully mounted %s to %s", what, mount_entry_path(m));
return 0;
}
-static int make_read_only(BindMount *m, char **blacklist) {
+static int make_read_only(MountEntry *m, char **blacklist) {
int r = 0;
assert(m);
- if (IN_SET(m->mode, INACCESSIBLE, READONLY))
- r = bind_remount_recursive(m->path, true, blacklist);
- else if (m->mode == PRIVATE_DEV) { /* Can be readonly but the submounts can't*/
- if (mount(NULL, m->path, NULL, MS_REMOUNT|DEV_MOUNT_OPTIONS|MS_RDONLY, NULL) < 0)
+ if (mount_entry_read_only(m))
+ r = bind_remount_recursive(mount_entry_path(m), true, blacklist);
+ else if (m->mode == PRIVATE_DEV) { /* Superblock can be readonly but the submounts can't */
+ if (mount(NULL, mount_entry_path(m), NULL, MS_REMOUNT|DEV_MOUNT_OPTIONS|MS_RDONLY, NULL) < 0)
r = -errno;
} else
return 0;
@@ -637,41 +809,21 @@ static int make_read_only(BindMount *m, char **blacklist) {
* already stays this way. This improves compatibility with container managers, where we won't attempt to undo
* read-only mounts already applied. */
+ if (r == -ENOENT && m->ignore)
+ r = 0;
+
return r;
}
-static int chase_all_symlinks(const char *root_directory, BindMount *m, unsigned *n) {
- BindMount *f, *t;
- int r;
+static bool namespace_info_mount_apivfs(const NameSpaceInfo *ns_info) {
+ assert(ns_info);
- assert(m);
- assert(n);
-
- /* Since mount() will always follow symlinks and we need to take the different root directory into account we
- * chase the symlinks on our own first. This call wil do so for all entries and remove all entries where we
- * can't resolve the path, and which have been marked for such removal. */
-
- for (f = m, t = m; f < m+*n; f++) {
-
- r = chase_symlinks(f->path, root_directory, &f->chased);
- if (r == -ENOENT && f->ignore) /* Doesn't exist? Then remove it! */
- continue;
- if (r < 0)
- return log_debug_errno(r, "Failed to chase symlinks for %s: %m", f->path);
+ /* ProtectControlGroups= and ProtectKernelTunables= imply MountAPIVFS=, since to protect the API VFS mounts,
+ * they need to be around in the first place... */
- if (path_equal(f->path, f->chased))
- f->chased = mfree(f->chased);
- else {
- log_debug("Chased %s → %s", f->path, f->chased);
- f->path = f->chased;
- }
-
- *t = *f;
- t++;
- }
-
- *n = t - m;
- return 0;
+ return ns_info->mount_apivfs ||
+ ns_info->protect_control_groups ||
+ ns_info->protect_kernel_tunables;
}
static unsigned namespace_calculate_mounts(
@@ -679,6 +831,8 @@ static unsigned namespace_calculate_mounts(
char** read_write_paths,
char** read_only_paths,
char** inaccessible_paths,
+ const BindMount *bind_mounts,
+ unsigned n_bind_mounts,
const char* tmp_dir,
const char* var_tmp_dir,
ProtectHome protect_home,
@@ -703,117 +857,177 @@ static unsigned namespace_calculate_mounts(
strv_length(read_write_paths) +
strv_length(read_only_paths) +
strv_length(inaccessible_paths) +
+ n_bind_mounts +
ns_info->private_dev +
(ns_info->protect_kernel_tunables ? ELEMENTSOF(protect_kernel_tunables_table) : 0) +
(ns_info->protect_control_groups ? 1 : 0) +
(ns_info->protect_kernel_modules ? ELEMENTSOF(protect_kernel_modules_table) : 0) +
- protect_home_cnt + protect_system_cnt;
+ protect_home_cnt + protect_system_cnt +
+ (namespace_info_mount_apivfs(ns_info) ? ELEMENTSOF(apivfs_table) : 0);
}
int setup_namespace(
const char* root_directory,
+ const char* root_image,
const NameSpaceInfo *ns_info,
char** read_write_paths,
char** read_only_paths,
char** inaccessible_paths,
+ const BindMount *bind_mounts,
+ unsigned n_bind_mounts,
const char* tmp_dir,
const char* var_tmp_dir,
ProtectHome protect_home,
ProtectSystem protect_system,
- unsigned long mount_flags) {
-
- BindMount *m, *mounts = NULL;
+ unsigned long mount_flags,
+ DissectImageFlags dissect_image_flags) {
+
+ _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
+ _cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
+ _cleanup_(dissected_image_unrefp) DissectedImage *dissected_image = NULL;
+ _cleanup_free_ void *root_hash = NULL;
+ MountEntry *m, *mounts = NULL;
+ size_t root_hash_size = 0;
bool make_slave = false;
- unsigned n;
+ unsigned n_mounts;
int r = 0;
+ assert(ns_info);
+
if (mount_flags == 0)
mount_flags = MS_SHARED;
- n = namespace_calculate_mounts(ns_info,
- read_write_paths,
- read_only_paths,
- inaccessible_paths,
- tmp_dir, var_tmp_dir,
- protect_home, protect_system);
+ if (root_image) {
+ dissect_image_flags |= DISSECT_IMAGE_REQUIRE_ROOT;
- /* Set mount slave mode */
- if (root_directory || n > 0)
- make_slave = true;
+ if (protect_system == PROTECT_SYSTEM_STRICT && strv_isempty(read_write_paths))
+ dissect_image_flags |= DISSECT_IMAGE_READ_ONLY;
- if (n > 0) {
- m = mounts = (BindMount *) alloca0(n * sizeof(BindMount));
- r = append_mounts(&m, read_write_paths, READWRITE);
+ r = loop_device_make_by_path(root_image,
+ dissect_image_flags & DISSECT_IMAGE_READ_ONLY ? O_RDONLY : O_RDWR,
+ &loop_device);
if (r < 0)
return r;
- r = append_mounts(&m, read_only_paths, READONLY);
+ r = root_hash_load(root_image, &root_hash, &root_hash_size);
if (r < 0)
return r;
- r = append_mounts(&m, inaccessible_paths, INACCESSIBLE);
+ r = dissect_image(loop_device->fd, root_hash, root_hash_size, dissect_image_flags, &dissected_image);
if (r < 0)
return r;
+ r = dissected_image_decrypt(dissected_image, NULL, root_hash, root_hash_size, dissect_image_flags, &decrypted_image);
+ if (r < 0)
+ return r;
+
+ if (!root_directory) {
+ /* Create a mount point for the image, if it's still missing. We use the same mount point for
+ * all images, which is safe, since they all live in their own namespaces after all, and hence
+ * won't see each other. */
+ root_directory = "/run/systemd/unit-root";
+ (void) mkdir(root_directory, 0700);
+ }
+ }
+
+ n_mounts = namespace_calculate_mounts(
+ ns_info,
+ read_write_paths,
+ read_only_paths,
+ inaccessible_paths,
+ bind_mounts, n_bind_mounts,
+ tmp_dir, var_tmp_dir,
+ protect_home, protect_system);
+
+ /* Set mount slave mode */
+ if (root_directory || n_mounts > 0)
+ make_slave = true;
+
+ if (n_mounts > 0) {
+ m = mounts = (MountEntry *) alloca0(n_mounts * sizeof(MountEntry));
+ r = append_access_mounts(&m, read_write_paths, READWRITE);
+ if (r < 0)
+ goto finish;
+
+ r = append_access_mounts(&m, read_only_paths, READONLY);
+ if (r < 0)
+ goto finish;
+
+ r = append_access_mounts(&m, inaccessible_paths, INACCESSIBLE);
+ if (r < 0)
+ goto finish;
+
+ r = append_bind_mounts(&m, bind_mounts, n_bind_mounts);
+ if (r < 0)
+ goto finish;
+
if (tmp_dir) {
- m->path = prefix_roota(root_directory, "/tmp");
- m->mode = PRIVATE_TMP;
- m++;
+ *(m++) = (MountEntry) {
+ .path_const = "/tmp",
+ .mode = PRIVATE_TMP,
+ };
}
if (var_tmp_dir) {
- m->path = prefix_roota(root_directory, "/var/tmp");
- m->mode = PRIVATE_VAR_TMP;
- m++;
+ *(m++) = (MountEntry) {
+ .path_const = "/var/tmp",
+ .mode = PRIVATE_VAR_TMP,
+ };
}
if (ns_info->private_dev) {
- m->path = prefix_roota(root_directory, "/dev");
- m->mode = PRIVATE_DEV;
- m++;
+ *(m++) = (MountEntry) {
+ .path_const = "/dev",
+ .mode = PRIVATE_DEV,
+ };
}
if (ns_info->protect_kernel_tunables) {
- r = append_protect_kernel_tunables(&m, root_directory);
+ r = append_static_mounts(&m, protect_kernel_tunables_table, ELEMENTSOF(protect_kernel_tunables_table), ns_info->ignore_protect_paths);
if (r < 0)
- return r;
+ goto finish;
}
if (ns_info->protect_kernel_modules) {
- r = append_protect_kernel_modules(&m, root_directory);
+ r = append_static_mounts(&m, protect_kernel_modules_table, ELEMENTSOF(protect_kernel_modules_table), ns_info->ignore_protect_paths);
if (r < 0)
- return r;
+ goto finish;
}
if (ns_info->protect_control_groups) {
- m->path = prefix_roota(root_directory, "/sys/fs/cgroup");
- m->mode = READONLY;
- m++;
+ *(m++) = (MountEntry) {
+ .path_const = "/sys/fs/cgroup",
+ .mode = READONLY,
+ };
}
- r = append_protect_home(&m, root_directory, protect_home);
+ r = append_protect_home(&m, protect_home, ns_info->ignore_protect_paths);
if (r < 0)
- return r;
+ goto finish;
- r = append_protect_system(&m, root_directory, protect_system);
+ r = append_protect_system(&m, protect_system, false);
if (r < 0)
- return r;
+ goto finish;
- assert(mounts + n == m);
+ if (namespace_info_mount_apivfs(ns_info)) {
+ r = append_static_mounts(&m, apivfs_table, ELEMENTSOF(apivfs_table), ns_info->ignore_protect_paths);
+ if (r < 0)
+ goto finish;
+ }
+
+ assert(mounts + n_mounts == m);
- /* Resolve symlinks manually first, as mount() will always follow them relative to the host's
- * root. Moreover we want to suppress duplicates based on the resolved paths. This of course is a bit
- * racy. */
- r = chase_all_symlinks(root_directory, mounts, &n);
+ /* Prepend the root directory where that's necessary */
+ r = prefix_where_needed(mounts, n_mounts, root_directory);
if (r < 0)
goto finish;
- qsort(mounts, n, sizeof(BindMount), mount_path_compare);
+ qsort(mounts, n_mounts, sizeof(MountEntry), mount_path_compare);
- drop_duplicates(mounts, &n);
- drop_outside_root(root_directory, mounts, &n);
- drop_inaccessible(mounts, &n);
- drop_nop(mounts, &n);
+ drop_duplicates(mounts, &n_mounts);
+ drop_outside_root(root_directory, mounts, &n_mounts);
+ drop_inaccessible(mounts, &n_mounts);
+ drop_nop(mounts, &n_mounts);
}
if (unshare(CLONE_NEWNS) < 0) {
@@ -830,9 +1044,21 @@ int setup_namespace(
}
}
- if (root_directory) {
+ if (root_image) {
+ r = dissected_image_mount(dissected_image, root_directory, dissect_image_flags);
+ if (r < 0)
+ goto finish;
+
+ r = decrypted_image_relinquish(decrypted_image);
+ if (r < 0)
+ goto finish;
+
+ loop_device_relinquish(loop_device);
+
+ } else if (root_directory) {
+
/* Turn directory into bind mount, if it isn't one yet */
- r = path_is_mount_point(root_directory, AT_SYMLINK_FOLLOW);
+ r = path_is_mount_point(root_directory, NULL, AT_SYMLINK_FOLLOW);
if (r < 0)
goto finish;
if (r == 0) {
@@ -843,25 +1069,25 @@ int setup_namespace(
}
}
- if (n > 0) {
+ if (n_mounts > 0) {
char **blacklist;
unsigned j;
/* First round, add in all special mounts we need */
- for (m = mounts; m < mounts + n; ++m) {
- r = apply_mount(m, tmp_dir, var_tmp_dir);
+ for (m = mounts; m < mounts + n_mounts; ++m) {
+ r = apply_mount(root_directory, m, tmp_dir, var_tmp_dir);
if (r < 0)
goto finish;
}
/* Create a blacklist we can pass to bind_mount_recursive() */
- blacklist = newa(char*, n+1);
- for (j = 0; j < n; j++)
- blacklist[j] = (char*) mounts[j].path;
+ blacklist = newa(char*, n_mounts+1);
+ for (j = 0; j < n_mounts; j++)
+ blacklist[j] = (char*) mount_entry_path(mounts+j);
blacklist[j] = NULL;
/* Second round, flip the ro bits if necessary. */
- for (m = mounts; m < mounts + n; ++m) {
+ for (m = mounts; m < mounts + n_mounts; ++m) {
r = make_read_only(m, blacklist);
if (r < 0)
goto finish;
@@ -886,12 +1112,59 @@ int setup_namespace(
r = 0;
finish:
- for (m = mounts; m < mounts + n; m++)
- free(m->chased);
+ for (m = mounts; m < mounts + n_mounts; m++)
+ mount_entry_done(m);
return r;
}
+void bind_mount_free_many(BindMount *b, unsigned n) {
+ unsigned i;
+
+ assert(b || n == 0);
+
+ for (i = 0; i < n; i++) {
+ free(b[i].source);
+ free(b[i].destination);
+ }
+
+ free(b);
+}
+
+int bind_mount_add(BindMount **b, unsigned *n, const BindMount *item) {
+ _cleanup_free_ char *s = NULL, *d = NULL;
+ BindMount *c;
+
+ assert(b);
+ assert(n);
+ assert(item);
+
+ s = strdup(item->source);
+ if (!s)
+ return -ENOMEM;
+
+ d = strdup(item->destination);
+ if (!d)
+ return -ENOMEM;
+
+ c = realloc_multiply(*b, sizeof(BindMount), *n + 1);
+ if (!c)
+ return -ENOMEM;
+
+ *b = c;
+
+ c[(*n) ++] = (BindMount) {
+ .source = s,
+ .destination = d,
+ .read_only = item->read_only,
+ .recursive = item->recursive,
+ .ignore_enoent = item->ignore_enoent,
+ };
+
+ s = d = NULL;
+ return 0;
+}
+
static int setup_one_tmp_dir(const char *id, const char *prefix, char **path) {
_cleanup_free_ char *x = NULL;
char bid[SD_ID128_STRING_MAX];
@@ -909,7 +1182,7 @@ static int setup_one_tmp_dir(const char *id, const char *prefix, char **path) {
if (r < 0)
return r;
- x = strjoin(prefix, "/systemd-private-", sd_id128_to_string(boot_id, bid), "-", id, "-XXXXXX", NULL);
+ x = strjoin(prefix, "/systemd-private-", sd_id128_to_string(boot_id, bid), "-", id, "-XXXXXX");
if (!x)
return -ENOMEM;
diff --git a/src/core/namespace.h b/src/core/namespace.h
index 6310638e9a..f54954bd86 100644
--- a/src/core/namespace.h
+++ b/src/core/namespace.h
@@ -21,9 +21,11 @@
***/
typedef struct NameSpaceInfo NameSpaceInfo;
+typedef struct BindMount BindMount;
#include <stdbool.h>
+#include "dissect-image.h"
#include "macro.h"
typedef enum ProtectHome {
@@ -44,26 +46,42 @@ typedef enum ProtectSystem {
} ProtectSystem;
struct NameSpaceInfo {
+ bool ignore_protect_paths:1;
bool private_dev:1;
bool protect_control_groups:1;
bool protect_kernel_tunables:1;
bool protect_kernel_modules:1;
+ bool mount_apivfs:1;
};
-int setup_namespace(const char *chroot,
- const NameSpaceInfo *ns_info,
- char **read_write_paths,
- char **read_only_paths,
- char **inaccessible_paths,
- const char *tmp_dir,
- const char *var_tmp_dir,
- ProtectHome protect_home,
- ProtectSystem protect_system,
- unsigned long mount_flags);
-
-int setup_tmp_dirs(const char *id,
- char **tmp_dir,
- char **var_tmp_dir);
+struct BindMount {
+ char *source;
+ char *destination;
+ bool read_only:1;
+ bool recursive:1;
+ bool ignore_enoent:1;
+};
+
+int setup_namespace(
+ const char *root_directory,
+ const char *root_image,
+ const NameSpaceInfo *ns_info,
+ char **read_write_paths,
+ char **read_only_paths,
+ char **inaccessible_paths,
+ const BindMount *bind_mounts,
+ unsigned n_bind_mounts,
+ const char *tmp_dir,
+ const char *var_tmp_dir,
+ ProtectHome protect_home,
+ ProtectSystem protect_system,
+ unsigned long mount_flags,
+ DissectImageFlags dissected_image_flags);
+
+int setup_tmp_dirs(
+ const char *id,
+ char **tmp_dir,
+ char **var_tmp_dir);
int setup_netns(int netns_storage_socket[2]);
@@ -72,3 +90,6 @@ ProtectHome protect_home_from_string(const char *s) _pure_;
const char* protect_system_to_string(ProtectSystem p) _const_;
ProtectSystem protect_system_from_string(const char *s) _pure_;
+
+void bind_mount_free_many(BindMount *b, unsigned n);
+int bind_mount_add(BindMount **b, unsigned *n, const BindMount *item);
diff --git a/src/core/org.freedesktop.systemd1.conf b/src/core/org.freedesktop.systemd1.conf
index a61677e645..e824a2233c 100644
--- a/src/core/org.freedesktop.systemd1.conf
+++ b/src/core/org.freedesktop.systemd1.conf
@@ -66,6 +66,14 @@
<allow send_destination="org.freedesktop.systemd1"
send_interface="org.freedesktop.systemd1.Manager"
+ send_member="GetJobAfter"/>
+
+ <allow send_destination="org.freedesktop.systemd1"
+ send_interface="org.freedesktop.systemd1.Manager"
+ send_member="GetJobBefore"/>
+
+ <allow send_destination="org.freedesktop.systemd1"
+ send_interface="org.freedesktop.systemd1.Manager"
send_member="ListUnits"/>
<allow send_destination="org.freedesktop.systemd1"
@@ -250,6 +258,14 @@
send_interface="org.freedesktop.systemd1.Job"
send_member="Cancel"/>
+ <allow send_destination="org.freedesktop.systemd1"
+ send_interface="org.freedesktop.systemd1.Job"
+ send_member="GetAfter"/>
+
+ <allow send_destination="org.freedesktop.systemd1"
+ send_interface="org.freedesktop.systemd1.Job"
+ send_member="GetBefore"/>
+
<allow receive_sender="org.freedesktop.systemd1"/>
</policy>
diff --git a/src/core/scope.c b/src/core/scope.c
index d6e1f8e392..a1d5c1cfd5 100644
--- a/src/core/scope.c
+++ b/src/core/scope.c
@@ -273,7 +273,9 @@ static void scope_enter_signal(Scope *s, ScopeState state, ScopeResult f) {
if (state == SCOPE_STOP_SIGTERM)
skip_signal = bus_scope_send_request_stop(s) > 0;
- if (!skip_signal) {
+ if (skip_signal)
+ r = 1; /* wait */
+ else {
r = unit_kill_context(
UNIT(s),
&s->kill_context,
@@ -283,8 +285,7 @@ static void scope_enter_signal(Scope *s, ScopeState state, ScopeResult f) {
-1, -1, false);
if (r < 0)
goto fail;
- } else
- r = 1;
+ }
if (r > 0) {
r = scope_arm_timer(s, usec_add(now(CLOCK_MONOTONIC), s->timeout_stop_usec));
@@ -474,7 +475,7 @@ static void scope_sigchld_event(Unit *u, pid_t pid, int code, int status) {
/* If the PID set is empty now, then let's finish this off
(On unified we use proper notifications) */
- if (cg_unified(SYSTEMD_CGROUP_CONTROLLER) <= 0 && set_isempty(u->pids))
+ if (cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) == 0 && set_isempty(u->pids))
scope_notify_cgroup_empty_event(u);
}
diff --git a/src/core/service.c b/src/core/service.c
index a7274a758f..874f2be931 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -33,7 +33,7 @@
#include "exit-status.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "fs-util.h"
#include "load-dropin.h"
#include "load-fragment.h"
@@ -49,7 +49,6 @@
#include "string-util.h"
#include "strv.h"
#include "unit-name.h"
-#include "unit-printf.h"
#include "unit.h"
#include "utf8.h"
#include "util.h"
@@ -850,11 +849,8 @@ static int service_load_pid_file(Service *s, bool may_warn) {
return r;
r = unit_watch_pid(UNIT(s), pid);
- if (r < 0) {
- /* FIXME: we need to do something here */
- log_unit_warning_errno(UNIT(s), r, "Failed to watch PID "PID_FMT" for service: %m", pid);
- return r;
- }
+ if (r < 0) /* FIXME: we need to do something here */
+ return log_unit_warning_errno(UNIT(s), r, "Failed to watch PID "PID_FMT" for service: %m", pid);
return 0;
}
@@ -1179,6 +1175,25 @@ static int service_collect_fds(Service *s, int **fds, char ***fd_names) {
return rn_fds;
}
+static bool service_exec_needs_notify_socket(Service *s, ExecFlags flags) {
+ assert(s);
+
+ /* Notifications are accepted depending on the process and
+ * the access setting of the service:
+ * process: \ access: NONE MAIN EXEC ALL
+ * main no yes yes yes
+ * control no no yes yes
+ * other (forked) no no no yes */
+
+ if (flags & EXEC_IS_CONTROL)
+ /* A control process */
+ return IN_SET(s->notify_access, NOTIFY_EXEC, NOTIFY_ALL);
+
+ /* We only spawn main processes and control processes, so any
+ * process that is not a control process is a main process */
+ return s->notify_access != NOTIFY_NONE;
+}
+
static int service_spawn(
Service *s,
ExecCommand *c,
@@ -1186,7 +1201,7 @@ static int service_spawn(
ExecFlags flags,
pid_t *_pid) {
- _cleanup_strv_free_ char **argv = NULL, **final_env = NULL, **our_env = NULL, **fd_names = NULL;
+ _cleanup_strv_free_ char **final_env = NULL, **our_env = NULL, **fd_names = NULL;
_cleanup_free_ int *fds = NULL;
unsigned n_fds = 0, n_env = 0;
const char *path;
@@ -1244,15 +1259,11 @@ static int service_spawn(
if (r < 0)
return r;
- r = unit_full_printf_strv(UNIT(s), c->argv, &argv);
- if (r < 0)
- return r;
-
our_env = new0(char*, 9);
if (!our_env)
return -ENOMEM;
- if ((flags & EXEC_IS_CONTROL) ? s->notify_access == NOTIFY_ALL : s->notify_access != NOTIFY_NONE)
+ if (service_exec_needs_notify_socket(s, flags))
if (asprintf(our_env + n_env++, "NOTIFY_SOCKET=%s", UNIT(s)->manager->notify_socket) < 0)
return -ENOMEM;
@@ -1278,10 +1289,10 @@ static int service_spawn(
return r;
}
- if (r == 0 && IN_SET(sa.sa.sa_family, AF_INET, AF_INET6)) {
+ if (r == 0 && IN_SET(sa.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK)) {
_cleanup_free_ char *addr = NULL;
char *t;
- int port;
+ unsigned port;
r = sockaddr_pretty(&sa.sa, salen, true, false, &addr);
if (r < 0)
@@ -1292,9 +1303,9 @@ static int service_spawn(
return -ENOMEM;
our_env[n_env++] = t;
- port = sockaddr_port(&sa.sa);
- if (port < 0)
- return port;
+ r = sockaddr_port(&sa.sa, &port);
+ if (r < 0)
+ return r;
if (asprintf(&t, "REMOTE_PORT=%u", port) < 0)
return -ENOMEM;
@@ -1330,12 +1341,12 @@ static int service_spawn(
} else
path = UNIT(s)->cgroup_path;
- exec_params.argv = argv;
+ exec_params.argv = c->argv;
exec_params.environment = final_env;
exec_params.fds = fds;
exec_params.fd_names = fd_names;
exec_params.n_fds = n_fds;
- exec_params.flags |= UNIT(s)->manager->confirm_spawn ? EXEC_CONFIRM_SPAWN : 0;
+ exec_params.confirm_spawn = manager_get_confirm_spawn(UNIT(s)->manager);
exec_params.cgroup_supported = UNIT(s)->manager->cgroup_supported;
exec_params.cgroup_path = path;
exec_params.cgroup_delegate = s->cgroup_context.delegate;
@@ -1359,8 +1370,7 @@ static int service_spawn(
return r;
r = unit_watch_pid(UNIT(s), pid);
- if (r < 0)
- /* FIXME: we need to do something here */
+ if (r < 0) /* FIXME: we need to do something here */
return r;
*_pid = pid;
@@ -1694,7 +1704,9 @@ static void service_enter_running(Service *s, ServiceResult f) {
service_arm_timer(s, usec_add(UNIT(s)->active_enter_timestamp.monotonic, s->runtime_max_usec));
}
- } else if (s->remain_after_exit)
+ } else if (f != SERVICE_SUCCESS)
+ service_enter_signal(s, SERVICE_STOP_SIGTERM, f);
+ else if (s->remain_after_exit)
service_set_state(s, SERVICE_EXITED);
else
service_enter_stop(s, SERVICE_SUCCESS);
@@ -1830,7 +1842,7 @@ static void service_enter_start(Service *s) {
fail:
log_unit_warning_errno(UNIT(s), r, "Failed to run 'start' task: %m");
- service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES);
+ service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES);
}
static void service_enter_start_pre(Service *s) {
@@ -1976,9 +1988,7 @@ static void service_run_next_control(Service *s) {
fail:
log_unit_warning_errno(UNIT(s), r, "Failed to run next control task: %m");
- if (s->state == SERVICE_START_PRE)
- service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES);
- else if (s->state == SERVICE_STOP)
+ if (IN_SET(s->state, SERVICE_START_PRE, SERVICE_STOP))
service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES);
else if (s->state == SERVICE_STOP_POST)
service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true);
@@ -2577,17 +2587,24 @@ static void service_notify_cgroup_empty_event(Unit *u) {
* SIGCHLD for. */
case SERVICE_START:
+ if (s->type == SERVICE_NOTIFY) {
+ /* No chance of getting a ready notification anymore */
+ service_enter_stop_post(s, SERVICE_FAILURE_PROTOCOL);
+ break;
+ }
+
+ /* Fall through */
+
case SERVICE_START_POST:
- /* If we were hoping for the daemon to write its PID file,
- * we can give up now. */
if (s->pid_file_pathspec) {
+ /* Give up hoping for the daemon to write its PID file */
log_unit_warning(u, "Daemon never wrote its PID file. Failing.");
service_unwatch_pid_file(s);
if (s->state == SERVICE_START)
- service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES);
+ service_enter_stop_post(s, SERVICE_FAILURE_PROTOCOL);
else
- service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
+ service_enter_stop(s, SERVICE_FAILURE_PROTOCOL);
}
break;
@@ -2719,7 +2736,17 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
if (f == SERVICE_SUCCESS)
service_enter_start_post(s);
else
- service_enter_signal(s, SERVICE_FINAL_SIGTERM, f);
+ service_enter_signal(s, SERVICE_STOP_SIGTERM, f);
+ break;
+ } else if (s->type == SERVICE_NOTIFY) {
+ /* Only enter running through a notification, so that the
+ * SERVICE_START state signifies that no ready notification
+ * has been received */
+ if (f != SERVICE_SUCCESS)
+ service_enter_signal(s, SERVICE_STOP_SIGTERM, f);
+ else if (!s->remain_after_exit)
+ /* The service has never been active */
+ service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_PROTOCOL);
break;
}
@@ -2799,7 +2826,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
if (f == SERVICE_SUCCESS)
service_enter_start(s);
else
- service_enter_signal(s, SERVICE_FINAL_SIGTERM, f);
+ service_enter_signal(s, SERVICE_STOP_SIGTERM, f);
break;
case SERVICE_START:
@@ -2808,7 +2835,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
break;
if (f != SERVICE_SUCCESS) {
- service_enter_signal(s, SERVICE_FINAL_SIGTERM, f);
+ service_enter_signal(s, SERVICE_STOP_SIGTERM, f);
break;
}
@@ -2825,7 +2852,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
if (!has_start_post && r < 0) {
r = service_demand_pid_file(s);
if (r < 0 || !cgroup_good(s))
- service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES);
+ service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_PROTOCOL);
break;
}
} else
@@ -2847,7 +2874,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
if (r < 0) {
r = service_demand_pid_file(s);
if (r < 0 || !cgroup_good(s))
- service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
+ service_enter_stop(s, SERVICE_FAILURE_PROTOCOL);
break;
}
} else
@@ -2906,7 +2933,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
/* If the PID set is empty now, then let's finish this off
(On unified we use proper notifications) */
- if (cg_unified(SYSTEMD_CGROUP_CONTROLLER) <= 0 && set_isempty(u->pids))
+ if (cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) == 0 && set_isempty(u->pids))
service_notify_cgroup_empty_event(u);
}
@@ -2921,7 +2948,7 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us
case SERVICE_START_PRE:
case SERVICE_START:
log_unit_warning(UNIT(s), "%s operation timed out. Terminating.", s->state == SERVICE_START ? "Start" : "Start-pre");
- service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_TIMEOUT);
+ service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_TIMEOUT);
break;
case SERVICE_START_POST:
@@ -3042,7 +3069,18 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags, FDSet *fds)
if (s->main_pid != 0)
log_unit_warning(u, "Got notification message from PID "PID_FMT", but reception only permitted for main PID "PID_FMT, pid, s->main_pid);
else
- log_unit_debug(u, "Got notification message from PID "PID_FMT", but reception only permitted for main PID which is currently not known", pid);
+ log_unit_warning(u, "Got notification message from PID "PID_FMT", but reception only permitted for main PID which is currently not known", pid);
+ return;
+ } else if (s->notify_access == NOTIFY_EXEC && pid != s->main_pid && pid != s->control_pid) {
+ if (s->main_pid != 0 && s->control_pid != 0)
+ log_unit_warning(u, "Got notification message from PID "PID_FMT", but reception only permitted for main PID "PID_FMT" and control PID "PID_FMT,
+ pid, s->main_pid, s->control_pid);
+ else if (s->main_pid != 0)
+ log_unit_warning(u, "Got notification message from PID "PID_FMT", but reception only permitted for main PID "PID_FMT, pid, s->main_pid);
+ else if (s->control_pid != 0)
+ log_unit_warning(u, "Got notification message from PID "PID_FMT", but reception only permitted for control PID "PID_FMT, pid, s->control_pid);
+ else
+ log_unit_warning(u, "Got notification message from PID "PID_FMT", but reception only permitted for main PID and control PID which are currently not known", pid);
return;
} else
log_unit_debug(u, "Got notification message from PID "PID_FMT" (%s)", pid, isempty(cc) ? "n/a" : cc);
@@ -3052,6 +3090,10 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags, FDSet *fds)
if (e && IN_SET(s->state, SERVICE_START, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD)) {
if (parse_pid(e, &pid) < 0)
log_unit_warning(u, "Failed to parse MAINPID= field in notification message: %s", e);
+ else if (pid == s->control_pid)
+ log_unit_warning(u, "A control process cannot also be the main process");
+ else if (pid == getpid() || pid == 1)
+ log_unit_warning(u, "Service manager can't be main process, ignoring sd_notify() MAINPID= field");
else {
service_set_main_pid(s, pid);
unit_watch_pid(UNIT(s), pid);
@@ -3241,7 +3283,7 @@ static void service_bus_name_owner_change(
if (r >= 0)
r = sd_bus_creds_get_pid(creds, &pid);
if (r >= 0) {
- log_unit_debug(u, "D-Bus name %s is now owned by process %u", name, (unsigned) pid);
+ log_unit_debug(u, "D-Bus name %s is now owned by process " PID_FMT, name, pid);
service_set_main_pid(s, pid);
unit_watch_pid(UNIT(s), pid);
@@ -3273,7 +3315,7 @@ int service_set_socket_fd(Service *s, int fd, Socket *sock, bool selinux_context
if (UNIT(s)->description) {
_cleanup_free_ char *a;
- a = strjoin(UNIT(s)->description, " (", peer, ")", NULL);
+ a = strjoin(UNIT(s)->description, " (", peer, ")");
if (!a)
return -ENOMEM;
@@ -3367,6 +3409,7 @@ DEFINE_STRING_TABLE_LOOKUP(service_exec_command, ServiceExecCommand);
static const char* const notify_access_table[_NOTIFY_ACCESS_MAX] = {
[NOTIFY_NONE] = "none",
[NOTIFY_MAIN] = "main",
+ [NOTIFY_EXEC] = "exec",
[NOTIFY_ALL] = "all"
};
@@ -3384,6 +3427,7 @@ DEFINE_STRING_TABLE_LOOKUP(notify_state, NotifyState);
static const char* const service_result_table[_SERVICE_RESULT_MAX] = {
[SERVICE_SUCCESS] = "success",
[SERVICE_FAILURE_RESOURCES] = "resources",
+ [SERVICE_FAILURE_PROTOCOL] = "protocol",
[SERVICE_FAILURE_TIMEOUT] = "timeout",
[SERVICE_FAILURE_EXIT_CODE] = "exit-code",
[SERVICE_FAILURE_SIGNAL] = "signal",
diff --git a/src/core/service.h b/src/core/service.h
index 2869144fcb..ff9cfaeb88 100644
--- a/src/core/service.h
+++ b/src/core/service.h
@@ -65,6 +65,7 @@ typedef enum NotifyAccess {
NOTIFY_NONE,
NOTIFY_ALL,
NOTIFY_MAIN,
+ NOTIFY_EXEC,
_NOTIFY_ACCESS_MAX,
_NOTIFY_ACCESS_INVALID = -1
} NotifyAccess;
@@ -78,9 +79,12 @@ typedef enum NotifyState {
_NOTIFY_STATE_INVALID = -1
} NotifyState;
+/* The values of this enum are referenced in man/systemd.exec.xml and src/shared/bus-unit-util.c.
+ * Update those sources for each change to this enum. */
typedef enum ServiceResult {
SERVICE_SUCCESS,
SERVICE_FAILURE_RESOURCES, /* a bit of a misnomer, just our catch-all error for errnos we didn't expect */
+ SERVICE_FAILURE_PROTOCOL,
SERVICE_FAILURE_TIMEOUT,
SERVICE_FAILURE_EXIT_CODE,
SERVICE_FAILURE_SIGNAL,
diff --git a/src/core/shutdown.c b/src/core/shutdown.c
index a795d875bb..a7d5e57936 100644
--- a/src/core/shutdown.c
+++ b/src/core/shutdown.c
@@ -32,6 +32,7 @@
#include "alloc-util.h"
#include "cgroup-util.h"
#include "def.h"
+#include "exec-util.h"
#include "fileio.h"
#include "killall.h"
#include "log.h"
@@ -321,7 +322,7 @@ int main(int argc, char *argv[]) {
arguments[0] = NULL;
arguments[1] = arg_verb;
arguments[2] = NULL;
- execute_directories(dirs, DEFAULT_TIMEOUT_USEC, arguments);
+ execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, arguments);
if (!in_container && !in_initrd() &&
access("/run/initramfs/shutdown", X_OK) == 0) {
@@ -402,7 +403,7 @@ int main(int argc, char *argv[]) {
_cleanup_free_ char *param = NULL;
r = read_one_line_file("/run/systemd/reboot-param", &param);
- if (r < 0)
+ if (r < 0 && r != -ENOENT)
log_warning_errno(r, "Failed to read reboot parameter file: %m");
if (!isempty(param)) {
diff --git a/src/core/socket.c b/src/core/socket.c
index 9a2c3a7df7..c4da227e09 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -36,7 +36,7 @@
#include "def.h"
#include "exit-status.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "io-util.h"
#include "label.h"
#include "log.h"
@@ -54,7 +54,6 @@
#include "string-util.h"
#include "strv.h"
#include "unit-name.h"
-#include "unit-printf.h"
#include "unit.h"
#include "user-util.h"
#include "in-addr-util.h"
@@ -64,6 +63,7 @@ struct SocketPeer {
Socket *socket;
union sockaddr_union peer;
+ socklen_t peer_salen;
};
static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
@@ -424,8 +424,7 @@ static const char *socket_find_symlink_target(Socket *s) {
break;
case SOCKET_SOCKET:
- if (p->address.sockaddr.un.sun_path[0] != 0)
- f = p->address.sockaddr.un.sun_path;
+ f = socket_address_get_path(&p->address);
break;
default:
@@ -450,7 +449,7 @@ static int socket_verify(Socket *s) {
return 0;
if (!s->ports) {
- log_unit_error(UNIT(s), "Unit lacks Listen setting. Refusing.");
+ log_unit_error(UNIT(s), "Unit has no Listen setting (ListenStream=, ListenDatagram=, ListenFIFO=, ...). Refusing.");
return -EINVAL;
}
@@ -486,12 +485,15 @@ static void peer_address_hash_func(const void *p, struct siphash *state) {
const SocketPeer *s = p;
assert(s);
- assert(IN_SET(s->peer.sa.sa_family, AF_INET, AF_INET6));
if (s->peer.sa.sa_family == AF_INET)
siphash24_compress(&s->peer.in.sin_addr, sizeof(s->peer.in.sin_addr), state);
- else
+ else if (s->peer.sa.sa_family == AF_INET6)
siphash24_compress(&s->peer.in6.sin6_addr, sizeof(s->peer.in6.sin6_addr), state);
+ else if (s->peer.sa.sa_family == AF_VSOCK)
+ siphash24_compress(&s->peer.vm.svm_cid, sizeof(s->peer.vm.svm_cid), state);
+ else
+ assert_not_reached("Unknown address family.");
}
static int peer_address_compare_func(const void *a, const void *b) {
@@ -507,6 +509,12 @@ static int peer_address_compare_func(const void *a, const void *b) {
return memcmp(&x->peer.in.sin_addr, &y->peer.in.sin_addr, sizeof(x->peer.in.sin_addr));
case AF_INET6:
return memcmp(&x->peer.in6.sin6_addr, &y->peer.in6.sin6_addr, sizeof(x->peer.in6.sin6_addr));
+ case AF_VSOCK:
+ if (x->peer.vm.svm_cid < y->peer.vm.svm_cid)
+ return -1;
+ if (x->peer.vm.svm_cid > y->peer.vm.svm_cid)
+ return 1;
+ return 0;
}
assert_not_reached("Black sheep in the family!");
}
@@ -593,7 +601,7 @@ int socket_acquire_peer(Socket *s, int fd, SocketPeer **p) {
if (r < 0)
return log_error_errno(errno, "getpeername failed: %m");
- if (!IN_SET(sa.peer.sa.sa_family, AF_INET, AF_INET6)) {
+ if (!IN_SET(sa.peer.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK)) {
*p = NULL;
return 0;
}
@@ -609,6 +617,7 @@ int socket_acquire_peer(Socket *s, int fd, SocketPeer **p) {
return log_oom();
remote->peer = sa.peer;
+ remote->peer_salen = salen;
r = set_put(s->peers_by_address, remote);
if (r < 0)
@@ -939,6 +948,16 @@ static int instance_from_socket(int fd, unsigned nr, char **instance) {
break;
}
+ case AF_VSOCK:
+ if (asprintf(&r,
+ "%u-%u:%u-%u:%u",
+ nr,
+ local.vm.svm_cid, local.vm.svm_port,
+ remote.vm.svm_cid, remote.vm.svm_port) < 0)
+ return -ENOMEM;
+
+ break;
+
default:
assert_not_reached("Unhandled socket type.");
}
@@ -1241,7 +1260,7 @@ static int usbffs_address_create(const char *path) {
if (fstat(fd, &st) < 0)
return -errno;
- /* Check whether this is a regular file (ffs endpoint)*/
+ /* Check whether this is a regular file (ffs endpoint) */
if (!S_ISREG(st.st_mode))
return -EEXIST;
@@ -1321,11 +1340,11 @@ static int usbffs_write_descs(int fd, Service *s) {
if (!s->usb_function_descriptors || !s->usb_function_strings)
return -EINVAL;
- r = copy_file_fd(s->usb_function_descriptors, fd, false);
+ r = copy_file_fd(s->usb_function_descriptors, fd, 0);
if (r < 0)
return r;
- return copy_file_fd(s->usb_function_strings, fd, false);
+ return copy_file_fd(s->usb_function_strings, fd, 0);
}
static int usbffs_select_ep(const struct dirent *d) {
@@ -1740,7 +1759,6 @@ static int socket_coldplug(Unit *u) {
}
static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
- _cleanup_free_ char **argv = NULL;
pid_t pid;
int r;
ExecParameters exec_params = {
@@ -1772,13 +1790,9 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
if (r < 0)
return r;
- r = unit_full_printf_strv(UNIT(s), c->argv, &argv);
- if (r < 0)
- return r;
-
- exec_params.argv = argv;
+ exec_params.argv = c->argv;
exec_params.environment = UNIT(s)->manager->environment;
- exec_params.flags |= UNIT(s)->manager->confirm_spawn ? EXEC_CONFIRM_SPAWN : 0;
+ exec_params.confirm_spawn = manager_get_confirm_spawn(UNIT(s)->manager);
exec_params.cgroup_supported = UNIT(s)->manager->cgroup_supported;
exec_params.cgroup_path = UNIT(s)->cgroup_path;
exec_params.cgroup_delegate = s->cgroup_context.delegate;
@@ -2196,7 +2210,7 @@ static void socket_enter_running(Socket *s, int cfd) {
} else if (r > 0 && p->n_ref > s->max_connections_per_source) {
_cleanup_free_ char *t = NULL;
- sockaddr_pretty(&p->peer.sa, FAMILY_ADDRESS_SIZE(p->peer.sa.sa_family), true, false, &t);
+ (void) sockaddr_pretty(&p->peer.sa, p->peer_salen, true, false, &t);
log_unit_warning(UNIT(s),
"Too many incoming connections (%u) from source %s, dropping connection.",
diff --git a/src/core/swap.c b/src/core/swap.c
index 2228a254bb..e9468e105c 100644
--- a/src/core/swap.c
+++ b/src/core/swap.c
@@ -29,7 +29,7 @@
#include "escape.h"
#include "exit-status.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "fstab-util.h"
#include "parse-util.h"
#include "path-util.h"
@@ -420,7 +420,7 @@ static int swap_setup_unit(
fail:
log_unit_warning_errno(u, r, "Failed to load swap unit: %m");
- if (delete && u)
+ if (delete)
unit_free(u);
return r;
@@ -636,7 +636,7 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
goto fail;
exec_params.environment = UNIT(s)->manager->environment;
- exec_params.flags |= UNIT(s)->manager->confirm_spawn ? EXEC_CONFIRM_SPAWN : 0;
+ exec_params.confirm_spawn = manager_get_confirm_spawn(UNIT(s)->manager);
exec_params.cgroup_supported = UNIT(s)->manager->cgroup_supported;
exec_params.cgroup_path = UNIT(s)->cgroup_path;
exec_params.cgroup_delegate = s->cgroup_context.delegate;
diff --git a/src/core/target.c b/src/core/target.c
index 765c1f3fa4..ff0d764fb5 100644
--- a/src/core/target.c
+++ b/src/core/target.c
@@ -75,8 +75,11 @@ static int target_add_default_dependencies(Target *t) {
return r;
}
+ if (unit_has_name(UNIT(t), SPECIAL_SHUTDOWN_TARGET))
+ return 0;
+
/* Make sure targets are unloaded on shutdown */
- return unit_add_dependency_by_name(UNIT(t), UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
+ return unit_add_two_dependencies_by_name(UNIT(t), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
}
static int target_load(Unit *u) {
diff --git a/src/core/timer.c b/src/core/timer.c
index 9682ac1ae4..af67b7591a 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -147,7 +147,7 @@ static int timer_setup_persistent(Timer *t) {
e = getenv("XDG_DATA_HOME");
if (e)
- t->stamp_path = strjoin(e, "/systemd/timers/stamp-", UNIT(t)->id, NULL);
+ t->stamp_path = strjoin(e, "/systemd/timers/stamp-", UNIT(t)->id);
else {
_cleanup_free_ char *h = NULL;
@@ -156,7 +156,7 @@ static int timer_setup_persistent(Timer *t) {
if (r < 0)
return log_unit_error_errno(UNIT(t), r, "Failed to determine home directory: %m");
- t->stamp_path = strjoin(h, "/.local/share/systemd/timers/stamp-", UNIT(t)->id, NULL);
+ t->stamp_path = strjoin(h, "/.local/share/systemd/timers/stamp-", UNIT(t)->id);
}
}
@@ -232,7 +232,7 @@ static void timer_dump(Unit *u, FILE *f, const char *prefix) {
if (v->base == TIMER_CALENDAR) {
_cleanup_free_ char *p = NULL;
- calendar_spec_to_string(v->calendar_spec, &p);
+ (void) calendar_spec_to_string(v->calendar_spec, &p);
fprintf(f,
"%s%s: %s\n",
@@ -350,7 +350,7 @@ static void add_random(Timer *t, usec_t *v) {
else
*v += add;
- log_unit_info(UNIT(t), "Adding %s random time.", format_timespan(s, sizeof(s), add, 0));
+ log_unit_debug(UNIT(t), "Adding %s random time.", format_timespan(s, sizeof(s), add, 0));
}
static void timer_enter_waiting(Timer *t, bool initial) {
diff --git a/src/core/transaction.c b/src/core/transaction.c
index e22e3b30c2..b6d1062414 100644
--- a/src/core/transaction.c
+++ b/src/core/transaction.c
@@ -907,7 +907,10 @@ int transaction_add_job_and_dependencies(
SET_FOREACH(dep, following, i) {
r = transaction_add_job_and_dependencies(tr, type, dep, ret, false, false, false, ignore_order, e);
if (r < 0) {
- log_unit_warning(dep, "Cannot add dependency job for, ignoring: %s", bus_error_message(e, r));
+ log_unit_full(dep,
+ r == -ERFKILL ? LOG_INFO : LOG_WARNING,
+ r, "Cannot add dependency job, ignoring: %s",
+ bus_error_message(e, r));
sd_bus_error_free(e);
}
}
diff --git a/src/core/triggers.systemd.in b/src/core/triggers.systemd.in
index 0d8c303136..f8c8cbc5f9 100644
--- a/src/core/triggers.systemd.in
+++ b/src/core/triggers.systemd.in
@@ -27,11 +27,13 @@
-- installed, because other cases are covered by the *un scriptlets,
-- so sometimes we will reload needlessly.
-pid = posix.fork()
-if pid == 0 then
- assert(posix.exec("%{_bindir}/systemctl", "daemon-reload"))
-elseif pid > 0 then
- posix.wait(pid)
+if posix.access("/run/systemd/system") then
+ pid = posix.fork()
+ if pid == 0 then
+ assert(posix.exec("%{_bindir}/systemctl", "daemon-reload"))
+ elseif pid > 0 then
+ posix.wait(pid)
+ end
end
%transfiletriggerun -p <lua> -- @systemunitdir@ /etc/systemd/system
@@ -48,10 +50,12 @@ end
-- file in %transfiletriggerun and execute the daemon-reload in
-- the first %filetriggerpostun.
-posix.mkdir("%{_localstatedir}/lib")
-posix.mkdir("%{_localstatedir}/lib/rpm-state")
-posix.mkdir("%{_localstatedir}/lib/rpm-state/systemd")
-io.open("%{_localstatedir}/lib/rpm-state/systemd/needs-reload", "w")
+if posix.access("/run/systemd/system") then
+ posix.mkdir("%{_localstatedir}/lib")
+ posix.mkdir("%{_localstatedir}/lib/rpm-state")
+ posix.mkdir("%{_localstatedir}/lib/rpm-state/systemd")
+ io.open("%{_localstatedir}/lib/rpm-state/systemd/needs-reload", "w")
+end
%filetriggerpostun -P 1000100 -p <lua> -- @systemunitdir@ /etc/systemd/system
if posix.access("%{_localstatedir}/lib/rpm-state/systemd/needs-reload") then
diff --git a/src/core/umount.c b/src/core/umount.c
index 1e5459ed80..77b5bd9556 100644
--- a/src/core/umount.c
+++ b/src/core/umount.c
@@ -344,24 +344,37 @@ static int delete_loopback(const char *device) {
}
static int delete_dm(dev_t devnum) {
- _cleanup_close_ int fd = -1;
- int r;
+
struct dm_ioctl dm = {
- .version = {DM_VERSION_MAJOR,
- DM_VERSION_MINOR,
- DM_VERSION_PATCHLEVEL},
+ .version = {
+ DM_VERSION_MAJOR,
+ DM_VERSION_MINOR,
+ DM_VERSION_PATCHLEVEL
+ },
.data_size = sizeof(dm),
.dev = devnum,
};
+ _cleanup_close_ int fd = -1;
+
assert(major(devnum) != 0);
fd = open("/dev/mapper/control", O_RDWR|O_CLOEXEC);
if (fd < 0)
return -errno;
- r = ioctl(fd, DM_DEV_REMOVE, &dm);
- return r >= 0 ? 0 : -errno;
+ if (ioctl(fd, DM_DEV_REMOVE, &dm) < 0)
+ return -errno;
+
+ return 0;
+}
+
+static bool nonunmountable_path(const char *path) {
+ return path_equal(path, "/")
+#ifndef HAVE_SPLIT_USR
+ || path_equal(path, "/usr")
+#endif
+ || path_startswith(path, "/run/initramfs");
}
static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_error) {
@@ -399,21 +412,21 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
* somehwere else via a bind mount. If we
* explicitly remount the super block of that
* alias read-only we hence should be
- * relatively safe regarding keeping the fs we
- * can otherwise not see dirty. */
+ * relatively safe regarding keeping dirty an fs
+ * we cannot otherwise see. */
log_info("Remounting '%s' read-only with options '%s'.", m->path, options);
- (void) mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, options);
+ if (mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, options) < 0) {
+ if (log_error)
+ log_notice_errno(errno, "Failed to remount '%s' read-only: %m", m->path);
+ if (nonunmountable_path(m->path))
+ n_failed++;
+ }
}
/* Skip / and /usr since we cannot unmount that
* anyway, since we are running from it. They have
* already been remounted ro. */
- if (path_equal(m->path, "/")
-#ifndef HAVE_SPLIT_USR
- || path_equal(m->path, "/usr")
-#endif
- || path_startswith(m->path, "/run/initramfs")
- )
+ if (nonunmountable_path(m->path))
continue;
/* Trying to umount. We don't force here since we rely
@@ -425,8 +438,9 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
*changed = true;
mount_point_free(head, m);
- } else if (log_error) {
- log_warning_errno(errno, "Could not unmount %s: %m", m->path);
+ } else {
+ if (log_error)
+ log_warning_errno(errno, "Could not unmount %s: %m", m->path);
n_failed++;
}
}
@@ -550,8 +564,6 @@ int umount_all(bool *changed) {
/* umount one more time with logging enabled */
r = mount_points_list_umount(&mp_list_head, &umount_changed, true);
- if (r <= 0)
- goto end;
end:
mount_points_list_free(&mp_list_head);
diff --git a/src/core/unit-printf.c b/src/core/unit-printf.c
index f11df42af3..746e1a46ef 100644
--- a/src/core/unit-printf.c
+++ b/src/core/unit-printf.c
@@ -19,7 +19,7 @@
#include "alloc-util.h"
#include "cgroup-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "macro.h"
#include "specifier.h"
#include "string-util.h"
@@ -78,12 +78,18 @@ static int specifier_filename(char specifier, void *data, void *userdata, char *
return unit_name_to_path(u->id, ret);
}
+static void bad_specifier(Unit *u, char specifier) {
+ log_unit_warning(u, "Specifier '%%%c' used in unit configuration, which is deprecated. Please update your unit file, as it does not work as intended.", specifier);
+}
+
static int specifier_cgroup(char specifier, void *data, void *userdata, char **ret) {
Unit *u = userdata;
char *n;
assert(u);
+ bad_specifier(u, specifier);
+
if (u->cgroup_path)
n = strdup(u->cgroup_path);
else
@@ -101,6 +107,8 @@ static int specifier_cgroup_root(char specifier, void *data, void *userdata, cha
assert(u);
+ bad_specifier(u, specifier);
+
n = strdup(u->manager->cgroup_root);
if (!n)
return -ENOMEM;
@@ -115,6 +123,8 @@ static int specifier_cgroup_slice(char specifier, void *data, void *userdata, ch
assert(u);
+ bad_specifier(u, specifier);
+
if (UNIT_ISSET(u->slice)) {
Unit *slice;
@@ -194,13 +204,20 @@ static int specifier_user_shell(char specifier, void *data, void *userdata, char
int unit_name_printf(Unit *u, const char* format, char **ret) {
/*
- * This will use the passed string as format string and
- * replace the following specifiers:
+ * This will use the passed string as format string and replace the following specifiers (which should all be
+ * safe for inclusion in unit names):
*
* %n: the full id of the unit (foo@bar.waldo)
* %N: the id of the unit without the suffix (foo@bar)
* %p: the prefix (foo)
* %i: the instance (bar)
+ *
+ * %U: the UID of the running user
+ * %u: the username of the running user
+ *
+ * %m: the machine ID of the running system
+ * %H: the host name of the running system
+ * %b: the boot ID of the running system
*/
const Specifier table[] = {
@@ -208,7 +225,14 @@ int unit_name_printf(Unit *u, const char* format, char **ret) {
{ 'N', specifier_prefix_and_instance, NULL },
{ 'p', specifier_prefix, NULL },
{ 'i', specifier_string, u->instance },
- { 0, NULL, NULL }
+
+ { 'U', specifier_user_id, NULL },
+ { 'u', specifier_user_name, NULL },
+
+ { 'm', specifier_machine_id, NULL },
+ { 'H', specifier_host_name, NULL },
+ { 'b', specifier_boot_id, NULL },
+ {}
};
assert(u);
@@ -220,22 +244,23 @@ int unit_name_printf(Unit *u, const char* format, char **ret) {
int unit_full_printf(Unit *u, const char *format, char **ret) {
- /* This is similar to unit_name_printf() but also supports
- * unescaping. Also, adds a couple of additional codes:
+ /* This is similar to unit_name_printf() but also supports unescaping. Also, adds a couple of additional codes
+ * (which are likely not suitable for unescaped inclusion in unit names):
+ *
+ * %f: the unescaped instance if set, otherwise the id unescaped as path
+ * %c: cgroup path of unit (deprecated)
+ * %r: where units in this slice are placed in the cgroup tree (deprecated)
+ * %R: the root of this systemd's instance tree (deprecated)
+ * %t: the runtime directory to place sockets in (e.g. "/run" or $XDG_RUNTIME_DIR)
+ *
+ * %h: the homedir of the running user
+ * %s: the shell of the running user
+ *
+ * %v: `uname -r` of the running system
*
- * %f the instance if set, otherwise the id
- * %c cgroup path of unit
- * %r where units in this slice are placed in the cgroup tree
- * %R the root of this systemd's instance tree
- * %t the runtime directory to place sockets in (e.g. "/run" or $XDG_RUNTIME_DIR)
- * %U the UID of the running user
- * %u the username of the running user
- * %h the homedir of the running user
- * %s the shell of the running user
- * %m the machine ID of the running system
- * %H the host name of the running system
- * %b the boot ID of the running system
- * %v `uname -r` of the running system
+ * NOTICE: When you add new entries here, please be careful: specifiers which depend on settings of the unit
+ * file itself are broken by design, as they would resolve differently depending on whether they are used
+ * before or after the relevant configuration setting. Hence: don't add them.
*/
const Specifier table[] = {
diff --git a/src/core/unit.c b/src/core/unit.c
index e664e23892..f76b6c30a8 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -36,7 +36,7 @@
#include "escape.h"
#include "execute.h"
#include "fileio-label.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "id128-util.h"
#include "load-dropin.h"
#include "load-fragment.h"
@@ -389,10 +389,8 @@ void unit_add_to_gc_queue(Unit *u) {
if (unit_check_gc(u))
return;
- LIST_PREPEND(gc_queue, u->manager->gc_queue, u);
+ LIST_PREPEND(gc_queue, u->manager->gc_unit_queue, u);
u->in_gc_queue = true;
-
- u->manager->n_in_gc_queue++;
}
void unit_add_to_dbus_queue(Unit *u) {
@@ -404,6 +402,7 @@ void unit_add_to_dbus_queue(Unit *u) {
/* Shortcut things if nobody cares */
if (sd_bus_track_count(u->manager->subscribed) <= 0 &&
+ sd_bus_track_count(u->bus_track) <= 0 &&
set_isempty(u->manager->private_buses)) {
u->sent_dbus_new_signal = true;
return;
@@ -518,7 +517,8 @@ void unit_free(Unit *u) {
Iterator i;
char *t;
- assert(u);
+ if (!u)
+ return;
if (u->transient_file)
fclose(u->transient_file);
@@ -570,10 +570,8 @@ void unit_free(Unit *u) {
if (u->in_cleanup_queue)
LIST_REMOVE(cleanup_queue, u->manager->cleanup_queue, u);
- if (u->in_gc_queue) {
- LIST_REMOVE(gc_queue, u->manager->gc_queue, u);
- u->manager->n_in_gc_queue--;
- }
+ if (u->in_gc_queue)
+ LIST_REMOVE(gc_queue, u->manager->gc_unit_queue, u);
if (u->in_cgroup_queue)
LIST_REMOVE(cgroup_queue, u->manager->cgroup_queue, u);
@@ -865,15 +863,25 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
return r;
}
+ if (c->root_image) {
+ r = unit_require_mounts_for(u, c->root_image);
+ if (r < 0)
+ return r;
+ }
+
if (!MANAGER_IS_SYSTEM(u->manager))
return 0;
if (c->private_tmp) {
- r = unit_require_mounts_for(u, "/tmp");
- if (r < 0)
- return r;
+ const char *p;
- r = unit_require_mounts_for(u, "/var/tmp");
+ FOREACH_STRING(p, "/tmp", "/var/tmp") {
+ r = unit_require_mounts_for(u, p);
+ if (r < 0)
+ return r;
+ }
+
+ r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_TMPFILES_SETUP_SERVICE, NULL, true);
if (r < 0)
return r;
}
@@ -1082,6 +1090,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
/* Common implementation for multiple backends */
int unit_load_fragment_and_dropin(Unit *u) {
+ Unit *t;
int r;
assert(u);
@@ -1094,16 +1103,18 @@ int unit_load_fragment_and_dropin(Unit *u) {
if (u->load_state == UNIT_STUB)
return -ENOENT;
- /* Load drop-in directory data */
- r = unit_load_dropin(unit_follow_merge(u));
- if (r < 0)
- return r;
+ /* If the unit is an alias and the final unit has already been
+ * loaded, there's no point in reloading the dropins one more time. */
+ t = unit_follow_merge(u);
+ if (t != u && t->load_state != UNIT_STUB)
+ return 0;
- return 0;
+ return unit_load_dropin(t);
}
/* Common implementation for multiple backends */
int unit_load_fragment_and_dropin_optional(Unit *u) {
+ Unit *t;
int r;
assert(u);
@@ -1119,12 +1130,13 @@ int unit_load_fragment_and_dropin_optional(Unit *u) {
if (u->load_state == UNIT_STUB)
u->load_state = UNIT_LOADED;
- /* Load drop-in directory data */
- r = unit_load_dropin(unit_follow_merge(u));
- if (r < 0)
- return r;
+ /* If the unit is an alias and the final unit has already been
+ * loaded, there's no point in reloading the dropins one more time. */
+ t = unit_follow_merge(u);
+ if (t != u && t->load_state != UNIT_STUB)
+ return 0;
- return 0;
+ return unit_load_dropin(t);
}
int unit_add_default_target_dependency(Unit *u, Unit *target) {
@@ -1455,9 +1467,8 @@ static void unit_status_print_starting_stopping(Unit *u, JobType t) {
}
static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
- const char *format;
+ const char *format, *mid;
char buf[LINE_MAX];
- sd_id128_t mid;
assert(u);
@@ -1475,9 +1486,9 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
snprintf(buf, sizeof buf, format, unit_description(u));
REENABLE_WARNING;
- mid = t == JOB_START ? SD_MESSAGE_UNIT_STARTING :
- t == JOB_STOP ? SD_MESSAGE_UNIT_STOPPING :
- SD_MESSAGE_UNIT_RELOADING;
+ mid = t == JOB_START ? "MESSAGE_ID=" SD_MESSAGE_UNIT_STARTING_STR :
+ t == JOB_STOP ? "MESSAGE_ID=" SD_MESSAGE_UNIT_STOPPING_STR :
+ "MESSAGE_ID=" SD_MESSAGE_UNIT_RELOADING_STR;
/* Note that we deliberately use LOG_MESSAGE() instead of
* LOG_UNIT_MESSAGE() here, since this is supposed to mimic
@@ -1486,7 +1497,7 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
* possible, which means we should avoid the low-level unit
* name. */
log_struct(LOG_INFO,
- LOG_MESSAGE_ID(mid),
+ mid,
LOG_UNIT_ID(u),
LOG_MESSAGE("%s", buf),
NULL);
@@ -1515,6 +1526,43 @@ int unit_start_limit_test(Unit *u) {
return emergency_action(u->manager, u->start_limit_action, u->reboot_arg, "unit failed");
}
+bool unit_shall_confirm_spawn(Unit *u) {
+ assert(u);
+
+ if (manager_is_confirm_spawn_disabled(u->manager))
+ return false;
+
+ /* For some reasons units remaining in the same process group
+ * as PID 1 fail to acquire the console even if it's not used
+ * by any process. So skip the confirmation question for them. */
+ return !unit_get_exec_context(u)->same_pgrp;
+}
+
+static bool unit_verify_deps(Unit *u) {
+ Unit *other;
+ Iterator j;
+
+ assert(u);
+
+ /* Checks whether all BindsTo= dependencies of this unit are fulfilled — if they are also combined with
+ * After=. We do not check Requires= or Requisite= here as they only should have an effect on the job
+ * processing, but do not have any effect afterwards. We don't check BindsTo= dependencies that are not used in
+ * conjunction with After= as for them any such check would make things entirely racy. */
+
+ SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], j) {
+
+ if (!set_contains(u->dependencies[UNIT_AFTER], other))
+ continue;
+
+ if (!UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(other))) {
+ log_unit_notice(u, "Bound to unit %s, but unit isn't active.", other->id);
+ return false;
+ }
+ }
+
+ return true;
+}
+
/* Errors:
* -EBADR: This unit type does not support starting.
* -EALREADY: Unit is already started.
@@ -1523,6 +1571,7 @@ int unit_start_limit_test(Unit *u) {
* -EPROTO: Assert failed
* -EINVAL: Unit not loaded
* -EOPNOTSUPP: Unit type not supported
+ * -ENOLINK: The necessary dependencies are not fulfilled.
*/
int unit_start(Unit *u) {
UnitActiveState state;
@@ -1568,6 +1617,12 @@ int unit_start(Unit *u) {
if (!unit_supported(u))
return -EOPNOTSUPP;
+ /* Let's make sure that the deps really are in order before we start this. Normally the job engine should have
+ * taken care of this already, but let's check this here again. After all, our dependencies might not be in
+ * effect anymore, due to a reload or due to a failed condition. */
+ if (!unit_verify_deps(u))
+ return -ENOLINK;
+
/* Forward to the main object, if we aren't it. */
following = unit_following(u);
if (following) {
@@ -2510,7 +2565,7 @@ int unit_set_default_slice(Unit *u) {
return -ENOMEM;
if (MANAGER_IS_SYSTEM(u->manager))
- b = strjoin("system-", escaped, ".slice", NULL);
+ b = strjoin("system-", escaped, ".slice");
else
b = strappend(escaped, ".slice");
if (!b)
@@ -2628,7 +2683,7 @@ void unit_unwatch_bus_name(Unit *u, const char *name) {
assert(u);
assert(name);
- hashmap_remove_value(u->manager->watch_bus, name, u);
+ (void) hashmap_remove_value(u->manager->watch_bus, name, u);
u->match_bus_slot = sd_bus_slot_unref(u->match_bus_slot);
}
@@ -3040,6 +3095,9 @@ int unit_add_node_link(Unit *u, const char *what, bool wants, UnitDependency dep
if (r < 0)
return r;
+ if (dep == UNIT_REQUIRES && device_shall_be_bound_by(device, u))
+ dep = UNIT_BINDS_TO;
+
r = unit_add_two_dependencies(u, UNIT_AFTER,
MANAGER_IS_SYSTEM(u->manager) ? dep : UNIT_WANTS,
device, true);
@@ -3096,6 +3154,11 @@ static bool fragment_mtime_newer(const char *path, usec_t mtime, bool path_maske
if (!path)
return false;
+ /* If the source is some virtual kernel file system, then we assume we watch it anyway, and hence pretend we
+ * are never out-of-date. */
+ if (PATH_STARTSWITH_SET(path, "/proc", "/sys"))
+ return false;
+
if (stat(path, &st) < 0)
/* What, cannot access this anymore? */
return true;
@@ -3429,14 +3492,6 @@ int unit_patch_contexts(Unit *u) {
ec->working_directory_missing_ok = true;
}
- if (MANAGER_IS_USER(u->manager) &&
- (ec->syscall_whitelist ||
- !set_isempty(ec->syscall_filter) ||
- !set_isempty(ec->syscall_archs) ||
- ec->address_families_whitelist ||
- !set_isempty(ec->address_families)))
- ec->no_new_privileges = true;
-
if (ec->private_devices)
ec->capability_bounding_set &= ~((UINT64_C(1) << CAP_MKNOD) | (UINT64_C(1) << CAP_SYS_RAWIO));
@@ -3670,7 +3725,7 @@ int unit_make_transient(Unit *u) {
if (!UNIT_VTABLE(u)->can_transient)
return -EOPNOTSUPP;
- path = strjoin(u->manager->lookup_paths.transient, "/", u->id, NULL);
+ path = strjoin(u->manager->lookup_paths.transient, "/", u->id);
if (!path)
return -ENOMEM;
@@ -3755,14 +3810,14 @@ int unit_kill_context(
bool main_pid_alien) {
bool wait_for_exit = false, send_sighup;
- cg_kill_log_func_t log_func;
+ cg_kill_log_func_t log_func = NULL;
int sig, r;
assert(u);
assert(c);
- /* Kill the processes belonging to this unit, in preparation for shutting the unit down. Returns > 0 if we
- * killed something worth waiting for, 0 otherwise. */
+ /* Kill the processes belonging to this unit, in preparation for shutting the unit down.
+ * Returns > 0 if we killed something worth waiting for, 0 otherwise. */
if (c->kill_mode == KILL_NONE)
return 0;
@@ -3774,9 +3829,8 @@ int unit_kill_context(
IN_SET(k, KILL_TERMINATE, KILL_TERMINATE_AND_LOG) &&
sig != SIGHUP;
- log_func =
- k != KILL_TERMINATE ||
- IN_SET(sig, SIGKILL, SIGABRT) ? log_kill : NULL;
+ if (k != KILL_TERMINATE || IN_SET(sig, SIGKILL, SIGABRT))
+ log_func = log_kill;
if (main_pid > 0) {
if (log_func)
@@ -3847,10 +3901,10 @@ int unit_kill_context(
* should not exist in non-delegated units. On
* the unified hierarchy that's different,
* there we get proper events. Hence rely on
- * them.*/
+ * them. */
- if (cg_unified(SYSTEMD_CGROUP_CONTROLLER) > 0 ||
- (detect_container() == 0 && !unit_cgroup_delegate(u)))
+ if (cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) > 0 ||
+ (detect_container() == 0 && !unit_cgroup_delegate(u)))
wait_for_exit = true;
if (send_sighup) {
@@ -4020,7 +4074,7 @@ void unit_warn_if_dir_nonempty(Unit *u, const char* where) {
}
log_struct(LOG_NOTICE,
- LOG_MESSAGE_ID(SD_MESSAGE_OVERMOUNTING),
+ "MESSAGE_ID=" SD_MESSAGE_OVERMOUNTING_STR,
LOG_UNIT_ID(u),
LOG_UNIT_MESSAGE(u, "Directory %s to mount over is not empty, mounting anyway.", where),
"WHERE=%s", where,
@@ -4042,7 +4096,7 @@ int unit_fail_if_symlink(Unit *u, const char* where) {
return 0;
log_struct(LOG_ERR,
- LOG_MESSAGE_ID(SD_MESSAGE_OVERMOUNTING),
+ "MESSAGE_ID=" SD_MESSAGE_OVERMOUNTING_STR,
LOG_UNIT_ID(u),
LOG_UNIT_MESSAGE(u, "Mount on symlink %s not allowed.", where),
"WHERE=%s", where,
diff --git a/src/core/unit.h b/src/core/unit.h
index 991543664b..8052c234fd 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -441,6 +441,9 @@ struct UnitVTable {
/* True if transient units of this type are OK */
bool can_transient:1;
+
+ /* True if queued jobs of this type should be GC'ed if no other job needs them anymore */
+ bool gc_jobs:1;
};
extern const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX];
@@ -654,6 +657,8 @@ void unit_notify_user_lookup(Unit *u, uid_t uid, gid_t gid);
int unit_set_invocation_id(Unit *u, sd_id128_t id);
int unit_acquire_invocation_id(Unit *u);
+bool unit_shall_confirm_spawn(Unit *u);
+
/* Macros which append UNIT= or USER_UNIT= to the message */
#define log_unit_full(unit, level, error, ...) \
diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c
index a982c204be..5828e949e3 100644
--- a/src/coredump/coredump.c
+++ b/src/coredump/coredump.c
@@ -47,13 +47,14 @@
#include "fileio.h"
#include "fs-util.h"
#include "io-util.h"
-#include "journald-native.h"
+#include "journal-importer.h"
#include "log.h"
#include "macro.h"
#include "missing.h"
#include "mkdir.h"
#include "parse-util.h"
#include "process-util.h"
+#include "signal-util.h"
#include "socket-util.h"
#include "special.h"
#include "stacktrace.h"
@@ -77,8 +78,22 @@
assert_cc(JOURNAL_SIZE_MAX <= DATA_SIZE_MAX);
enum {
- /* We use this as array indexes for a couple of special fields we use for naming coredumping files, and
- * attaching xattrs */
+ /* We use this as array indexes for a couple of special fields we use for
+ * naming coredump files, and attaching xattrs, and for indexing argv[].
+
+ * Our pattern for man:systectl(1) kernel.core_pattern is such that the
+ * kernel passes fields until CONTEXT_RLIMIT as arguments in argv[]. After
+ * that it gets complicated: the kernel passes "comm" as one or more fields
+ * starting at index CONTEXT_COMM (in other words, full "comm" is under index
+ * CONTEXT_COMM when it does not contain spaces, which is the common
+ * case). This mapping is not reversible, so we prefer to retrieve "comm"
+ * from /proc. We only fall back to argv[CONTEXT_COMM...] when that fails.
+ *
+ * In the internal context[] array, fields before CONTEXT_COMM are the
+ * strings from argv[], so they should not be freed. The strings at indices
+ * CONTEXT_COMM and higher are allocated by us and should be freed at the
+ * end.
+ */
CONTEXT_PID,
CONTEXT_UID,
CONTEXT_GID,
@@ -87,6 +102,7 @@ enum {
CONTEXT_RLIMIT,
CONTEXT_COMM,
CONTEXT_EXE,
+ CONTEXT_UNIT,
_CONTEXT_MAX
};
@@ -111,7 +127,7 @@ static CoredumpStorage arg_storage = COREDUMP_STORAGE_EXTERNAL;
static bool arg_compress = true;
static uint64_t arg_process_size_max = PROCESS_SIZE_MAX;
static uint64_t arg_external_size_max = EXTERNAL_SIZE_MAX;
-static size_t arg_journal_size_max = JOURNAL_SIZE_MAX;
+static uint64_t arg_journal_size_max = JOURNAL_SIZE_MAX;
static uint64_t arg_keep_free = (uint64_t) -1;
static uint64_t arg_max_use = (uint64_t) -1;
@@ -186,6 +202,7 @@ static int fix_xattr(int fd, const char *context[_CONTEXT_MAX]) {
[CONTEXT_GID] = "user.coredump.gid",
[CONTEXT_SIGNAL] = "user.coredump.signal",
[CONTEXT_TIMESTAMP] = "user.coredump.timestamp",
+ [CONTEXT_RLIMIT] = "user.coredump.rlimit",
[CONTEXT_COMM] = "user.coredump.comm",
[CONTEXT_EXE] = "user.coredump.exe",
};
@@ -308,7 +325,8 @@ static int save_external_coredump(
char **ret_filename,
int *ret_node_fd,
int *ret_data_fd,
- uint64_t *ret_size) {
+ uint64_t *ret_size,
+ bool *ret_truncated) {
_cleanup_free_ char *fn = NULL, *tmp = NULL;
_cleanup_close_ int fd = -1;
@@ -352,15 +370,17 @@ static int save_external_coredump(
if (fd < 0)
return log_error_errno(fd, "Failed to create temporary file for coredump %s: %m", fn);
- r = copy_bytes(input_fd, fd, max_size, false);
+ r = copy_bytes(input_fd, fd, max_size, 0);
if (r < 0) {
log_error_errno(r, "Cannot store coredump of %s (%s): %m", context[CONTEXT_PID], context[CONTEXT_COMM]);
goto fail;
- } else if (r == 1)
+ }
+ *ret_truncated = r == 1;
+ if (*ret_truncated)
log_struct(LOG_INFO,
LOG_MESSAGE("Core file was truncated to %zu bytes.", max_size),
"SIZE_LIMIT=%zu", max_size,
- LOG_MESSAGE_ID(SD_MESSAGE_TRUNCATED_CORE),
+ "MESSAGE_ID=" SD_MESSAGE_TRUNCATED_CORE_STR,
NULL);
if (fstat(fd, &st) < 0) {
@@ -642,7 +662,11 @@ static int get_process_container_parent_cmdline(pid_t pid, char** cmdline) {
if (r < 0)
return r;
- return get_process_cmdline(container_pid, 0, false, cmdline);
+ r = get_process_cmdline(container_pid, 0, false, cmdline);
+ if (r < 0)
+ return r;
+
+ return 1;
}
static int change_uid_gid(const char *context[]) {
@@ -671,6 +695,21 @@ static int change_uid_gid(const char *context[]) {
return drop_privileges(uid, gid, 0);
}
+static bool is_journald_crash(const char *context[_CONTEXT_MAX]) {
+ assert(context);
+
+ return streq_ptr(context[CONTEXT_UNIT], SPECIAL_JOURNALD_SERVICE);
+}
+
+static bool is_pid1_crash(const char *context[_CONTEXT_MAX]) {
+ assert(context);
+
+ return streq_ptr(context[CONTEXT_UNIT], SPECIAL_INIT_SCOPE) ||
+ streq_ptr(context[CONTEXT_PID], "1");
+}
+
+#define SUBMIT_COREDUMP_FIELDS 4
+
static int submit_coredump(
const char *context[_CONTEXT_MAX],
struct iovec *iovec,
@@ -681,18 +720,22 @@ static int submit_coredump(
_cleanup_close_ int coredump_fd = -1, coredump_node_fd = -1;
_cleanup_free_ char *core_message = NULL, *filename = NULL, *coredump_data = NULL;
uint64_t coredump_size = UINT64_MAX;
+ bool truncated = false, journald_crash;
int r;
assert(context);
assert(iovec);
- assert(n_iovec_allocated >= n_iovec + 3);
+ assert(n_iovec_allocated >= n_iovec + SUBMIT_COREDUMP_FIELDS);
assert(input_fd >= 0);
+ journald_crash = is_journald_crash(context);
+
/* Vacuum before we write anything again */
(void) coredump_vacuum(-1, arg_keep_free, arg_max_use);
/* Always stream the coredump to disk, if that's possible */
- r = save_external_coredump(context, input_fd, &filename, &coredump_node_fd, &coredump_fd, &coredump_size);
+ r = save_external_coredump(context, input_fd,
+ &filename, &coredump_node_fd, &coredump_fd, &coredump_size, &truncated);
if (r < 0)
/* Skip whole core dumping part */
goto log;
@@ -708,7 +751,7 @@ static int submit_coredump(
coredump_filename = strjoina("COREDUMP_FILENAME=", filename);
IOVEC_SET_STRING(iovec[n_iovec++], coredump_filename);
} else if (arg_storage == COREDUMP_STORAGE_EXTERNAL)
- log_info("The core will not be stored: size %zu is greater than %zu (the configured maximum)",
+ log_info("The core will not be stored: size %"PRIu64" is greater than %"PRIu64" (the configured maximum)",
coredump_size, arg_external_size_max);
/* Vacuum again, but exclude the coredump we just created */
@@ -729,22 +772,44 @@ static int submit_coredump(
r = coredump_make_stack_trace(coredump_fd, context[CONTEXT_EXE], &stacktrace);
if (r >= 0)
- core_message = strjoin("MESSAGE=Process ", context[CONTEXT_PID], " (", context[CONTEXT_COMM], ") of user ", context[CONTEXT_UID], " dumped core.\n\n", stacktrace, NULL);
+ core_message = strjoin("MESSAGE=Process ", context[CONTEXT_PID],
+ " (", context[CONTEXT_COMM], ") of user ",
+ context[CONTEXT_UID], " dumped core.",
+ journald_crash ? "\nCoredump diverted to " : "",
+ journald_crash ? filename : "",
+ "\n\n", stacktrace);
else if (r == -EINVAL)
log_warning("Failed to generate stack trace: %s", dwfl_errmsg(dwfl_errno()));
else
log_warning_errno(r, "Failed to generate stack trace: %m");
} else
- log_debug("Not generating stack trace: core size %zu is greater than %zu (the configured maximum)",
+ log_debug("Not generating stack trace: core size %"PRIu64" is greater than %"PRIu64" (the configured maximum)",
coredump_size, arg_process_size_max);
if (!core_message)
#endif
log:
- core_message = strjoin("MESSAGE=Process ", context[CONTEXT_PID], " (", context[CONTEXT_COMM], ") of user ", context[CONTEXT_UID], " dumped core.", NULL);
+ core_message = strjoin("MESSAGE=Process ", context[CONTEXT_PID],
+ " (", context[CONTEXT_COMM], ") of user ",
+ context[CONTEXT_UID], " dumped core.",
+ journald_crash ? "\nCoredump diverted to " : NULL,
+ journald_crash ? filename : NULL);
+ if (!core_message)
+ return log_oom();
+
+ if (journald_crash) {
+ /* We cannot log to the journal, so just print the MESSAGE.
+ * The target was set previously to something safe. */
+ log_struct(LOG_ERR, core_message, NULL);
+ return 0;
+ }
+
if (core_message)
IOVEC_SET_STRING(iovec[n_iovec++], core_message);
+ if (truncated)
+ IOVEC_SET_STRING(iovec[n_iovec++], "COREDUMP_TRUNCATED=1");
+
/* Optionally store the entire coredump in the journal */
if (arg_storage == COREDUMP_STORAGE_JOURNAL) {
if (coredump_size <= arg_journal_size_max) {
@@ -760,7 +825,7 @@ log:
} else
log_warning_errno(r, "Failed to attach the core to the journal entry: %m");
} else
- log_info("The core will not be stored: size %zu is greater than %zu (the configured maximum)",
+ log_info("The core will not be stored: size %"PRIu64" is greater than %"PRIu64" (the configured maximum)",
coredump_size, arg_journal_size_max);
}
@@ -773,17 +838,17 @@ log:
return 0;
}
-static void map_context_fields(const struct iovec *iovec, const char *context[]) {
+static void map_context_fields(const struct iovec *iovec, const char* context[]) {
- static const char * const context_field_names[_CONTEXT_MAX] = {
+ static const char * const context_field_names[] = {
[CONTEXT_PID] = "COREDUMP_PID=",
[CONTEXT_UID] = "COREDUMP_UID=",
[CONTEXT_GID] = "COREDUMP_GID=",
[CONTEXT_SIGNAL] = "COREDUMP_SIGNAL=",
[CONTEXT_TIMESTAMP] = "COREDUMP_TIMESTAMP=",
+ [CONTEXT_RLIMIT] = "COREDUMP_RLIMIT=",
[CONTEXT_COMM] = "COREDUMP_COMM=",
[CONTEXT_EXE] = "COREDUMP_EXE=",
- [CONTEXT_RLIMIT] = "COREDUMP_RLIMIT=",
};
unsigned i;
@@ -791,9 +856,12 @@ static void map_context_fields(const struct iovec *iovec, const char *context[])
assert(iovec);
assert(context);
- for (i = 0; i < _CONTEXT_MAX; i++) {
+ for (i = 0; i < ELEMENTSOF(context_field_names); i++) {
size_t l;
+ if (!context_field_names[i])
+ continue;
+
l = strlen(context_field_names[i]);
if (iovec->iov_len < l)
continue;
@@ -811,7 +879,7 @@ static void map_context_fields(const struct iovec *iovec, const char *context[])
static int process_socket(int fd) {
_cleanup_close_ int coredump_fd = -1;
struct iovec *iovec = NULL;
- size_t n_iovec = 0, n_iovec_allocated = 0, i;
+ size_t n_iovec = 0, n_allocated = 0, i, k;
const char *context[_CONTEXT_MAX] = {};
int r;
@@ -821,6 +889,8 @@ static int process_socket(int fd) {
log_parse_environment();
log_open();
+ log_debug("Processing coredump received on stdin...");
+
for (;;) {
union {
struct cmsghdr cmsghdr;
@@ -834,7 +904,7 @@ static int process_socket(int fd) {
ssize_t n;
ssize_t l;
- if (!GREEDY_REALLOC(iovec, n_iovec_allocated, n_iovec + 3)) {
+ if (!GREEDY_REALLOC(iovec, n_allocated, n_iovec + SUBMIT_COREDUMP_FIELDS)) {
r = log_oom();
goto finish;
}
@@ -898,7 +968,7 @@ static int process_socket(int fd) {
n_iovec++;
}
- if (!GREEDY_REALLOC(iovec, n_iovec_allocated, n_iovec + 3)) {
+ if (!GREEDY_REALLOC(iovec, n_allocated, n_iovec + SUBMIT_COREDUMP_FIELDS)) {
r = log_oom();
goto finish;
}
@@ -913,7 +983,14 @@ static int process_socket(int fd) {
assert(context[CONTEXT_COMM]);
assert(coredump_fd >= 0);
- r = submit_coredump(context, iovec, n_iovec_allocated, n_iovec, coredump_fd);
+ /* Small quirk: the journal fields contain the timestamp padded with six zeroes, so that the kernel-supplied 1s
+ * granularity timestamps becomes 1µs granularity, i.e. the granularity systemd usually operates in. Since we
+ * are reconstructing the original kernel context, we chop this off again, here. */
+ k = strlen(context[CONTEXT_TIMESTAMP]);
+ if (k > 6)
+ context[CONTEXT_TIMESTAMP] = strndupa(context[CONTEXT_TIMESTAMP], k - 6);
+
+ r = submit_coredump(context, iovec, n_allocated, n_iovec, coredump_fd);
finish:
for (i = 0; i < n_iovec; i++)
@@ -989,284 +1066,318 @@ static int send_iovec(const struct iovec iovec[], size_t n_iovec, int input_fd)
return 0;
}
-static int process_special_crash(const char *context[], int input_fd) {
- _cleanup_close_ int coredump_fd = -1, coredump_node_fd = -1;
- _cleanup_free_ char *filename = NULL;
- uint64_t coredump_size;
- int r;
+static char* set_iovec_field(struct iovec iovec[27], size_t *n_iovec, const char *field, const char *value) {
+ char *x;
- assert(context);
- assert(input_fd >= 0);
-
- /* If we are pid1 or journald, we cut things short, don't write to the journal, but still create a coredump. */
-
- if (arg_storage != COREDUMP_STORAGE_NONE)
- arg_storage = COREDUMP_STORAGE_EXTERNAL;
-
- r = save_external_coredump(context, input_fd, &filename, &coredump_node_fd, &coredump_fd, &coredump_size);
- if (r < 0)
- return r;
-
- r = maybe_remove_external_coredump(filename, coredump_size);
- if (r < 0)
- return r;
+ x = strappend(field, value);
+ if (x)
+ IOVEC_SET_STRING(iovec[(*n_iovec)++], x);
+ return x;
+}
- log_notice("Detected coredump of the journal daemon or PID 1, diverted to %s.", filename);
+static char* set_iovec_field_free(struct iovec iovec[27], size_t *n_iovec, const char *field, char *value) {
+ char *x;
- return 0;
+ x = set_iovec_field(iovec, n_iovec, field, value);
+ free(value);
+ return x;
}
-static int process_kernel(int argc, char* argv[]) {
+static int gather_pid_metadata(
+ char* context[_CONTEXT_MAX],
+ char **comm_fallback,
+ struct iovec *iovec, size_t *n_iovec) {
+
+ /* We need 26 empty slots in iovec!
+ *
+ * Note that if we fail on oom later on, we do not roll-back changes to the iovec structure. (It remains valid,
+ * with the first n_iovec fields initialized.) */
- /* The small core field we allocate on the stack, to keep things simple */
- char
- *core_pid = NULL, *core_uid = NULL, *core_gid = NULL, *core_signal = NULL,
- *core_session = NULL, *core_exe = NULL, *core_comm = NULL, *core_cmdline = NULL,
- *core_cgroup = NULL, *core_cwd = NULL, *core_root = NULL, *core_unit = NULL,
- *core_user_unit = NULL, *core_slice = NULL, *core_timestamp = NULL, *core_rlimit = NULL;
-
- /* The larger ones we allocate on the heap */
- _cleanup_free_ char
- *core_owner_uid = NULL, *core_open_fds = NULL, *core_proc_status = NULL,
- *core_proc_maps = NULL, *core_proc_limits = NULL, *core_proc_cgroup = NULL, *core_environ = NULL,
- *core_proc_mountinfo = NULL, *core_container_cmdline = NULL;
-
- _cleanup_free_ char *exe = NULL, *comm = NULL;
- const char *context[_CONTEXT_MAX];
- bool proc_self_root_is_slash;
- struct iovec iovec[27];
- size_t n_iovec = 0;
uid_t owner_uid;
- const char *p;
pid_t pid;
char *t;
- int r;
-
- if (argc < CONTEXT_COMM + 1) {
- log_error("Not enough arguments passed from kernel (%i, expected %i).", argc - 1, CONTEXT_COMM + 1 - 1);
- return -EINVAL;
- }
+ const char *p;
+ int r, signo;
- r = parse_pid(argv[CONTEXT_PID + 1], &pid);
+ r = parse_pid(context[CONTEXT_PID], &pid);
if (r < 0)
- return log_error_errno(r, "Failed to parse PID.");
+ return log_error_errno(r, "Failed to parse PID \"%s\": %m", context[CONTEXT_PID]);
- r = get_process_comm(pid, &comm);
+ r = get_process_comm(pid, &context[CONTEXT_COMM]);
if (r < 0) {
log_warning_errno(r, "Failed to get COMM, falling back to the command line: %m");
- comm = strv_join(argv + CONTEXT_COMM + 1, " ");
- if (!comm)
+ context[CONTEXT_COMM] = strv_join(comm_fallback, " ");
+ if (!context[CONTEXT_COMM])
return log_oom();
}
- r = get_process_exe(pid, &exe);
+ r = get_process_exe(pid, &context[CONTEXT_EXE]);
if (r < 0)
log_warning_errno(r, "Failed to get EXE, ignoring: %m");
- context[CONTEXT_PID] = argv[CONTEXT_PID + 1];
- context[CONTEXT_UID] = argv[CONTEXT_UID + 1];
- context[CONTEXT_GID] = argv[CONTEXT_GID + 1];
- context[CONTEXT_SIGNAL] = argv[CONTEXT_SIGNAL + 1];
- context[CONTEXT_TIMESTAMP] = argv[CONTEXT_TIMESTAMP + 1];
- context[CONTEXT_RLIMIT] = argv[CONTEXT_RLIMIT + 1];
- context[CONTEXT_COMM] = comm;
- context[CONTEXT_EXE] = exe;
-
- if (cg_pid_get_unit(pid, &t) >= 0) {
+ if (cg_pid_get_unit(pid, &context[CONTEXT_UNIT]) >= 0) {
+ if (!is_journald_crash((const char**) context)) {
+ /* OK, now we know it's not the journal, hence we can make use of it now. */
+ log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
+ log_open();
+ }
/* If this is PID 1 disable coredump collection, we'll unlikely be able to process it later on. */
- if (streq(t, SPECIAL_INIT_SCOPE)) {
+ if (is_pid1_crash((const char**) context)) {
log_notice("Due to PID 1 having crashed coredump collection will now be turned off.");
(void) write_string_file("/proc/sys/kernel/core_pattern", "|/bin/false", 0);
}
- /* Let's avoid dead-locks when processing journald and init crashes, as socket activation and logging
- * are unlikely to work then. */
- if (STR_IN_SET(t, SPECIAL_JOURNALD_SERVICE, SPECIAL_INIT_SCOPE)) {
- free(t);
- return process_special_crash(context, STDIN_FILENO);
- }
-
- core_unit = strjoina("COREDUMP_UNIT=", t);
- free(t);
-
- IOVEC_SET_STRING(iovec[n_iovec++], core_unit);
+ set_iovec_field(iovec, n_iovec, "COREDUMP_UNIT=", context[CONTEXT_UNIT]);
}
- /* OK, now we know it's not the journal, hence we can make use of it now. */
- log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
- log_open();
+ if (cg_pid_get_user_unit(pid, &t) >= 0)
+ set_iovec_field_free(iovec, n_iovec, "COREDUMP_USER_UNIT=", t);
- if (cg_pid_get_user_unit(pid, &t) >= 0) {
- core_user_unit = strjoina("COREDUMP_USER_UNIT=", t);
- free(t);
+ /* The next few are mandatory */
+ if (!set_iovec_field(iovec, n_iovec, "COREDUMP_PID=", context[CONTEXT_PID]))
+ return log_oom();
- IOVEC_SET_STRING(iovec[n_iovec++], core_user_unit);
- }
+ if (!set_iovec_field(iovec, n_iovec, "COREDUMP_UID=", context[CONTEXT_UID]))
+ return log_oom();
- core_pid = strjoina("COREDUMP_PID=", context[CONTEXT_PID]);
- IOVEC_SET_STRING(iovec[n_iovec++], core_pid);
+ if (!set_iovec_field(iovec, n_iovec, "COREDUMP_GID=", context[CONTEXT_GID]))
+ return log_oom();
- core_uid = strjoina("COREDUMP_UID=", context[CONTEXT_UID]);
- IOVEC_SET_STRING(iovec[n_iovec++], core_uid);
+ if (!set_iovec_field(iovec, n_iovec, "COREDUMP_SIGNAL=", context[CONTEXT_SIGNAL]))
+ return log_oom();
- core_gid = strjoina("COREDUMP_GID=", context[CONTEXT_GID]);
- IOVEC_SET_STRING(iovec[n_iovec++], core_gid);
+ if (!set_iovec_field(iovec, n_iovec, "COREDUMP_RLIMIT=", context[CONTEXT_RLIMIT]))
+ return log_oom();
- core_signal = strjoina("COREDUMP_SIGNAL=", context[CONTEXT_SIGNAL]);
- IOVEC_SET_STRING(iovec[n_iovec++], core_signal);
+ if (!set_iovec_field(iovec, n_iovec, "COREDUMP_COMM=", context[CONTEXT_COMM]))
+ return log_oom();
- core_rlimit = strjoina("COREDUMP_RLIMIT=", context[CONTEXT_RLIMIT]);
- IOVEC_SET_STRING(iovec[n_iovec++], core_rlimit);
+ if (context[CONTEXT_EXE] &&
+ !set_iovec_field(iovec, n_iovec, "COREDUMP_EXE=", context[CONTEXT_EXE]))
+ return log_oom();
- if (sd_pid_get_session(pid, &t) >= 0) {
- core_session = strjoina("COREDUMP_SESSION=", t);
- free(t);
-
- IOVEC_SET_STRING(iovec[n_iovec++], core_session);
- }
+ if (sd_pid_get_session(pid, &t) >= 0)
+ set_iovec_field_free(iovec, n_iovec, "COREDUMP_SESSION=", t);
if (sd_pid_get_owner_uid(pid, &owner_uid) >= 0) {
- r = asprintf(&core_owner_uid, "COREDUMP_OWNER_UID=" UID_FMT, owner_uid);
+ r = asprintf(&t, "COREDUMP_OWNER_UID=" UID_FMT, owner_uid);
if (r > 0)
- IOVEC_SET_STRING(iovec[n_iovec++], core_owner_uid);
+ IOVEC_SET_STRING(iovec[(*n_iovec)++], t);
}
- if (sd_pid_get_slice(pid, &t) >= 0) {
- core_slice = strjoina("COREDUMP_SLICE=", t);
- free(t);
+ if (sd_pid_get_slice(pid, &t) >= 0)
+ set_iovec_field_free(iovec, n_iovec, "COREDUMP_SLICE=", t);
- IOVEC_SET_STRING(iovec[n_iovec++], core_slice);
- }
+ if (get_process_cmdline(pid, 0, false, &t) >= 0)
+ set_iovec_field_free(iovec, n_iovec, "COREDUMP_CMDLINE=", t);
- if (comm) {
- core_comm = strjoina("COREDUMP_COMM=", comm);
- IOVEC_SET_STRING(iovec[n_iovec++], core_comm);
- }
+ if (cg_pid_get_path_shifted(pid, NULL, &t) >= 0)
+ set_iovec_field_free(iovec, n_iovec, "COREDUMP_CGROUP=", t);
- if (exe) {
- core_exe = strjoina("COREDUMP_EXE=", exe);
- IOVEC_SET_STRING(iovec[n_iovec++], core_exe);
- }
+ if (compose_open_fds(pid, &t) >= 0)
+ set_iovec_field_free(iovec, n_iovec, "COREDUMP_OPEN_FDS=", t);
- if (get_process_cmdline(pid, 0, false, &t) >= 0) {
- core_cmdline = strjoina("COREDUMP_CMDLINE=", t);
- free(t);
+ p = procfs_file_alloca(pid, "status");
+ if (read_full_file(p, &t, NULL) >= 0)
+ set_iovec_field_free(iovec, n_iovec, "COREDUMP_PROC_STATUS=", t);
- IOVEC_SET_STRING(iovec[n_iovec++], core_cmdline);
- }
+ p = procfs_file_alloca(pid, "maps");
+ if (read_full_file(p, &t, NULL) >= 0)
+ set_iovec_field_free(iovec, n_iovec, "COREDUMP_PROC_MAPS=", t);
- if (cg_pid_get_path_shifted(pid, NULL, &t) >= 0) {
- core_cgroup = strjoina("COREDUMP_CGROUP=", t);
- free(t);
+ p = procfs_file_alloca(pid, "limits");
+ if (read_full_file(p, &t, NULL) >= 0)
+ set_iovec_field_free(iovec, n_iovec, "COREDUMP_PROC_LIMITS=", t);
- IOVEC_SET_STRING(iovec[n_iovec++], core_cgroup);
- }
+ p = procfs_file_alloca(pid, "cgroup");
+ if (read_full_file(p, &t, NULL) >=0)
+ set_iovec_field_free(iovec, n_iovec, "COREDUMP_PROC_CGROUP=", t);
- if (compose_open_fds(pid, &t) >= 0) {
- core_open_fds = strappend("COREDUMP_OPEN_FDS=", t);
- free(t);
+ p = procfs_file_alloca(pid, "mountinfo");
+ if (read_full_file(p, &t, NULL) >=0)
+ set_iovec_field_free(iovec, n_iovec, "COREDUMP_PROC_MOUNTINFO=", t);
- if (core_open_fds)
- IOVEC_SET_STRING(iovec[n_iovec++], core_open_fds);
- }
+ if (get_process_cwd(pid, &t) >= 0)
+ set_iovec_field_free(iovec, n_iovec, "COREDUMP_CWD=", t);
- p = procfs_file_alloca(pid, "status");
- if (read_full_file(p, &t, NULL) >= 0) {
- core_proc_status = strappend("COREDUMP_PROC_STATUS=", t);
- free(t);
+ if (get_process_root(pid, &t) >= 0) {
+ bool proc_self_root_is_slash;
- if (core_proc_status)
- IOVEC_SET_STRING(iovec[n_iovec++], core_proc_status);
- }
+ proc_self_root_is_slash = strcmp(t, "/") == 0;
- p = procfs_file_alloca(pid, "maps");
- if (read_full_file(p, &t, NULL) >= 0) {
- core_proc_maps = strappend("COREDUMP_PROC_MAPS=", t);
- free(t);
+ set_iovec_field_free(iovec, n_iovec, "COREDUMP_ROOT=", t);
- if (core_proc_maps)
- IOVEC_SET_STRING(iovec[n_iovec++], core_proc_maps);
+ /* If the process' root is "/", then there is a chance it has
+ * mounted own root and hence being containerized. */
+ if (proc_self_root_is_slash && get_process_container_parent_cmdline(pid, &t) > 0)
+ set_iovec_field_free(iovec, n_iovec, "COREDUMP_CONTAINER_CMDLINE=", t);
}
- p = procfs_file_alloca(pid, "limits");
- if (read_full_file(p, &t, NULL) >= 0) {
- core_proc_limits = strappend("COREDUMP_PROC_LIMITS=", t);
- free(t);
+ if (get_process_environ(pid, &t) >= 0)
+ set_iovec_field_free(iovec, n_iovec, "COREDUMP_ENVIRON=", t);
- if (core_proc_limits)
- IOVEC_SET_STRING(iovec[n_iovec++], core_proc_limits);
- }
+ t = strjoin("COREDUMP_TIMESTAMP=", context[CONTEXT_TIMESTAMP], "000000", NULL);
+ if (t)
+ IOVEC_SET_STRING(iovec[(*n_iovec)++], t);
- p = procfs_file_alloca(pid, "cgroup");
- if (read_full_file(p, &t, NULL) >=0) {
- core_proc_cgroup = strappend("COREDUMP_PROC_CGROUP=", t);
- free(t);
+ if (safe_atoi(context[CONTEXT_SIGNAL], &signo) >= 0 && SIGNAL_VALID(signo))
+ set_iovec_field(iovec, n_iovec, "COREDUMP_SIGNAL_NAME=SIG", signal_to_string(signo));
- if (core_proc_cgroup)
- IOVEC_SET_STRING(iovec[n_iovec++], core_proc_cgroup);
- }
+ return 0; /* we successfully acquired all metadata */
+}
- p = procfs_file_alloca(pid, "mountinfo");
- if (read_full_file(p, &t, NULL) >=0) {
- core_proc_mountinfo = strappend("COREDUMP_PROC_MOUNTINFO=", t);
- free(t);
+static int process_kernel(int argc, char* argv[]) {
- if (core_proc_mountinfo)
- IOVEC_SET_STRING(iovec[n_iovec++], core_proc_mountinfo);
- }
+ char* context[_CONTEXT_MAX] = {};
+ struct iovec iovec[28 + SUBMIT_COREDUMP_FIELDS];
+ size_t i, n_iovec, n_to_free = 0;
+ int r;
- if (get_process_cwd(pid, &t) >= 0) {
- core_cwd = strjoina("COREDUMP_CWD=", t);
- free(t);
+ log_debug("Processing coredump received from the kernel...");
- IOVEC_SET_STRING(iovec[n_iovec++], core_cwd);
+ if (argc < CONTEXT_COMM + 1) {
+ log_error("Not enough arguments passed by the kernel (%i, expected %i).", argc - 1, CONTEXT_COMM + 1 - 1);
+ return -EINVAL;
}
- if (get_process_root(pid, &t) >= 0) {
- core_root = strjoina("COREDUMP_ROOT=", t);
+ context[CONTEXT_PID] = argv[1 + CONTEXT_PID];
+ context[CONTEXT_UID] = argv[1 + CONTEXT_UID];
+ context[CONTEXT_GID] = argv[1 + CONTEXT_GID];
+ context[CONTEXT_SIGNAL] = argv[1 + CONTEXT_SIGNAL];
+ context[CONTEXT_TIMESTAMP] = argv[1 + CONTEXT_TIMESTAMP];
+ context[CONTEXT_RLIMIT] = argv[1 + CONTEXT_RLIMIT];
- IOVEC_SET_STRING(iovec[n_iovec++], core_root);
+ r = gather_pid_metadata(context, argv + 1 + CONTEXT_COMM, iovec, &n_to_free);
+ if (r < 0)
+ goto finish;
- /* If the process' root is "/", then there is a chance it has
- * mounted own root and hence being containerized. */
- proc_self_root_is_slash = strcmp(t, "/") == 0;
- free(t);
- if (proc_self_root_is_slash && get_process_container_parent_cmdline(pid, &t) > 0) {
- core_container_cmdline = strappend("COREDUMP_CONTAINER_CMDLINE=", t);
- free(t);
+ n_iovec = n_to_free;
- if (core_container_cmdline)
- IOVEC_SET_STRING(iovec[n_iovec++], core_container_cmdline);
- }
+ IOVEC_SET_STRING(iovec[n_iovec++], "MESSAGE_ID=" SD_MESSAGE_COREDUMP_STR);
+
+ assert_cc(2 == LOG_CRIT);
+ IOVEC_SET_STRING(iovec[n_iovec++], "PRIORITY=2");
+
+ assert(n_iovec <= ELEMENTSOF(iovec));
+
+ if (is_journald_crash((const char**) context) || is_pid1_crash((const char**) context))
+ r = submit_coredump((const char**) context,
+ iovec, ELEMENTSOF(iovec), n_iovec,
+ STDIN_FILENO);
+ else
+ r = send_iovec(iovec, n_iovec, STDIN_FILENO);
+
+ finish:
+ for (i = 0; i < n_to_free; i++)
+ free(iovec[i].iov_base);
+
+ /* Those fields are allocated by gather_pid_metadata */
+ free(context[CONTEXT_COMM]);
+ free(context[CONTEXT_EXE]);
+ free(context[CONTEXT_UNIT]);
+
+ return r;
+}
+
+static int process_backtrace(int argc, char *argv[]) {
+ char *context[_CONTEXT_MAX] = {};
+ _cleanup_free_ char *message = NULL;
+ _cleanup_free_ struct iovec *iovec = NULL;
+ size_t n_iovec, n_allocated, n_to_free = 0, i;
+ int r;
+ JournalImporter importer = {
+ .fd = STDIN_FILENO,
+ };
+
+ log_debug("Processing backtrace on stdin...");
+
+ if (argc < CONTEXT_COMM + 1) {
+ log_error("Not enough arguments passed (%i, expected %i).", argc - 1, CONTEXT_COMM + 1 - 1);
+ return -EINVAL;
}
- if (get_process_environ(pid, &t) >= 0) {
- core_environ = strappend("COREDUMP_ENVIRON=", t);
- free(t);
+ context[CONTEXT_PID] = argv[2 + CONTEXT_PID];
+ context[CONTEXT_UID] = argv[2 + CONTEXT_UID];
+ context[CONTEXT_GID] = argv[2 + CONTEXT_GID];
+ context[CONTEXT_SIGNAL] = argv[2 + CONTEXT_SIGNAL];
+ context[CONTEXT_TIMESTAMP] = argv[2 + CONTEXT_TIMESTAMP];
+ context[CONTEXT_RLIMIT] = argv[2 + CONTEXT_RLIMIT];
+
+ n_allocated = 33 + COREDUMP_STORAGE_EXTERNAL;
+ /* 25 metadata, 2 static, +unknown input, 4 storage, rounded up */
+ iovec = new(struct iovec, n_allocated);
+ if (!iovec)
+ return log_oom();
- if (core_environ)
- IOVEC_SET_STRING(iovec[n_iovec++], core_environ);
+ r = gather_pid_metadata(context, argv + 2 + CONTEXT_COMM, iovec, &n_to_free);
+ if (r < 0)
+ goto finish;
+ if (r > 0) {
+ /* This was a special crash, and has already been processed. */
+ r = 0;
+ goto finish;
+ }
+ n_iovec = n_to_free;
+
+ for (;;) {
+ r = journal_importer_process_data(&importer);
+ if (r < 0) {
+ log_error_errno(r, "Failed to parse journal entry on stdin: %m");
+ goto finish;
+ }
+ if (r == 1 || /* complete entry */
+ journal_importer_eof(&importer)) /* end of data */
+ break;
}
- core_timestamp = strjoina("COREDUMP_TIMESTAMP=", context[CONTEXT_TIMESTAMP], "000000");
- IOVEC_SET_STRING(iovec[n_iovec++], core_timestamp);
+ if (!GREEDY_REALLOC(iovec, n_allocated, n_iovec + importer.iovw.count + 2))
+ return log_oom();
- IOVEC_SET_STRING(iovec[n_iovec++], "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1");
+ if (journal_importer_eof(&importer)) {
+ log_warning("Did not receive a full journal entry on stdin, ignoring message sent by reporter");
+ message = strjoin("MESSAGE=Process ", context[CONTEXT_PID],
+ " (", context[CONTEXT_COMM], ")"
+ " of user ", context[CONTEXT_UID],
+ " failed with ", context[CONTEXT_SIGNAL]);
+ if (!message) {
+ r = log_oom();
+ goto finish;
+ }
+ IOVEC_SET_STRING(iovec[n_iovec++], message);
+ } else {
+ for (i = 0; i < importer.iovw.count; i++)
+ iovec[n_iovec++] = importer.iovw.iovec[i];
+ }
+
+ IOVEC_SET_STRING(iovec[n_iovec++], "MESSAGE_ID=" SD_MESSAGE_BACKTRACE_STR);
assert_cc(2 == LOG_CRIT);
IOVEC_SET_STRING(iovec[n_iovec++], "PRIORITY=2");
- assert(n_iovec <= ELEMENTSOF(iovec));
+ assert(n_iovec <= n_allocated);
+
+ r = sd_journal_sendv(iovec, n_iovec);
+ if (r < 0)
+ log_error_errno(r, "Failed to log backtrace: %m");
+
+ finish:
+ for (i = 0; i < n_to_free; i++)
+ free(iovec[i].iov_base);
+
+ /* Those fields are allocated by gather_pid_metadata */
+ free(context[CONTEXT_COMM]);
+ free(context[CONTEXT_EXE]);
+ free(context[CONTEXT_UNIT]);
- return send_iovec(iovec, n_iovec, STDIN_FILENO);
+ return r;
}
int main(int argc, char *argv[]) {
int r;
- /* First, log to a safe place, since we don't know what crashed and it might be journald which we'd rather not
- * log to then. */
+ /* First, log to a safe place, since we don't know what crashed and it might
+ * be journald which we'd rather not log to then. */
log_set_target(LOG_TARGET_KMSG);
log_open();
@@ -1286,11 +1397,14 @@ int main(int argc, char *argv[]) {
goto finish;
}
- /* If we got an fd passed, we are running in coredumpd mode. Otherwise we are invoked from the kernel as
- * coredump handler */
- if (r == 0)
- r = process_kernel(argc, argv);
- else if (r == 1)
+ /* If we got an fd passed, we are running in coredumpd mode. Otherwise we
+ * are invoked from the kernel as coredump handler. */
+ if (r == 0) {
+ if (streq_ptr(argv[1], "--backtrace"))
+ r = process_backtrace(argc, argv);
+ else
+ r = process_kernel(argc, argv);
+ } else if (r == 1)
r = process_socket(SD_LISTEN_FDS_START);
else {
log_error("Received unexpected number of file descriptors.");
diff --git a/src/coredump/coredumpctl.c b/src/coredump/coredumpctl.c
index 0e5351e621..114a13fc78 100644
--- a/src/coredump/coredumpctl.c
+++ b/src/coredump/coredumpctl.c
@@ -24,28 +24,37 @@
#include <string.h>
#include <unistd.h>
+#include "sd-bus.h"
#include "sd-journal.h"
+#include "sd-messages.h"
#include "alloc-util.h"
+#include "bus-error.h"
+#include "bus-util.h"
#include "compress.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
#include "journal-internal.h"
+#include "journal-util.h"
#include "log.h"
#include "macro.h"
#include "pager.h"
#include "parse-util.h"
#include "path-util.h"
#include "process-util.h"
-#include "set.h"
#include "sigbus.h"
#include "signal-util.h"
#include "string-util.h"
+#include "strv.h"
#include "terminal-util.h"
#include "user-util.h"
#include "util.h"
+#define SHORT_BUS_CALL_TIMEOUT_USEC (3 * USEC_PER_SEC)
+
+static usec_t arg_since = USEC_INFINITY, arg_until = USEC_INFINITY;
+
static enum {
ACTION_NONE,
ACTION_INFO,
@@ -59,36 +68,11 @@ static bool arg_no_pager = false;
static int arg_no_legend = false;
static int arg_one = false;
static FILE* arg_output = NULL;
+static bool arg_reverse = false;
+static char** arg_matches = NULL;
+static bool arg_quiet = false;
-static Set *new_matches(void) {
- Set *set;
- char *tmp;
- int r;
-
- set = set_new(NULL);
- if (!set) {
- log_oom();
- return NULL;
- }
-
- tmp = strdup("MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1");
- if (!tmp) {
- log_oom();
- set_free(set);
- return NULL;
- }
-
- r = set_consume(set, tmp);
- if (r < 0) {
- log_error_errno(r, "failed to add to set: %m");
- set_free(set);
- return NULL;
- }
-
- return set;
-}
-
-static int add_match(Set *set, const char *match) {
+static int add_match(sd_journal *j, const char *match) {
_cleanup_free_ char *p = NULL;
char *pattern = NULL;
const char* prefix;
@@ -100,7 +84,8 @@ static int add_match(Set *set, const char *match) {
else if (strchr(match, '/')) {
r = path_make_absolute_cwd(match, &p);
if (r < 0)
- goto fail;
+ return log_error_errno(r, "path_make_absolute_cwd(\"%s\"): %m", match);
+
match = p;
prefix = "COREDUMP_EXE=";
} else if (parse_pid(match, &pid) >= 0)
@@ -108,20 +93,36 @@ static int add_match(Set *set, const char *match) {
else
prefix = "COREDUMP_COMM=";
- pattern = strjoin(prefix, match, NULL);
- if (!pattern) {
- r = -ENOMEM;
- goto fail;
- }
+ pattern = strjoin(prefix, match);
+ if (!pattern)
+ return log_oom();
- log_debug("Adding pattern: %s", pattern);
- r = set_consume(set, pattern);
+ log_debug("Adding match: %s", pattern);
+ r = sd_journal_add_match(j, pattern, 0);
if (r < 0)
- goto fail;
+ return log_error_errno(r, "Failed to add match \"%s\": %m", match);
+ return 0;
+}
+
+static int add_matches(sd_journal *j) {
+ char **match;
+ int r;
+
+ r = sd_journal_add_match(j, "MESSAGE_ID=" SD_MESSAGE_COREDUMP_STR, 0);
+ if (r < 0)
+ return log_error_errno(r, "Failed to add match \"%s\": %m", "MESSAGE_ID=" SD_MESSAGE_COREDUMP_STR);
+
+ r = sd_journal_add_match(j, "MESSAGE_ID=" SD_MESSAGE_BACKTRACE_STR, 0);
+ if (r < 0)
+ return log_error_errno(r, "Failed to add match \"%s\": %m", "MESSAGE_ID=" SD_MESSAGE_BACKTRACE_STR);
+
+ STRV_FOREACH(match, arg_matches) {
+ r = add_match(j, *match);
+ if (r < 0)
+ return r;
+ }
return 0;
-fail:
- return log_error_errno(r, "Failed to add match: %m");
}
static void help(void) {
@@ -133,10 +134,13 @@ static void help(void) {
" --no-pager Do not pipe output into a pager\n"
" --no-legend Do not print the column headers.\n"
" -1 Show information about most recent entry only\n"
+ " -S --since=DATE Only print coredumps since the date\n"
+ " -U --until=DATE Only print coredumps until the date\n"
+ " -r --reverse Show the newest entries first\n"
" -F --field=FIELD List all values a certain field takes\n"
- " -o --output=FILE Write output to FILE\n\n"
+ " -o --output=FILE Write output to FILE\n"
" -D --directory=DIR Use journal files from directory\n\n"
-
+ " -q --quiet Do not show info messages and privilege warning\n"
"Commands:\n"
" list [MATCHES...] List available coredumps (default)\n"
" info [MATCHES...] Show detailed information about one or more coredumps\n"
@@ -145,14 +149,14 @@ static void help(void) {
, program_invocation_short_name);
}
-static int parse_argv(int argc, char *argv[], Set *matches) {
+static int parse_argv(int argc, char *argv[]) {
enum {
ARG_VERSION = 0x100,
ARG_NO_PAGER,
ARG_NO_LEGEND,
};
- int r, c;
+ int c, r;
static const struct option options[] = {
{ "help", no_argument, NULL, 'h' },
@@ -162,15 +166,18 @@ static int parse_argv(int argc, char *argv[], Set *matches) {
{ "output", required_argument, NULL, 'o' },
{ "field", required_argument, NULL, 'F' },
{ "directory", required_argument, NULL, 'D' },
+ { "reverse", no_argument, NULL, 'r' },
+ { "since", required_argument, NULL, 'S' },
+ { "until", required_argument, NULL, 'U' },
+ { "quiet", no_argument, NULL, 'q' },
{}
};
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "ho:F:1D:", options, NULL)) >= 0)
+ while ((c = getopt_long(argc, argv, "ho:F:1D:rS:U:q", options, NULL)) >= 0)
switch(c) {
-
case 'h':
arg_action = ACTION_NONE;
help();
@@ -200,6 +207,18 @@ static int parse_argv(int argc, char *argv[], Set *matches) {
break;
+ case 'S':
+ r = parse_timestamp(optarg, &arg_since);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse timestamp: %s", optarg);
+ break;
+
+ case 'U':
+ r = parse_timestamp(optarg, &arg_until);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse timestamp: %s", optarg);
+ break;
+
case 'F':
if (arg_field) {
log_error("cannot use --field/-F more than once");
@@ -216,6 +235,14 @@ static int parse_argv(int argc, char *argv[], Set *matches) {
arg_directory = optarg;
break;
+ case 'r':
+ arg_reverse = true;
+ break;
+
+ case 'q':
+ arg_quiet = true;
+ break;
+
case '?':
return -EINVAL;
@@ -223,6 +250,12 @@ static int parse_argv(int argc, char *argv[], Set *matches) {
assert_not_reached("Unhandled option");
}
+ if (arg_since != USEC_INFINITY && arg_until != USEC_INFINITY &&
+ arg_since > arg_until) {
+ log_error("--since= must be before --until=.");
+ return -EINVAL;
+ }
+
if (optind < argc) {
const char *cmd = argv[optind++];
if (streq(cmd, "list"))
@@ -244,12 +277,8 @@ static int parse_argv(int argc, char *argv[], Set *matches) {
return -EINVAL;
}
- while (optind < argc) {
- r = add_match(matches, argv[optind]);
- if (r != 0)
- return r;
- optind++;
- }
+ if (optind < argc)
+ arg_matches = argv + optind;
return 0;
}
@@ -322,20 +351,22 @@ static int print_field(FILE* file, sd_journal *j) {
static int print_list(FILE* file, sd_journal *j, int had_legend) {
_cleanup_free_ char
- *pid = NULL, *uid = NULL, *gid = NULL,
+ *mid = NULL, *pid = NULL, *uid = NULL, *gid = NULL,
*sgnl = NULL, *exe = NULL, *comm = NULL, *cmdline = NULL,
- *filename = NULL, *coredump = NULL;
+ *filename = NULL, *truncated = NULL, *coredump = NULL;
const void *d;
size_t l;
usec_t t;
char buf[FORMAT_TIMESTAMP_MAX];
int r;
const char *present;
+ bool normal_coredump;
assert(file);
assert(j);
SD_JOURNAL_FOREACH_DATA(j, d, l) {
+ RETRIEVE(d, l, "MESSAGE_ID", mid);
RETRIEVE(d, l, "COREDUMP_PID", pid);
RETRIEVE(d, l, "COREDUMP_UID", uid);
RETRIEVE(d, l, "COREDUMP_GID", gid);
@@ -344,6 +375,7 @@ static int print_list(FILE* file, sd_journal *j, int had_legend) {
RETRIEVE(d, l, "COREDUMP_COMM", comm);
RETRIEVE(d, l, "COREDUMP_CMDLINE", cmdline);
RETRIEVE(d, l, "COREDUMP_FILENAME", filename);
+ RETRIEVE(d, l, "COREDUMP_TRUNCATED", truncated);
RETRIEVE(d, l, "COREDUMP", coredump);
}
@@ -359,15 +391,17 @@ static int print_list(FILE* file, sd_journal *j, int had_legend) {
format_timestamp(buf, sizeof(buf), t);
if (!had_legend && !arg_no_legend)
- fprintf(file, "%-*s %*s %*s %*s %*s %*s %s\n",
+ fprintf(file, "%-*s %*s %*s %*s %*s %-*s %s\n",
FORMAT_TIMESTAMP_WIDTH, "TIME",
6, "PID",
5, "UID",
5, "GID",
3, "SIG",
- 8, "COREFILE",
+ 9, "COREFILE",
"EXE");
+ normal_coredump = streq_ptr(mid, SD_MESSAGE_COREDUMP_STR);
+
if (filename)
if (access(filename, R_OK) == 0)
present = "present";
@@ -377,16 +411,21 @@ static int print_list(FILE* file, sd_journal *j, int had_legend) {
present = "error";
else if (coredump)
present = "journal";
- else
+ else if (normal_coredump)
present = "none";
+ else
+ present = "-";
+
+ if (STR_IN_SET(present, "present", "journal") && truncated && parse_boolean(truncated) > 0)
+ present = "truncated";
fprintf(file, "%-*s %*s %*s %*s %*s %-*s %s\n",
FORMAT_TIMESTAMP_WIDTH, buf,
6, strna(pid),
5, strna(uid),
5, strna(gid),
- 3, strna(sgnl),
- 8, present,
+ 3, normal_coredump ? strna(sgnl) : "-",
+ 9, present,
strna(exe ?: (comm ?: cmdline)));
return 0;
@@ -394,21 +433,23 @@ static int print_list(FILE* file, sd_journal *j, int had_legend) {
static int print_info(FILE *file, sd_journal *j, bool need_space) {
_cleanup_free_ char
- *pid = NULL, *uid = NULL, *gid = NULL,
+ *mid = NULL, *pid = NULL, *uid = NULL, *gid = NULL,
*sgnl = NULL, *exe = NULL, *comm = NULL, *cmdline = NULL,
*unit = NULL, *user_unit = NULL, *session = NULL,
*boot_id = NULL, *machine_id = NULL, *hostname = NULL,
*slice = NULL, *cgroup = NULL, *owner_uid = NULL,
*message = NULL, *timestamp = NULL, *filename = NULL,
- *coredump = NULL;
+ *truncated = NULL, *coredump = NULL;
const void *d;
size_t l;
+ bool normal_coredump;
int r;
assert(file);
assert(j);
SD_JOURNAL_FOREACH_DATA(j, d, l) {
+ RETRIEVE(d, l, "MESSAGE_ID", mid);
RETRIEVE(d, l, "COREDUMP_PID", pid);
RETRIEVE(d, l, "COREDUMP_UID", uid);
RETRIEVE(d, l, "COREDUMP_GID", gid);
@@ -424,6 +465,7 @@ static int print_info(FILE *file, sd_journal *j, bool need_space) {
RETRIEVE(d, l, "COREDUMP_CGROUP", cgroup);
RETRIEVE(d, l, "COREDUMP_TIMESTAMP", timestamp);
RETRIEVE(d, l, "COREDUMP_FILENAME", filename);
+ RETRIEVE(d, l, "COREDUMP_TRUNCATED", truncated);
RETRIEVE(d, l, "COREDUMP", coredump);
RETRIEVE(d, l, "_BOOT_ID", boot_id);
RETRIEVE(d, l, "_MACHINE_ID", machine_id);
@@ -434,6 +476,8 @@ static int print_info(FILE *file, sd_journal *j, bool need_space) {
if (need_space)
fputs("\n", file);
+ normal_coredump = streq_ptr(mid, SD_MESSAGE_COREDUMP_STR);
+
if (comm)
fprintf(file,
" PID: %s%s%s (%s)\n",
@@ -479,11 +523,12 @@ static int print_info(FILE *file, sd_journal *j, bool need_space) {
if (sgnl) {
int sig;
+ const char *name = normal_coredump ? "Signal" : "Reason";
- if (safe_atoi(sgnl, &sig) >= 0)
- fprintf(file, " Signal: %s (%s)\n", sgnl, signal_to_string(sig));
+ if (normal_coredump && safe_atoi(sgnl, &sig) >= 0)
+ fprintf(file, " %s: %s (%s)\n", name, sgnl, signal_to_string(sig));
else
- fprintf(file, " Signal: %s\n", sgnl);
+ fprintf(file, " %s: %s\n", name, sgnl);
}
if (timestamp) {
@@ -539,9 +584,24 @@ static int print_info(FILE *file, sd_journal *j, bool need_space) {
if (hostname)
fprintf(file, " Hostname: %s\n", hostname);
- if (filename)
- fprintf(file, " Storage: %s%s\n", filename,
- access(filename, R_OK) < 0 ? " (inaccessible)" : "");
+ if (filename) {
+ bool inacc, trunc;
+
+ inacc = access(filename, R_OK) < 0;
+ trunc = truncated && parse_boolean(truncated) > 0;
+
+ if (inacc || trunc)
+ fprintf(file, " Storage: %s%s (%s%s%s)%s\n",
+ ansi_highlight_red(),
+ filename,
+ inacc ? "inaccessible" : "",
+ inacc && trunc ? ", " : "",
+ trunc ? "truncated" : "",
+ ansi_normal());
+ else
+ fprintf(file, " Storage: %s\n", filename);
+ }
+
else if (coredump)
fprintf(file, " Storage: journal\n");
else
@@ -602,14 +662,57 @@ static int dump_list(sd_journal *j) {
return print_entry(j, 0);
} else {
- SD_JOURNAL_FOREACH(j) {
+ if (arg_since != USEC_INFINITY && !arg_reverse)
+ r = sd_journal_seek_realtime_usec(j, arg_since);
+ else if (arg_until != USEC_INFINITY && arg_reverse)
+ r = sd_journal_seek_realtime_usec(j, arg_until);
+ else if (arg_reverse)
+ r = sd_journal_seek_tail(j);
+ else
+ r = sd_journal_seek_head(j);
+ if (r < 0)
+ return log_error_errno(r, "Failed to seek to date: %m");
+
+ for (;;) {
+ if (!arg_reverse)
+ r = sd_journal_next(j);
+ else
+ r = sd_journal_previous(j);
+
+ if (r < 0)
+ return log_error_errno(r, "Failed to iterate through journal: %m");
+
+ if (r == 0)
+ break;
+
+ if (arg_until != USEC_INFINITY && !arg_reverse) {
+ usec_t usec;
+
+ r = sd_journal_get_realtime_usec(j, &usec);
+ if (r < 0)
+ return log_error_errno(r, "Failed to determine timestamp: %m");
+ if (usec > arg_until)
+ continue;
+ }
+
+ if (arg_since != USEC_INFINITY && arg_reverse) {
+ usec_t usec;
+
+ r = sd_journal_get_realtime_usec(j, &usec);
+ if (r < 0)
+ return log_error_errno(r, "Failed to determine timestamp: %m");
+ if (usec < arg_since)
+ continue;
+ }
+
r = print_entry(j, n_found++);
if (r < 0)
return r;
}
if (!arg_field && n_found <= 0) {
- log_notice("No coredumps found.");
+ if (!arg_quiet)
+ log_notice("No coredumps found.");
return -ESRCH;
}
}
@@ -667,7 +770,7 @@ static int save_core(sd_journal *j, FILE *file, char **path, bool *unlink_temp)
if (r < 0)
return log_error_errno(r, "Failed to acquire temporary directory path: %m");
- temp = strjoin(vt, "/coredump-XXXXXX", NULL);
+ temp = strjoin(vt, "/coredump-XXXXXX");
if (!temp)
return log_oom();
@@ -771,8 +874,8 @@ static int dump_core(sd_journal* j) {
return r;
r = sd_journal_previous(j);
- if (r > 0)
- log_warning("More than one entry matches, ignoring rest.");
+ if (r > 0 && !arg_quiet)
+ log_notice("More than one entry matches, ignoring rest.");
return 0;
}
@@ -821,6 +924,9 @@ static int run_gdb(sd_journal *j) {
if (r < 0)
return r;
+ /* Don't interfere with gdb and its handling of SIGINT. */
+ (void) ignore_signals(SIGINT, -1);
+
pid = fork();
if (pid < 0) {
r = log_error_errno(errno, "Failed to fork(): %m");
@@ -845,6 +951,8 @@ static int run_gdb(sd_journal *j) {
r = st.si_code == CLD_EXITED ? st.si_status : 255;
finish:
+ (void) default_signals(SIGINT, -1);
+
if (unlink_path) {
log_debug("Removed temporary file %s", path);
unlink(path);
@@ -853,24 +961,75 @@ finish:
return r;
}
+static int check_units_active(void) {
+ _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ int c = 0, r;
+ const char *id, *state, *substate;
+
+ if (arg_quiet)
+ return false;
+
+ r = sd_bus_default_system(&bus);
+ if (r < 0)
+ return log_error_errno(r, "Failed to acquire bus: %m");
+
+ r = sd_bus_message_new_method_call(
+ bus,
+ &m,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "ListUnitsByPatterns");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append_strv(m, NULL);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append_strv(m, STRV_MAKE("systemd-coredump@*.service"));
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_call(bus, m, SHORT_BUS_CALL_TIMEOUT_USEC, &error, &reply);
+ if (r < 0)
+ return log_error_errno(r, "Failed to check if any systemd-coredump@.service units are running: %s",
+ bus_error_message(&error, r));
+
+ r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ while ((r = sd_bus_message_read(
+ reply, "(ssssssouso)",
+ &id, NULL, NULL, &state, &substate,
+ NULL, NULL, NULL, NULL, NULL)) > 0) {
+ bool found = !STR_IN_SET(state, "inactive", "dead", "failed");
+ log_debug("Unit %s is %s/%s, %scounting it.", id, state, substate, found ? "" : "not ");
+ c += found;
+ }
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ return c;
+}
+
int main(int argc, char *argv[]) {
_cleanup_(sd_journal_closep) sd_journal*j = NULL;
- const char* match;
- Iterator it;
- int r = 0;
- _cleanup_set_free_free_ Set *matches = NULL;
+ int r = 0, units_active;
setlocale(LC_ALL, "");
log_parse_environment();
log_open();
- matches = new_matches();
- if (!matches) {
- r = -ENOMEM;
- goto end;
- }
-
- r = parse_argv(argc, argv, matches);
+ r = parse_argv(argc, argv);
if (r < 0)
goto end;
@@ -893,14 +1052,13 @@ int main(int argc, char *argv[]) {
}
}
- SET_FOREACH(match, matches, it) {
- r = sd_journal_add_match(j, match, strlen(match));
- if (r != 0) {
- log_error_errno(r, "Failed to add match '%s': %m",
- match);
- goto end;
- }
- }
+ r = journal_access_check_and_warn(j, arg_quiet);
+ if (r < 0)
+ goto end;
+
+ r = add_matches(j);
+ if (r < 0)
+ goto end;
if (_unlikely_(log_get_max_level() >= LOG_DEBUG)) {
_cleanup_free_ char *filter;
@@ -909,6 +1067,8 @@ int main(int argc, char *argv[]) {
log_debug("Journal filter: %s", filter);
}
+ units_active = check_units_active(); /* error is treated the same as 0 */
+
switch(arg_action) {
case ACTION_LIST:
@@ -929,6 +1089,11 @@ int main(int argc, char *argv[]) {
assert_not_reached("Shouldn't be here");
}
+ if (units_active > 0)
+ printf("%s-- Notice: %d systemd-coredump@.service %s, output may be incomplete.%s\n",
+ ansi_highlight_red(),
+ units_active, units_active == 1 ? "unit is running" : "units are running",
+ ansi_normal());
end:
pager_close();
diff --git a/src/coredump/stacktrace.c b/src/coredump/stacktrace.c
index cc4dad9465..778bee9b12 100644
--- a/src/coredump/stacktrace.c
+++ b/src/coredump/stacktrace.c
@@ -22,7 +22,7 @@
#include "alloc-util.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "macro.h"
#include "stacktrace.h"
#include "string-util.h"
diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
index e2dc4327fe..b58b6db7c9 100644
--- a/src/cryptsetup/cryptsetup-generator.c
+++ b/src/cryptsetup/cryptsetup-generator.c
@@ -86,7 +86,7 @@ static int create_disk(
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
- p = strjoin(arg_dest, "/", n, NULL);
+ p = strjoin(arg_dest, "/", n);
if (!p)
return log_oom();
@@ -102,18 +102,17 @@ static int create_disk(
if (!f)
return log_error_errno(errno, "Failed to create unit file %s: %m", p);
- fputs(
- "# Automatically generated by systemd-cryptsetup-generator\n\n"
- "[Unit]\n"
- "Description=Cryptography Setup for %I\n"
- "Documentation=man:crypttab(5) man:systemd-cryptsetup-generator(8) man:systemd-cryptsetup@.service(8)\n"
- "SourcePath=/etc/crypttab\n"
- "DefaultDependencies=no\n"
- "Conflicts=umount.target\n"
- "BindsTo=dev-mapper-%i.device\n"
- "IgnoreOnIsolate=true\n"
- "After=cryptsetup-pre.target\n",
- f);
+ fputs("# Automatically generated by systemd-cryptsetup-generator\n\n"
+ "[Unit]\n"
+ "Description=Cryptography Setup for %I\n"
+ "Documentation=man:crypttab(5) man:systemd-cryptsetup-generator(8) man:systemd-cryptsetup@.service(8)\n"
+ "SourcePath=/etc/crypttab\n"
+ "DefaultDependencies=no\n"
+ "Conflicts=umount.target\n"
+ "BindsTo=dev-mapper-%i.device\n"
+ "IgnoreOnIsolate=true\n"
+ "After=cryptsetup-pre.target\n",
+ f);
if (!nofail)
fprintf(f,
@@ -145,13 +144,17 @@ static int create_disk(
}
}
- if (is_device_path(u))
+ if (is_device_path(u)) {
fprintf(f,
"BindsTo=%s\n"
"After=%s\n"
"Before=umount.target\n",
d, d);
- else
+
+ if (swap)
+ fputs("Before=dev-mapper-%i.swap\n",
+ f);
+ } else
fprintf(f,
"RequiresMountsFor=%s\n",
u);
@@ -188,7 +191,7 @@ static int create_disk(
if (!noauto) {
- to = strjoin(arg_dest, "/", d, ".wants/", n, NULL);
+ to = strjoin(arg_dest, "/", d, ".wants/", n);
if (!to)
return log_oom();
@@ -198,9 +201,9 @@ static int create_disk(
free(to);
if (!nofail)
- to = strjoin(arg_dest, "/cryptsetup.target.requires/", n, NULL);
+ to = strjoin(arg_dest, "/cryptsetup.target.requires/", n);
else
- to = strjoin(arg_dest, "/cryptsetup.target.wants/", n, NULL);
+ to = strjoin(arg_dest, "/cryptsetup.target.wants/", n);
if (!to)
return log_oom();
@@ -210,7 +213,7 @@ static int create_disk(
}
free(to);
- to = strjoin(arg_dest, "/dev-mapper-", e, ".device.requires/", n, NULL);
+ to = strjoin(arg_dest, "/dev-mapper-", e, ".device.requires/", n);
if (!to)
return log_oom();
@@ -220,7 +223,7 @@ static int create_disk(
if (!noauto && !nofail) {
_cleanup_free_ char *dmname;
- dmname = strjoin("dev-mapper-", e, ".device", NULL);
+ dmname = strjoin("dev-mapper-", e, ".device");
if (!dmname)
return log_oom();
@@ -278,27 +281,30 @@ static crypto_device *get_crypto_device(const char *uuid) {
}
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
- int r;
- crypto_device *d;
_cleanup_free_ char *uuid = NULL, *uuid_value = NULL;
+ crypto_device *d;
+ int r;
- if (streq(key, "luks") && value) {
+ if (streq(key, "luks")) {
- r = parse_boolean(value);
+ r = value ? parse_boolean(value) : 1;
if (r < 0)
- log_warning("Failed to parse luks switch %s. Ignoring.", value);
+ log_warning("Failed to parse luks= kernel command line switch %s. Ignoring.", value);
else
arg_enabled = r;
- } else if (streq(key, "luks.crypttab") && value) {
+ } else if (streq(key, "luks.crypttab")) {
- r = parse_boolean(value);
+ r = value ? parse_boolean(value) : 1;
if (r < 0)
- log_warning("Failed to parse luks crypttab switch %s. Ignoring.", value);
+ log_warning("Failed to parse luks.crypttab= kernel command line switch %s. Ignoring.", value);
else
arg_read_crypttab = r;
- } else if (streq(key, "luks.uuid") && value) {
+ } else if (streq(key, "luks.uuid")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
d = get_crypto_device(startswith(value, "luks-") ? value+5 : value);
if (!d)
@@ -306,7 +312,10 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
d->create = arg_whitelist = true;
- } else if (streq(key, "luks.options") && value) {
+ } else if (streq(key, "luks.options")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
r = sscanf(value, "%m[0-9a-fA-F-]=%ms", &uuid, &uuid_value);
if (r == 2) {
@@ -314,13 +323,14 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
if (!d)
return log_oom();
- free(d->options);
- d->options = uuid_value;
- uuid_value = NULL;
+ free_and_replace(d->options, uuid_value);
} else if (free_and_strdup(&arg_default_options, value) < 0)
return log_oom();
- } else if (streq(key, "luks.key") && value) {
+ } else if (streq(key, "luks.key")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
r = sscanf(value, "%m[0-9a-fA-F-]=%ms", &uuid, &uuid_value);
if (r == 2) {
@@ -328,13 +338,14 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
if (!d)
return log_oom();
- free(d->keyfile);
- d->keyfile = uuid_value;
- uuid_value = NULL;
+ free_and_replace(d->keyfile, uuid_value);
} else if (free_and_strdup(&arg_default_keyfile, value) < 0)
return log_oom();
- } else if (streq(key, "luks.name") && value) {
+ } else if (streq(key, "luks.name")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
r = sscanf(value, "%m[0-9a-fA-F-]=%ms", &uuid, &uuid_value);
if (r == 2) {
@@ -349,7 +360,6 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
uuid_value = NULL;
} else
log_warning("Failed to parse luks name switch %s. Ignoring.", value);
-
}
return 0;
@@ -458,7 +468,7 @@ static int add_proc_cmdline_devices(void) {
}
int main(int argc, char *argv[]) {
- int r = EXIT_FAILURE;
+ int r;
if (argc > 1 && argc != 4) {
log_error("This program takes three or no arguments.");
@@ -475,32 +485,36 @@ int main(int argc, char *argv[]) {
umask(0022);
arg_disks = hashmap_new(&string_hash_ops);
- if (!arg_disks)
- goto cleanup;
+ if (!arg_disks) {
+ r = log_oom();
+ goto finish;
+ }
- r = parse_proc_cmdline(parse_proc_cmdline_item, NULL, true);
+ r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
if (r < 0) {
- log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
- r = EXIT_FAILURE;
+ log_warning_errno(r, "Failed to parse kernel command line: %m");
+ goto finish;
}
if (!arg_enabled) {
- r = EXIT_SUCCESS;
- goto cleanup;
+ r = 0;
+ goto finish;
}
- if (add_crypttab_devices() < 0)
- goto cleanup;
+ r = add_crypttab_devices();
+ if (r < 0)
+ goto finish;
- if (add_proc_cmdline_devices() < 0)
- goto cleanup;
+ r = add_proc_cmdline_devices();
+ if (r < 0)
+ goto finish;
- r = EXIT_SUCCESS;
+ r = 0;
-cleanup:
+finish:
free_arg_disks();
free(arg_default_options);
free(arg_default_keyfile);
- return r;
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
index ff5a3f36fb..91c653312a 100644
--- a/src/cryptsetup/cryptsetup.c
+++ b/src/cryptsetup/cryptsetup.c
@@ -69,26 +69,25 @@ static usec_t arg_timeout = 0;
*/
static int parse_one_option(const char *option) {
+ const char *val;
+ int r;
+
assert(option);
/* Handled outside of this tool */
if (STR_IN_SET(option, "noauto", "auto", "nofail", "fail"))
return 0;
- if (startswith(option, "cipher=")) {
- char *t;
-
- t = strdup(option+7);
- if (!t)
+ if ((val = startswith(option, "cipher="))) {
+ r = free_and_strdup(&arg_cipher, val);
+ if (r < 0)
return log_oom();
- free(arg_cipher);
- arg_cipher = t;
+ } else if ((val = startswith(option, "size="))) {
- } else if (startswith(option, "size=")) {
-
- if (safe_atou(option+5, &arg_key_size) < 0) {
- log_error("size= parse failure, ignoring.");
+ r = safe_atou(val, &arg_key_size);
+ if (r < 0) {
+ log_error_errno(r, "Failed to parse %s, ignoring: %m", option);
return 0;
}
@@ -99,68 +98,67 @@ static int parse_one_option(const char *option) {
arg_key_size /= 8;
- } else if (startswith(option, "key-slot=")) {
+ } else if ((val = startswith(option, "key-slot="))) {
arg_type = CRYPT_LUKS1;
- if (safe_atoi(option+9, &arg_key_slot) < 0) {
- log_error("key-slot= parse failure, ignoring.");
+ r = safe_atoi(val, &arg_key_slot);
+ if (r < 0) {
+ log_error_errno(r, "Failed to parse %s, ignoring: %m", option);
return 0;
}
- } else if (startswith(option, "tcrypt-keyfile=")) {
+ } else if ((val = startswith(option, "tcrypt-keyfile="))) {
arg_type = CRYPT_TCRYPT;
- if (path_is_absolute(option+15)) {
- if (strv_extend(&arg_tcrypt_keyfiles, option + 15) < 0)
+ if (path_is_absolute(val)) {
+ if (strv_extend(&arg_tcrypt_keyfiles, val) < 0)
return log_oom();
} else
- log_error("Key file path '%s' is not absolute. Ignoring.", option+15);
+ log_error("Key file path \"%s\" is not absolute. Ignoring.", val);
- } else if (startswith(option, "keyfile-size=")) {
+ } else if ((val = startswith(option, "keyfile-size="))) {
- if (safe_atou(option+13, &arg_keyfile_size) < 0) {
- log_error("keyfile-size= parse failure, ignoring.");
+ r = safe_atou(val, &arg_keyfile_size);
+ if (r < 0) {
+ log_error_errno(r, "Failed to parse %s, ignoring: %m", option);
return 0;
}
- } else if (startswith(option, "keyfile-offset=")) {
+ } else if ((val = startswith(option, "keyfile-offset="))) {
- if (safe_atou(option+15, &arg_keyfile_offset) < 0) {
- log_error("keyfile-offset= parse failure, ignoring.");
+ r = safe_atou(val, &arg_keyfile_offset);
+ if (r < 0) {
+ log_error_errno(r, "Failed to parse %s, ignoring: %m", option);
return 0;
}
- } else if (startswith(option, "hash=")) {
- char *t;
-
- t = strdup(option+5);
- if (!t)
+ } else if ((val = startswith(option, "hash="))) {
+ r = free_and_strdup(&arg_hash, val);
+ if (r < 0)
return log_oom();
- free(arg_hash);
- arg_hash = t;
-
- } else if (startswith(option, "header=")) {
+ } else if ((val = startswith(option, "header="))) {
arg_type = CRYPT_LUKS1;
- if (!path_is_absolute(option+7)) {
- log_error("Header path '%s' is not absolute, refusing.", option+7);
+ if (!path_is_absolute(val)) {
+ log_error("Header path \"%s\" is not absolute, refusing.", val);
return -EINVAL;
}
if (arg_header) {
- log_error("Duplicate header= options, refusing.");
+ log_error("Duplicate header= option, refusing.");
return -EINVAL;
}
- arg_header = strdup(option+7);
+ arg_header = strdup(val);
if (!arg_header)
return log_oom();
- } else if (startswith(option, "tries=")) {
+ } else if ((val = startswith(option, "tries="))) {
- if (safe_atou(option+6, &arg_tries) < 0) {
- log_error("tries= parse failure, ignoring.");
+ r = safe_atou(val, &arg_tries);
+ if (r < 0) {
+ log_error_errno(r, "Failed to parse %s, ignoring: %m", option);
return 0;
}
@@ -190,29 +188,28 @@ static int parse_one_option(const char *option) {
#endif
} else if (STR_IN_SET(option, "plain", "swap", "tmp"))
arg_type = CRYPT_PLAIN;
- else if (startswith(option, "timeout=")) {
+ else if ((val = startswith(option, "timeout="))) {
- if (parse_sec(option+8, &arg_timeout) < 0) {
- log_error("timeout= parse failure, ignoring.");
+ r = parse_sec(val, &arg_timeout);
+ if (r < 0) {
+ log_error_errno(r, "Failed to parse %s, ignoring: %m", option);
return 0;
}
- } else if (startswith(option, "offset=")) {
+ } else if ((val = startswith(option, "offset="))) {
- if (safe_atou64(option+7, &arg_offset) < 0) {
- log_error("offset= parse failure, refusing.");
- return -EINVAL;
- }
+ r = safe_atou64(val, &arg_offset);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse %s: %m", option);
- } else if (startswith(option, "skip=")) {
+ } else if ((val = startswith(option, "skip="))) {
- if (safe_atou64(option+5, &arg_skip) < 0) {
- log_error("skip= parse failure, refusing.");
- return -EINVAL;
- }
+ r = safe_atou64(val, &arg_skip);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse %s: %m", option);
} else if (!streq(option, "none"))
- log_error("Encountered unknown /etc/crypttab option '%s', ignoring.", option);
+ log_warning("Encountered unknown /etc/crypttab option '%s', ignoring.", option);
return 0;
}
@@ -313,7 +310,7 @@ static char *disk_mount_point(const char *label) {
if (asprintf(&device, "/dev/mapper/%s", label) < 0)
return NULL;
- f = setmntent("/etc/fstab", "r");
+ f = setmntent("/etc/fstab", "re");
if (!f)
return NULL;
@@ -596,17 +593,17 @@ static int help(void) {
}
int main(int argc, char *argv[]) {
- int r = EXIT_FAILURE;
struct crypt_device *cd = NULL;
+ int r = -EINVAL;
if (argc <= 1) {
- help();
- return EXIT_SUCCESS;
+ r = help();
+ goto finish;
}
if (argc < 3) {
log_error("This program requires at least two arguments.");
- return EXIT_FAILURE;
+ goto finish;
}
log_set_target(LOG_TARGET_AUTO);
@@ -617,7 +614,6 @@ int main(int argc, char *argv[]) {
if (streq(argv[1], "attach")) {
uint32_t flags = 0;
- int k;
unsigned tries;
usec_t until;
crypt_status_info status;
@@ -651,11 +647,11 @@ int main(int argc, char *argv[]) {
if (arg_header) {
log_debug("LUKS header: %s", arg_header);
- k = crypt_init(&cd, arg_header);
+ r = crypt_init(&cd, arg_header);
} else
- k = crypt_init(&cd, argv[3]);
- if (k) {
- log_error_errno(k, "crypt_init() failed: %m");
+ r = crypt_init(&cd, argv[3]);
+ if (r < 0) {
+ log_error_errno(r, "crypt_init() failed: %m");
goto finish;
}
@@ -664,7 +660,7 @@ int main(int argc, char *argv[]) {
status = crypt_status(cd, argv[2]);
if (status == CRYPT_ACTIVE || status == CRYPT_BUSY) {
log_info("Volume %s already active.", argv[2]);
- r = EXIT_SUCCESS;
+ r = 0;
goto finish;
}
@@ -694,29 +690,30 @@ int main(int argc, char *argv[]) {
_cleanup_strv_free_erase_ char **passwords = NULL;
if (!key_file) {
- k = get_password(argv[2], argv[3], until, tries == 0 && !arg_verify, &passwords);
- if (k == -EAGAIN)
+ r = get_password(argv[2], argv[3], until, tries == 0 && !arg_verify, &passwords);
+ if (r == -EAGAIN)
continue;
- else if (k < 0)
+ if (r < 0)
goto finish;
}
if (streq_ptr(arg_type, CRYPT_TCRYPT))
- k = attach_tcrypt(cd, argv[2], key_file, passwords, flags);
+ r = attach_tcrypt(cd, argv[2], key_file, passwords, flags);
else
- k = attach_luks_or_plain(cd,
+ r = attach_luks_or_plain(cd,
argv[2],
key_file,
arg_header ? argv[3] : NULL,
passwords,
flags);
- if (k >= 0)
+ if (r >= 0)
break;
- else if (k == -EAGAIN) {
+ if (r == -EAGAIN) {
key_file = NULL;
continue;
- } else if (k != -EPERM) {
- log_error_errno(k, "Failed to activate: %m");
+ }
+ if (r != -EPERM) {
+ log_error_errno(r, "Failed to activate: %m");
goto finish;
}
@@ -725,28 +722,28 @@ int main(int argc, char *argv[]) {
if (arg_tries != 0 && tries >= arg_tries) {
log_error("Too many attempts; giving up.");
- r = EXIT_FAILURE;
+ r = -EPERM;
goto finish;
}
} else if (streq(argv[1], "detach")) {
- int k;
- k = crypt_init_by_name(&cd, argv[2]);
- if (k == -ENODEV) {
+ r = crypt_init_by_name(&cd, argv[2]);
+ if (r == -ENODEV) {
log_info("Volume %s already inactive.", argv[2]);
- r = EXIT_SUCCESS;
+ r = 0;
goto finish;
- } else if (k) {
- log_error_errno(k, "crypt_init_by_name() failed: %m");
+ }
+ if (r < 0) {
+ log_error_errno(r, "crypt_init_by_name() failed: %m");
goto finish;
}
crypt_set_log_callback(cd, log_glue, NULL);
- k = crypt_deactivate(cd, argv[2]);
- if (k < 0) {
- log_error_errno(k, "Failed to deactivate: %m");
+ r = crypt_deactivate(cd, argv[2]);
+ if (r < 0) {
+ log_error_errno(r, "Failed to deactivate: %m");
goto finish;
}
@@ -755,10 +752,9 @@ int main(int argc, char *argv[]) {
goto finish;
}
- r = EXIT_SUCCESS;
+ r = 0;
finish:
-
if (cd)
crypt_free(cd);
@@ -767,5 +763,5 @@ finish:
free(arg_header);
strv_free(arg_tcrypt_keyfiles);
- return r;
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/src/debug-generator/debug-generator.c b/src/debug-generator/debug-generator.c
index 7f11ec724d..1d8bc71e57 100644
--- a/src/debug-generator/debug-generator.c
+++ b/src/debug-generator/debug-generator.c
@@ -39,56 +39,53 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
assert(key);
if (streq(key, "systemd.mask")) {
+ char *n;
- if (!value)
- log_error("Missing argument for systemd.mask= kernel command line parameter.");
- else {
- char *n;
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
- r = unit_name_mangle(value, UNIT_NAME_NOGLOB, &n);
- if (r < 0)
- return log_error_errno(r, "Failed to glob unit name: %m");
+ r = unit_name_mangle(value, UNIT_NAME_NOGLOB, &n);
+ if (r < 0)
+ return log_error_errno(r, "Failed to glob unit name: %m");
- r = strv_consume(&arg_mask, n);
- if (r < 0)
- return log_oom();
- }
+ r = strv_consume(&arg_mask, n);
+ if (r < 0)
+ return log_oom();
} else if (streq(key, "systemd.wants")) {
+ char *n;
- if (!value)
- log_error("Missing argument for systemd.want= kernel command line parameter.");
- else {
- char *n;
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
- r = unit_name_mangle(value, UNIT_NAME_NOGLOB, &n);
- if (r < 0)
- return log_error_errno(r, "Failed to glob unit name: %m");
+ r = unit_name_mangle(value, UNIT_NAME_NOGLOB, &n);
+ if (r < 0)
+ return log_error_errno(r, "Failed to glob unit name: %m");
- r = strv_consume(&arg_wants, n);
- if (r < 0)
- return log_oom();
- }
+ r = strv_consume(&arg_wants, n);
+ if (r < 0)
+ return log_oom();
- } else if (streq(key, "systemd.debug-shell")) {
+ } else if (proc_cmdline_key_streq(key, "systemd.debug_shell")) {
if (value) {
r = parse_boolean(value);
if (r < 0)
- log_error("Failed to parse systemd.debug-shell= argument '%s', ignoring.", value);
+ log_error("Failed to parse systemd.debug_shell= argument '%s', ignoring.", value);
else
arg_debug_shell = r;
} else
arg_debug_shell = true;
+
} else if (streq(key, "systemd.unit")) {
- if (!value)
- log_error("Missing argument for systemd.unit= kernel command line parameter.");
- else {
- r = free_and_strdup(&arg_default_unit, value);
- if (r < 0)
- return log_error_errno(r, "Failed to set default unit %s: %m", value);
- }
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
+ r = free_and_strdup(&arg_default_unit, value);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set default unit %s: %m", value);
+
} else if (!value) {
const char *target;
@@ -113,7 +110,7 @@ static int generate_mask_symlinks(void) {
STRV_FOREACH(u, arg_mask) {
_cleanup_free_ char *p = NULL;
- p = strjoin(arg_dest, "/", *u, NULL);
+ p = strjoin(arg_dest, "/", *u);
if (!p)
return log_oom();
@@ -135,8 +132,9 @@ static int generate_wants_symlinks(void) {
STRV_FOREACH(u, arg_wants) {
_cleanup_free_ char *p = NULL, *f = NULL;
+ const char *target = arg_default_unit ?: SPECIAL_DEFAULT_TARGET;
- p = strjoin(arg_dest, "/", arg_default_unit, ".wants/", *u, NULL);
+ p = strjoin(arg_dest, "/", target, ".wants/", *u);
if (!p)
return log_oom();
@@ -172,13 +170,7 @@ int main(int argc, char *argv[]) {
umask(0022);
- r = free_and_strdup(&arg_default_unit, SPECIAL_DEFAULT_TARGET);
- if (r < 0) {
- log_error_errno(r, "Failed to set default unit %s: %m", SPECIAL_DEFAULT_TARGET);
- goto finish;
- }
-
- r = parse_proc_cmdline(parse_proc_cmdline_item, NULL, false);
+ r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
if (r < 0)
log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
@@ -197,6 +189,7 @@ int main(int argc, char *argv[]) {
r = q;
finish:
- return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+ arg_default_unit = mfree(arg_default_unit);
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/src/delta/delta.c b/src/delta/delta.c
index f32744def2..9a44b15da7 100644
--- a/src/delta/delta.c
+++ b/src/delta/delta.c
@@ -87,14 +87,15 @@ static enum {
static int equivalent(const char *a, const char *b) {
_cleanup_free_ char *x = NULL, *y = NULL;
+ int r;
- x = canonicalize_file_name(a);
- if (!x)
- return -errno;
+ r = chase_symlinks(a, NULL, 0, &x);
+ if (r < 0)
+ return r;
- y = canonicalize_file_name(b);
- if (!y)
- return -errno;
+ r = chase_symlinks(b, NULL, 0, &y);
+ if (r < 0)
+ return r;
return path_equal(x, y);
}
@@ -214,7 +215,7 @@ static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const
assert(!endswith(drop, "/"));
- path = strjoin(toppath, "/", drop, NULL);
+ path = strjoin(toppath, "/", drop);
if (!path)
return -ENOMEM;
@@ -242,7 +243,7 @@ static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const
if (!endswith(*file, ".conf"))
continue;
- p = strjoin(path, "/", *file, NULL);
+ p = strjoin(path, "/", *file);
if (!p)
return -ENOMEM;
d = p + strlen(toppath) + 1;
@@ -296,6 +297,7 @@ static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const
static int enumerate_dir(Hashmap *top, Hashmap *bottom, Hashmap *drops, const char *path, bool dropins) {
_cleanup_closedir_ DIR *d;
+ struct dirent *de;
assert(top);
assert(bottom);
@@ -312,16 +314,10 @@ static int enumerate_dir(Hashmap *top, Hashmap *bottom, Hashmap *drops, const ch
return log_error_errno(errno, "Failed to open %s: %m", path);
}
- for (;;) {
- struct dirent *de;
+ FOREACH_DIRENT_ALL(de, d, return -errno) {
int k;
char *p;
- errno = 0;
- de = readdir(d);
- if (!de)
- return -errno;
-
dirent_ensure_type(d, de);
if (dropins && de->d_type == DT_DIR && endswith(de->d_name, ".d"))
@@ -330,7 +326,7 @@ static int enumerate_dir(Hashmap *top, Hashmap *bottom, Hashmap *drops, const ch
if (!dirent_is_file(de))
continue;
- p = strjoin(path, "/", de->d_name, NULL);
+ p = strjoin(path, "/", de->d_name);
if (!p)
return -ENOMEM;
@@ -353,6 +349,22 @@ static int enumerate_dir(Hashmap *top, Hashmap *bottom, Hashmap *drops, const ch
return k;
}
}
+ return 0;
+}
+
+static int should_skip_prefix(const char* p) {
+#ifdef HAVE_SPLIT_USR
+ int r;
+ _cleanup_free_ char *target = NULL;
+
+ r = chase_symlinks(p, NULL, 0, &target);
+ if (r < 0)
+ return r;
+
+ return !streq(p, target) && nulstr_contains(prefixes, target);
+#else
+ return 0;
+#endif
}
static int process_suffix(const char *suffix, const char *onlyprefix) {
@@ -382,8 +394,17 @@ static int process_suffix(const char *suffix, const char *onlyprefix) {
NULSTR_FOREACH(p, prefixes) {
_cleanup_free_ char *t = NULL;
+ int skip;
+
+ skip = should_skip_prefix(p);
+ if (skip < 0) {
+ r = skip;
+ goto finish;
+ }
+ if (skip)
+ continue;
- t = strjoin(p, "/", suffix, NULL);
+ t = strjoin(p, "/", suffix);
if (!t) {
r = -ENOMEM;
goto finish;
@@ -459,6 +480,13 @@ static int process_suffix_chop(const char *arg) {
/* Strip prefix from the suffix */
NULSTR_FOREACH(p, prefixes) {
const char *suffix;
+ int skip;
+
+ skip = should_skip_prefix(p);
+ if (skip < 0)
+ return skip;
+ if (skip)
+ continue;
suffix = startswith(arg, p);
if (suffix) {
diff --git a/src/dissect/Makefile b/src/dissect/Makefile
new file mode 120000
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/dissect/Makefile
@@ -0,0 +1 @@
+../Makefile \ No newline at end of file
diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c
new file mode 100644
index 0000000000..06564e94b1
--- /dev/null
+++ b/src/dissect/dissect.c
@@ -0,0 +1,294 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <getopt.h>
+
+#include "architecture.h"
+#include "dissect-image.h"
+#include "hexdecoct.h"
+#include "log.h"
+#include "loop-util.h"
+#include "string-util.h"
+#include "util.h"
+
+static enum {
+ ACTION_DISSECT,
+ ACTION_MOUNT,
+} arg_action = ACTION_DISSECT;
+static const char *arg_image = NULL;
+static const char *arg_path = NULL;
+static DissectImageFlags arg_flags = DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_DISCARD_ON_LOOP;
+static void *arg_root_hash = NULL;
+static size_t arg_root_hash_size = 0;
+
+static void help(void) {
+ printf("%s [OPTIONS...] IMAGE\n"
+ "%s [OPTIONS...] --mount IMAGE PATH\n"
+ "Dissect a file system OS image.\n\n"
+ " -h --help Show this help\n"
+ " --version Show package version\n"
+ " -m --mount Mount the image to the specified directory\n"
+ " -r --read-only Mount read-only\n"
+ " --discard=MODE Choose 'discard' mode (disabled, loop, all, crypto)\n"
+ " --root-hash=HASH Specify root hash for verity\n",
+ program_invocation_short_name,
+ program_invocation_short_name);
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+ enum {
+ ARG_VERSION = 0x100,
+ ARG_DISCARD,
+ ARG_ROOT_HASH,
+ };
+
+ static const struct option options[] = {
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, ARG_VERSION },
+ { "mount", no_argument, NULL, 'm' },
+ { "read-only", no_argument, NULL, 'r' },
+ { "discard", required_argument, NULL, ARG_DISCARD },
+ { "root-hash", required_argument, NULL, ARG_ROOT_HASH },
+ {}
+ };
+
+ int c, r;
+
+ assert(argc >= 0);
+ assert(argv);
+
+ while ((c = getopt_long(argc, argv, "hmr", options, NULL)) >= 0) {
+
+ switch (c) {
+
+ case 'h':
+ help();
+ return 0;
+
+ case ARG_VERSION:
+ return version();
+
+ case 'm':
+ arg_action = ACTION_MOUNT;
+ break;
+
+ case 'r':
+ arg_flags |= DISSECT_IMAGE_READ_ONLY;
+ break;
+
+ case ARG_DISCARD: {
+ DissectImageFlags flags;
+
+ if (streq(optarg, "disabled"))
+ flags = 0;
+ else if (streq(optarg, "loop"))
+ flags = DISSECT_IMAGE_DISCARD_ON_LOOP;
+ else if (streq(optarg, "all"))
+ flags = DISSECT_IMAGE_DISCARD_ON_LOOP | DISSECT_IMAGE_DISCARD;
+ else if (streq(optarg, "crypt"))
+ flags = DISSECT_IMAGE_DISCARD_ANY;
+ else {
+ log_error("Unknown --discard= parameter: %s", optarg);
+ return -EINVAL;
+ }
+ arg_flags = (arg_flags & ~DISSECT_IMAGE_DISCARD_ANY) | flags;
+
+ break;
+ }
+
+ case ARG_ROOT_HASH: {
+ void *p;
+ size_t l;
+
+ r = unhexmem(optarg, strlen(optarg), &p, &l);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse root hash: %s", optarg);
+ if (l < sizeof(sd_id128_t)) {
+ log_error("Root hash must be at least 128bit long: %s", optarg);
+ free(p);
+ return -EINVAL;
+ }
+
+ free(arg_root_hash);
+ arg_root_hash = p;
+ arg_root_hash_size = l;
+ break;
+ }
+
+ case '?':
+ return -EINVAL;
+
+ default:
+ assert_not_reached("Unhandled option");
+ }
+
+ }
+
+ switch (arg_action) {
+
+ case ACTION_DISSECT:
+ if (optind + 1 != argc) {
+ log_error("Expected a file path as only argument.");
+ return -EINVAL;
+ }
+
+ arg_image = argv[optind];
+ arg_flags |= DISSECT_IMAGE_READ_ONLY;
+ break;
+
+ case ACTION_MOUNT:
+ if (optind + 2 != argc) {
+ log_error("Expected a file path and mount point path as only arguments.");
+ return -EINVAL;
+ }
+
+ arg_image = argv[optind];
+ arg_path = argv[optind + 1];
+ break;
+
+ default:
+ assert_not_reached("Unknown action.");
+ }
+
+ return 1;
+}
+
+int main(int argc, char *argv[]) {
+ _cleanup_(loop_device_unrefp) LoopDevice *d = NULL;
+ _cleanup_(decrypted_image_unrefp) DecryptedImage *di = NULL;
+ _cleanup_(dissected_image_unrefp) DissectedImage *m = NULL;
+ int r;
+
+ log_parse_environment();
+ log_open();
+
+ r = parse_argv(argc, argv);
+ if (r <= 0)
+ goto finish;
+
+ r = loop_device_make_by_path(arg_image, (arg_flags & DISSECT_IMAGE_READ_ONLY) ? O_RDONLY : O_RDWR, &d);
+ if (r < 0) {
+ log_error_errno(r, "Failed to set up loopback device: %m");
+ goto finish;
+ }
+
+ if (!arg_root_hash) {
+ r = root_hash_load(arg_image, &arg_root_hash, &arg_root_hash_size);
+ if (r < 0) {
+ log_error_errno(r, "Failed to read root hash file for %s: %m", arg_image);
+ goto finish;
+ }
+ }
+
+ r = dissect_image(d->fd, arg_root_hash, arg_root_hash_size, arg_flags, &m);
+ if (r == -ENOPKG) {
+ log_error_errno(r, "Couldn't identify a suitable partition table or file system in %s.", arg_image);
+ goto finish;
+ }
+ if (r == -EADDRNOTAVAIL) {
+ log_error_errno(r, "No root partition for specified root hash found in %s.", arg_image);
+ goto finish;
+ }
+ if (r == -ENOTUNIQ) {
+ log_error_errno(r, "Multiple suitable root partitions found in image %s.", arg_image);
+ goto finish;
+ }
+ if (r == -ENXIO) {
+ log_error_errno(r, "No suitable root partition found in image %s.", arg_image);
+ goto finish;
+ }
+ if (r < 0) {
+ log_error_errno(r, "Failed to dissect image: %m");
+ goto finish;
+ }
+
+ switch (arg_action) {
+
+ case ACTION_DISSECT: {
+ unsigned i;
+
+ for (i = 0; i < _PARTITION_DESIGNATOR_MAX; i++) {
+ DissectedPartition *p = m->partitions + i;
+ int k;
+
+ if (!p->found)
+ continue;
+
+ printf("Found %s '%s' partition",
+ p->rw ? "writable" : "read-only",
+ partition_designator_to_string(i));
+
+ if (!sd_id128_is_null(p->uuid))
+ printf(" (UUID " SD_ID128_FORMAT_STR ")", SD_ID128_FORMAT_VAL(p->uuid));
+
+ if (p->fstype)
+ printf(" of type %s", p->fstype);
+
+ if (p->architecture != _ARCHITECTURE_INVALID)
+ printf(" for %s", architecture_to_string(p->architecture));
+
+ k = PARTITION_VERITY_OF(i);
+ if (k >= 0)
+ printf(" %s verity", m->partitions[k].found ? "with" : "without");
+
+ if (p->partno >= 0)
+ printf(" on partition #%i", p->partno);
+
+ if (p->node)
+ printf(" (%s)", p->node);
+
+ putchar('\n');
+ }
+
+ break;
+ }
+
+ case ACTION_MOUNT:
+ r = dissected_image_decrypt_interactively(m, NULL, arg_root_hash, arg_root_hash_size, arg_flags, &di);
+ if (r < 0)
+ goto finish;
+
+ r = dissected_image_mount(m, arg_path, arg_flags);
+ if (r < 0) {
+ log_error_errno(r, "Failed to mount image: %m");
+ goto finish;
+ }
+
+ if (di) {
+ r = decrypted_image_relinquish(di);
+ if (r < 0) {
+ log_error_errno(r, "Failed to relinquish DM devices: %m");
+ goto finish;
+ }
+ }
+
+ loop_device_relinquish(d);
+ break;
+
+ default:
+ assert_not_reached("Unknown action.");
+ }
+
+finish:
+ free(arg_root_hash);
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/environment-d-generator/Makefile b/src/environment-d-generator/Makefile
new file mode 120000
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/environment-d-generator/Makefile
@@ -0,0 +1 @@
+../Makefile \ No newline at end of file
diff --git a/src/environment-d-generator/environment-d-generator.c b/src/environment-d-generator/environment-d-generator.c
new file mode 100644
index 0000000000..2d4c4235e4
--- /dev/null
+++ b/src/environment-d-generator/environment-d-generator.c
@@ -0,0 +1,107 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "sd-path.h"
+
+#include "conf-files.h"
+#include "def.h"
+#include "escape.h"
+#include "fileio.h"
+#include "log.h"
+#include "path-lookup.h"
+
+static int environment_dirs(char ***ret) {
+ _cleanup_strv_free_ char **dirs = NULL;
+ _cleanup_free_ char *c = NULL;
+ int r;
+
+ dirs = strv_split_nulstr(CONF_PATHS_NULSTR("environment.d"));
+ if (!dirs)
+ return -ENOMEM;
+
+ /* ~/.config/systemd/environment.d */
+ r = sd_path_home(SD_PATH_USER_CONFIGURATION, "environment.d", &c);
+ if (r < 0)
+ return r;
+
+ r = strv_extend_front(&dirs, c);
+ if (r < 0)
+ return r;
+
+ *ret = dirs;
+ dirs = NULL;
+ return 0;
+}
+
+static int load_and_print(void) {
+ _cleanup_strv_free_ char **dirs = NULL, **files = NULL, **env = NULL;
+ char **i;
+ int r;
+
+ r = environment_dirs(&dirs);
+ if (r < 0)
+ return r;
+
+ r = conf_files_list_strv(&files, ".conf", NULL, (const char **) dirs);
+ if (r < 0)
+ return r;
+
+ /* This will mutate the existing environment, based on the presumption
+ * that in case of failure, a partial update is better than none. */
+
+ STRV_FOREACH(i, files) {
+ r = merge_env_file(&env, NULL, *i);
+ if (r == -ENOMEM)
+ return r;
+ }
+
+ STRV_FOREACH(i, env) {
+ char *t;
+ _cleanup_free_ char *q = NULL;
+
+ t = strchr(*i, '=');
+ assert(t);
+
+ q = shell_maybe_quote(t + 1);
+ if (!q)
+ return log_oom();
+
+ printf("%.*s=%s\n", (int) (t - *i), *i, q);
+ }
+
+ return 0;
+}
+
+int main(int argc, char *argv[]) {
+ int r;
+
+ log_parse_environment();
+ log_open();
+
+ if (argc > 1) {
+ log_error("This program takes no arguments.");
+ return EXIT_FAILURE;
+ }
+
+ r = load_and_print();
+ if (r < 0)
+ log_error_errno(r, "Failed to load environment.d: %m");
+
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/escape/escape.c b/src/escape/escape.c
index 9f39049577..af98c98e40 100644
--- a/src/escape/escape.c
+++ b/src/escape/escape.c
@@ -191,7 +191,7 @@ int main(int argc, char *argv[]) {
} else if (arg_suffix) {
char *x;
- x = strjoin(e, ".", arg_suffix, NULL);
+ x = strjoin(e, ".", arg_suffix);
if (!x) {
r = log_oom();
goto finish;
diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c
index 83a21eaf0e..f7574223ae 100644
--- a/src/firstboot/firstboot.c
+++ b/src/firstboot/firstboot.c
@@ -33,6 +33,7 @@
#include "mkdir.h"
#include "parse-util.h"
#include "path-util.h"
+#include "proc-cmdline.h"
#include "random-util.h"
#include "string-util.h"
#include "strv.h"
@@ -251,7 +252,7 @@ static int process_locale(void) {
if (arg_copy_locale && arg_root) {
mkdir_parents(etc_localeconf, 0755);
- r = copy_file("/etc/locale.conf", etc_localeconf, 0, 0644, 0);
+ r = copy_file("/etc/locale.conf", etc_localeconf, 0, 0644, 0, COPY_REFLINK);
if (r != -ENOENT) {
if (r < 0)
return log_error_errno(r, "Failed to copy %s: %m", etc_localeconf);
@@ -825,6 +826,7 @@ static int parse_argv(int argc, char *argv[]) {
}
int main(int argc, char *argv[]) {
+ bool enabled;
int r;
r = parse_argv(argc, argv);
@@ -837,6 +839,16 @@ int main(int argc, char *argv[]) {
umask(0022);
+ r = proc_cmdline_get_bool("systemd.firstboot", &enabled);
+ if (r < 0) {
+ log_error_errno(r, "Failed to parse systemd.firstboot= kernel command line argument, ignoring.");
+ goto finish;
+ }
+ if (r > 0 && !enabled) {
+ r = 0; /* disabled */
+ goto finish;
+ }
+
r = process_locale();
if (r < 0)
goto finish;
diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c
index be25c6a2b2..2100681e17 100644
--- a/src/fsck/fsck.c
+++ b/src/fsck/fsck.c
@@ -99,7 +99,10 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
assert(key);
- if (streq(key, "fsck.mode") && value) {
+ if (streq(key, "fsck.mode")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
if (streq(value, "auto"))
arg_force = arg_skip = false;
@@ -110,7 +113,10 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
else
log_warning("Invalid fsck.mode= parameter '%s'. Ignoring.", value);
- } else if (streq(key, "fsck.repair") && value) {
+ } else if (streq(key, "fsck.repair")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
if (streq(value, "preen"))
arg_repair = "-a";
@@ -293,7 +299,7 @@ int main(int argc, char *argv[]) {
umask(0022);
- r = parse_proc_cmdline(parse_proc_cmdline_item, NULL, true);
+ r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
if (r < 0)
log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index e77bd71a52..50d350fce8 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -42,16 +42,48 @@
#include "unit-name.h"
#include "util.h"
#include "virt.h"
+#include "volatile-util.h"
static const char *arg_dest = "/tmp";
+static const char *arg_dest_late = "/tmp";
static bool arg_fstab_enabled = true;
static char *arg_root_what = NULL;
static char *arg_root_fstype = NULL;
static char *arg_root_options = NULL;
+static char *arg_root_hash = NULL;
static int arg_root_rw = -1;
static char *arg_usr_what = NULL;
static char *arg_usr_fstype = NULL;
static char *arg_usr_options = NULL;
+static VolatileMode arg_volatile_mode = _VOLATILE_MODE_INVALID;
+
+static int write_options(FILE *f, const char *options) {
+ _cleanup_free_ char *o = NULL;
+
+ if (isempty(options))
+ return 0;
+
+ if (streq(options, "defaults"))
+ return 0;
+
+ o = strreplace(options, "%", "%%");
+ if (!o)
+ return log_oom();
+
+ fprintf(f, "Options=%s\n", o);
+ return 1;
+}
+
+static int write_what(FILE *f, const char *what) {
+ _cleanup_free_ char *w = NULL;
+
+ w = strreplace(what, "%", "%%");
+ if (!w)
+ return log_oom();
+
+ fprintf(f, "What=%s\n", w);
+ return 1;
+}
static int add_swap(
const char *what,
@@ -80,7 +112,7 @@ static int add_swap(
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
- unit = strjoin(arg_dest, "/", name, NULL);
+ unit = strjoin(arg_dest, "/", name);
if (!unit)
return log_oom();
@@ -92,17 +124,19 @@ static int add_swap(
"Failed to create unit file %s: %m",
unit);
- fprintf(f,
- "# Automatically generated by systemd-fstab-generator\n\n"
- "[Unit]\n"
- "SourcePath=/etc/fstab\n"
- "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n\n"
- "[Swap]\n"
- "What=%s\n",
- what);
+ fputs("# Automatically generated by systemd-fstab-generator\n\n"
+ "[Unit]\n"
+ "SourcePath=/etc/fstab\n"
+ "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n\n"
+ "[Swap]\n", f);
- if (!isempty(me->mnt_opts) && !streq(me->mnt_opts, "defaults"))
- fprintf(f, "Options=%s\n", me->mnt_opts);
+ r = write_what(f, what);
+ if (r < 0)
+ return r;
+
+ r = write_options(f, me->mnt_opts);
+ if (r < 0)
+ return r;
r = fflush_and_check(f);
if (r < 0)
@@ -141,13 +175,14 @@ static bool mount_in_initrd(struct mntent *me) {
streq(me->mnt_dir, "/usr");
}
-static int write_idle_timeout(FILE *f, const char *where, const char *opts) {
+static int write_timeout(FILE *f, const char *where, const char *opts,
+ const char *filter, const char *variable) {
_cleanup_free_ char *timeout = NULL;
char timespan[FORMAT_TIMESPAN_MAX];
usec_t u;
int r;
- r = fstab_filter_options(opts, "x-systemd.idle-timeout\0", NULL, &timeout, NULL);
+ r = fstab_filter_options(opts, filter, NULL, &timeout, NULL);
if (r < 0)
return log_warning_errno(r, "Failed to parse options: %m");
if (r == 0)
@@ -159,12 +194,23 @@ static int write_idle_timeout(FILE *f, const char *where, const char *opts) {
return 0;
}
- fprintf(f, "TimeoutIdleSec=%s\n", format_timespan(timespan, sizeof(timespan), u, 0));
+ fprintf(f, "%s=%s\n", variable, format_timespan(timespan, sizeof(timespan), u, 0));
return 0;
}
-static int write_requires_after(FILE *f, const char *opts) {
+static int write_idle_timeout(FILE *f, const char *where, const char *opts) {
+ return write_timeout(f, where, opts,
+ "x-systemd.idle-timeout\0", "TimeoutIdleSec");
+}
+
+static int write_mount_timeout(FILE *f, const char *where, const char *opts) {
+ return write_timeout(f, where, opts,
+ "x-systemd.mount-timeout\0", "TimeoutSec");
+}
+
+static int write_dependency(FILE *f, const char *opts,
+ const char *filter, const char *format) {
_cleanup_strv_free_ char **names = NULL, **units = NULL;
_cleanup_free_ char *res = NULL;
char **s;
@@ -173,7 +219,7 @@ static int write_requires_after(FILE *f, const char *opts) {
assert(f);
assert(opts);
- r = fstab_extract_values(opts, "x-systemd.requires", &names);
+ r = fstab_extract_values(opts, filter, &names);
if (r < 0)
return log_warning_errno(r, "Failed to parse options: %m");
if (r == 0)
@@ -194,12 +240,29 @@ static int write_requires_after(FILE *f, const char *opts) {
res = strv_join(units, " ");
if (!res)
return log_oom();
- fprintf(f, "After=%1$s\nRequires=%1$s\n", res);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+ fprintf(f, format, res);
+#pragma GCC diagnostic pop
}
return 0;
}
+static int write_after(FILE *f, const char *opts) {
+ return write_dependency(f, opts, "x-systemd.after", "After=%1$s\n");
+}
+
+static int write_requires_after(FILE *f, const char *opts) {
+ return write_dependency(f, opts,
+ "x-systemd.requires", "After=%1$s\nRequires=%1$s\n");
+}
+
+static int write_before(FILE *f, const char *opts) {
+ return write_dependency(f, opts,
+ "x-systemd.before", "Before=%1$s\n");
+}
+
static int write_requires_mounts_for(FILE *f, const char *opts) {
_cleanup_strv_free_ char **paths = NULL;
_cleanup_free_ char *res = NULL;
@@ -224,6 +287,7 @@ static int write_requires_mounts_for(FILE *f, const char *opts) {
}
static int add_mount(
+ const char *dest,
const char *what,
const char *where,
const char *fstype,
@@ -275,7 +339,7 @@ static int add_mount(
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
- unit = strjoin(arg_dest, "/", name, NULL);
+ unit = strjoin(dest, "/", name);
if (!unit)
return log_oom();
@@ -294,20 +358,26 @@ static int add_mount(
"Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n",
source);
- if (!noauto && !nofail && !automount)
+ if (!nofail && !automount)
fprintf(f, "Before=%s\n", post);
if (!automount && opts) {
+ r = write_after(f, opts);
+ if (r < 0)
+ return r;
r = write_requires_after(f, opts);
if (r < 0)
return r;
+ r = write_before(f, opts);
+ if (r < 0)
+ return r;
r = write_requires_mounts_for(f, opts);
if (r < 0)
return r;
}
if (passno != 0) {
- r = generator_write_fsck_deps(f, arg_dest, what, where, fstype);
+ r = generator_write_fsck_deps(f, dest, what, where, fstype);
if (r < 0)
return r;
}
@@ -315,27 +385,34 @@ static int add_mount(
fprintf(f,
"\n"
"[Mount]\n"
- "What=%s\n"
"Where=%s\n",
- what,
where);
+ r = write_what(f, what);
+ if (r < 0)
+ return r;
+
if (!isempty(fstype) && !streq(fstype, "auto"))
fprintf(f, "Type=%s\n", fstype);
- r = generator_write_timeouts(arg_dest, what, where, opts, &filtered);
+ r = generator_write_timeouts(dest, what, where, opts, &filtered);
+ if (r < 0)
+ return r;
+
+ r = write_mount_timeout(f, where, opts);
if (r < 0)
return r;
- if (!isempty(filtered) && !streq(filtered, "defaults"))
- fprintf(f, "Options=%s\n", filtered);
+ r = write_options(f, filtered);
+ if (r < 0)
+ return r;
r = fflush_and_check(f);
if (r < 0)
return log_error_errno(r, "Failed to write unit file %s: %m", unit);
if (!noauto && !automount) {
- lnk = strjoin(arg_dest, "/", post, nofail ? ".wants/" : ".requires/", name, NULL);
+ lnk = strjoin(dest, "/", post, nofail ? ".wants/" : ".requires/", name);
if (!lnk)
return log_oom();
@@ -349,7 +426,7 @@ static int add_mount(
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
- automount_unit = strjoin(arg_dest, "/", automount_name, NULL);
+ automount_unit = strjoin(dest, "/", automount_name);
if (!automount_unit)
return log_oom();
@@ -368,9 +445,15 @@ static int add_mount(
fprintf(f, "Before=%s\n", post);
if (opts) {
+ r = write_after(f, opts);
+ if (r < 0)
+ return r;
r = write_requires_after(f, opts);
if (r < 0)
return r;
+ r = write_before(f, opts);
+ if (r < 0)
+ return r;
r = write_requires_mounts_for(f, opts);
if (r < 0)
return r;
@@ -391,7 +474,7 @@ static int add_mount(
return log_error_errno(r, "Failed to write unit file %s: %m", automount_unit);
free(lnk);
- lnk = strjoin(arg_dest, "/", post, nofail ? ".wants/" : ".requires/", automount_name, NULL);
+ lnk = strjoin(dest, "/", post, nofail ? ".wants/" : ".requires/", automount_name);
if (!lnk)
return log_oom();
@@ -464,7 +547,8 @@ static int parse_fstab(bool initrd) {
else
post = SPECIAL_LOCAL_FS_TARGET;
- k = add_mount(what,
+ k = add_mount(arg_dest,
+ what,
where,
me->mnt_type,
me->mnt_opts,
@@ -525,7 +609,8 @@ static int add_sysroot_mount(void) {
return r;
}
- return add_mount(what,
+ return add_mount(arg_dest,
+ what,
"/sysroot",
arg_root_fstype,
opts,
@@ -578,7 +663,8 @@ static int add_sysroot_usr_mount(void) {
opts = arg_usr_options;
log_debug("Found entry what=%s where=/sysroot/usr type=%s", what, strna(arg_usr_fstype));
- return add_mount(what,
+ return add_mount(arg_dest,
+ what,
"/sysroot/usr",
arg_usr_fstype,
opts,
@@ -590,6 +676,46 @@ static int add_sysroot_usr_mount(void) {
"/proc/cmdline");
}
+static int add_volatile_root(void) {
+ const char *from, *to;
+
+ if (arg_volatile_mode != VOLATILE_YES)
+ return 0;
+
+ /* Let's add in systemd-remount-volatile.service which will remount the root device to tmpfs if this is
+ * requested, leaving only /usr from the root mount inside. */
+
+ from = strjoina(SYSTEM_DATA_UNIT_PATH "/systemd-volatile-root.service");
+ to = strjoina(arg_dest, "/" SPECIAL_INITRD_ROOT_FS_TARGET, ".requires/systemd-volatile-root.service");
+
+ (void) mkdir_parents(to, 0755);
+
+ if (symlink(from, to) < 0)
+ return log_error_errno(errno, "Failed to hook in volatile remount service: %m");
+
+ return 0;
+}
+
+static int add_volatile_var(void) {
+
+ if (arg_volatile_mode != VOLATILE_STATE)
+ return 0;
+
+ /* If requested, mount /var as tmpfs, but do so only if there's nothing else defined for this. */
+
+ return add_mount(arg_dest_late,
+ "tmpfs",
+ "/var",
+ "tmpfs",
+ "mode=0755",
+ 0,
+ false,
+ false,
+ false,
+ SPECIAL_LOCAL_FS_TARGET,
+ "/proc/cmdline");
+}
+
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
int r;
@@ -597,51 +723,76 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
* instance should take precedence. In the case of multiple rootflags=
* or usrflags= the arguments should be concatenated */
- if (STR_IN_SET(key, "fstab", "rd.fstab") && value) {
+ if (STR_IN_SET(key, "fstab", "rd.fstab")) {
- r = parse_boolean(value);
+ r = value ? parse_boolean(value) : 1;
if (r < 0)
log_warning("Failed to parse fstab switch %s. Ignoring.", value);
else
arg_fstab_enabled = r;
- } else if (streq(key, "root") && value) {
+ } else if (streq(key, "root")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
if (free_and_strdup(&arg_root_what, value) < 0)
return log_oom();
- } else if (streq(key, "rootfstype") && value) {
+ } else if (streq(key, "rootfstype")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
if (free_and_strdup(&arg_root_fstype, value) < 0)
return log_oom();
- } else if (streq(key, "rootflags") && value) {
+ } else if (streq(key, "rootflags")) {
char *o;
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
o = arg_root_options ?
- strjoin(arg_root_options, ",", value, NULL) :
+ strjoin(arg_root_options, ",", value) :
strdup(value);
if (!o)
return log_oom();
free(arg_root_options);
arg_root_options = o;
+ } else if (streq(key, "roothash")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
- } else if (streq(key, "mount.usr") && value) {
+ if (free_and_strdup(&arg_root_hash, value) < 0)
+ return log_oom();
+
+ } else if (streq(key, "mount.usr")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
if (free_and_strdup(&arg_usr_what, value) < 0)
return log_oom();
- } else if (streq(key, "mount.usrfstype") && value) {
+ } else if (streq(key, "mount.usrfstype")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
if (free_and_strdup(&arg_usr_fstype, value) < 0)
return log_oom();
- } else if (streq(key, "mount.usrflags") && value) {
+ } else if (streq(key, "mount.usrflags")) {
char *o;
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
o = arg_usr_options ?
- strjoin(arg_usr_options, ",", value, NULL) :
+ strjoin(arg_usr_options, ",", value) :
strdup(value);
if (!o)
return log_oom();
@@ -653,10 +804,40 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
arg_root_rw = true;
else if (streq(key, "ro") && !value)
arg_root_rw = false;
+ else if (streq(key, "systemd.volatile")) {
+ VolatileMode m;
+
+ if (value) {
+ m = volatile_mode_from_string(value);
+ if (m < 0)
+ log_warning("Failed to parse systemd.volatile= argument: %s", value);
+ else
+ arg_volatile_mode = m;
+ } else
+ arg_volatile_mode = VOLATILE_YES;
+ }
return 0;
}
+static int determine_root(void) {
+ /* If we have a root hash but no root device then Verity is used, and we use the "root" DM device as root. */
+
+ if (arg_root_what)
+ return 0;
+
+ if (!arg_root_hash)
+ return 0;
+
+ arg_root_what = strdup("/dev/mapper/root");
+ if (!arg_root_what)
+ return log_oom();
+
+ log_info("Using verity root device %s.", arg_root_what);
+
+ return 1;
+}
+
int main(int argc, char *argv[]) {
int r = 0;
@@ -667,6 +848,8 @@ int main(int argc, char *argv[]) {
if (argc > 1)
arg_dest = argv[1];
+ if (argc > 3)
+ arg_dest_late = argv[3];
log_set_target(LOG_TARGET_SAFE);
log_parse_environment();
@@ -674,10 +857,12 @@ int main(int argc, char *argv[]) {
umask(0022);
- r = parse_proc_cmdline(parse_proc_cmdline_item, NULL, false);
+ r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
if (r < 0)
log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
+ (void) determine_root();
+
/* Always honour root= and usr= in the kernel command line if we are in an initrd */
if (in_initrd()) {
int k;
@@ -687,8 +872,12 @@ int main(int argc, char *argv[]) {
k = add_sysroot_usr_mount();
if (k < 0)
r = k;
+
+ k = add_volatile_root();
+ if (k < 0)
+ r = k;
} else
- r = 0;
+ r = add_volatile_var();
/* Honour /etc/fstab only when that's enabled */
if (arg_fstab_enabled) {
@@ -714,6 +903,7 @@ int main(int argc, char *argv[]) {
free(arg_root_what);
free(arg_root_fstype);
free(arg_root_options);
+ free(arg_root_hash);
free(arg_usr_what);
free(arg_usr_fstype);
diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c
index a098b27a8e..80f676e477 100644
--- a/src/gpt-auto-generator/gpt-auto-generator.c
+++ b/src/gpt-auto-generator/gpt-auto-generator.c
@@ -29,6 +29,7 @@
#include "blkid-util.h"
#include "btrfs-util.h"
#include "dirent-util.h"
+#include "dissect-image.h"
#include "efivars.h"
#include "fd-util.h"
#include "fileio.h"
@@ -54,7 +55,7 @@ static bool arg_enabled = true;
static bool arg_root_enabled = true;
static bool arg_root_rw = false;
-static int add_cryptsetup(const char *id, const char *what, bool rw, char **device) {
+static int add_cryptsetup(const char *id, const char *what, bool rw, bool require, char **device) {
_cleanup_free_ char *e = NULL, *n = NULL, *p = NULL, *d = NULL, *to = NULL;
_cleanup_fclose_ FILE *f = NULL;
char *from, *ret;
@@ -62,7 +63,6 @@ static int add_cryptsetup(const char *id, const char *what, bool rw, char **devi
assert(id);
assert(what);
- assert(device);
r = unit_name_from_path(what, ".device", &d);
if (r < 0)
@@ -76,7 +76,7 @@ static int add_cryptsetup(const char *id, const char *what, bool rw, char **devi
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
- p = strjoin(arg_dest, "/", n, NULL);
+ p = strjoin(arg_dest, "/", n);
if (!p)
return log_oom();
@@ -111,7 +111,7 @@ static int add_cryptsetup(const char *id, const char *what, bool rw, char **devi
from = strjoina("../", n);
- to = strjoin(arg_dest, "/", d, ".wants/", n, NULL);
+ to = strjoin(arg_dest, "/", d, ".wants/", n);
if (!to)
return log_oom();
@@ -119,26 +119,29 @@ static int add_cryptsetup(const char *id, const char *what, bool rw, char **devi
if (symlink(from, to) < 0)
return log_error_errno(errno, "Failed to create symlink %s: %m", to);
- free(to);
- to = strjoin(arg_dest, "/cryptsetup.target.requires/", n, NULL);
- if (!to)
- return log_oom();
+ if (require) {
+ free(to);
- mkdir_parents_label(to, 0755);
- if (symlink(from, to) < 0)
- return log_error_errno(errno, "Failed to create symlink %s: %m", to);
+ to = strjoin(arg_dest, "/cryptsetup.target.requires/", n);
+ if (!to)
+ return log_oom();
- free(to);
- to = strjoin(arg_dest, "/dev-mapper-", e, ".device.requires/", n, NULL);
- if (!to)
- return log_oom();
+ mkdir_parents_label(to, 0755);
+ if (symlink(from, to) < 0)
+ return log_error_errno(errno, "Failed to create symlink %s: %m", to);
- mkdir_parents_label(to, 0755);
- if (symlink(from, to) < 0)
- return log_error_errno(errno, "Failed to create symlink %s: %m", to);
+ free(to);
+ to = strjoin(arg_dest, "/dev-mapper-", e, ".device.requires/", n);
+ if (!to)
+ return log_oom();
+
+ mkdir_parents_label(to, 0755);
+ if (symlink(from, to) < 0)
+ return log_error_errno(errno, "Failed to create symlink %s: %m", to);
+ }
free(p);
- p = strjoin(arg_dest, "/dev-mapper-", e, ".device.d/50-job-timeout-sec-0.conf", NULL);
+ p = strjoin(arg_dest, "/dev-mapper-", e, ".device.d/50-job-timeout-sec-0.conf");
if (!p)
return log_oom();
@@ -155,7 +158,8 @@ static int add_cryptsetup(const char *id, const char *what, bool rw, char **devi
if (!ret)
return log_oom();
- *device = ret;
+ if (device)
+ *device = ret;
return 0;
}
@@ -182,7 +186,7 @@ static int add_mount(
if (streq_ptr(fstype, "crypto_LUKS")) {
- r = add_cryptsetup(id, what, rw, &crypto_what);
+ r = add_cryptsetup(id, what, rw, true, &crypto_what);
if (r < 0)
return r;
@@ -194,7 +198,7 @@ static int add_mount(
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
- p = strjoin(arg_dest, "/", unit, NULL);
+ p = strjoin(arg_dest, "/", unit);
if (!p)
return log_oom();
@@ -236,7 +240,7 @@ static int add_mount(
return log_error_errno(r, "Failed to write unit file %s: %m", p);
if (post) {
- lnk = strjoin(arg_dest, "/", post, ".requires/", unit, NULL);
+ lnk = strjoin(arg_dest, "/", post, ".requires/", unit);
if (!lnk)
return log_oom();
@@ -252,7 +256,7 @@ static bool path_is_busy(const char *where) {
int r;
/* already a mountpoint; generators run during reload */
- r = path_is_mount_point(where, AT_SYMLINK_FOLLOW);
+ r = path_is_mount_point(where, NULL, AT_SYMLINK_FOLLOW);
if (r > 0)
return false;
@@ -270,61 +274,28 @@ static bool path_is_busy(const char *where) {
return false;
}
-static int probe_and_add_mount(
+static int add_partition_mount(
+ DissectedPartition *p,
const char *id,
- const char *what,
const char *where,
- bool rw,
- const char *description,
- const char *post) {
+ const char *description) {
- _cleanup_blkid_free_probe_ blkid_probe b = NULL;
- const char *fstype = NULL;
- int r;
-
- assert(id);
- assert(what);
- assert(where);
- assert(description);
+ assert(p);
if (path_is_busy(where)) {
log_debug("%s already populated, ignoring.", where);
return 0;
}
- /* Let's check the partition type here, so that we know
- * whether to do LUKS magic. */
-
- errno = 0;
- b = blkid_new_probe_from_filename(what);
- if (!b) {
- if (errno == 0)
- return log_oom();
- return log_error_errno(errno, "Failed to allocate prober: %m");
- }
-
- blkid_probe_enable_superblocks(b, 1);
- blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
-
- errno = 0;
- r = blkid_do_safeprobe(b);
- if (r == -2 || r == 1) /* no result or uncertain */
- return 0;
- else if (r != 0)
- return log_error_errno(errno ?: EIO, "Failed to probe %s: %m", what);
-
- /* add_mount is OK with fstype being NULL. */
- (void) blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);
-
return add_mount(
id,
- what,
+ p->node,
where,
- fstype,
- rw,
+ p->fstype,
+ p->rw,
NULL,
description,
- post);
+ SPECIAL_LOCAL_FS_TARGET);
}
static int add_swap(const char *path) {
@@ -340,7 +311,7 @@ static int add_swap(const char *path) {
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
- unit = strjoin(arg_dest, "/", name, NULL);
+ unit = strjoin(arg_dest, "/", name);
if (!unit)
return log_oom();
@@ -361,7 +332,7 @@ static int add_swap(const char *path) {
if (r < 0)
return log_error_errno(r, "Failed to write unit file %s: %m", unit);
- lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name, NULL);
+ lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name);
if (!lnk)
return log_oom();
@@ -393,7 +364,7 @@ static int add_automount(
assert(description);
if (options)
- opt = strjoin(options, ",noauto", NULL);
+ opt = strjoin(options, ",noauto");
else
opt = strdup("noauto");
if (!opt)
@@ -414,7 +385,7 @@ static int add_automount(
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
- p = strjoin(arg_dest, "/", unit, NULL);
+ p = strjoin(arg_dest, "/", unit);
if (!p)
return log_oom();
@@ -429,16 +400,16 @@ static int add_automount(
"Documentation=man:systemd-gpt-auto-generator(8)\n"
"[Automount]\n"
"Where=%s\n"
- "TimeoutIdleSec=%lld\n",
+ "TimeoutIdleSec="USEC_FMT"\n",
description,
where,
- (unsigned long long)timeout / USEC_PER_SEC);
+ timeout / USEC_PER_SEC);
r = fflush_and_check(f);
if (r < 0)
return log_error_errno(r, "Failed to write unit file %s: %m", p);
- lnk = strjoin(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".wants/", unit, NULL);
+ lnk = strjoin(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".wants/", unit);
if (!lnk)
return log_oom();
mkdir_parents_label(lnk, 0755);
@@ -449,22 +420,17 @@ static int add_automount(
return 0;
}
-static int add_boot(const char *what) {
+static int add_esp(DissectedPartition *p) {
const char *esp;
int r;
- assert(what);
+ assert(p);
if (in_initrd()) {
log_debug("In initrd, ignoring the ESP.");
return 0;
}
- if (detect_container() > 0) {
- log_debug("In a container, ignoring the ESP.");
- return 0;
- }
-
/* If /efi exists we'll use that. Otherwise we'll use /boot, as that's usually the better choice */
esp = access("/efi/", F_OK) >= 0 ? "/efi" : "/boot";
@@ -480,9 +446,7 @@ static int add_boot(const char *what) {
}
if (is_efi_boot()) {
- _cleanup_blkid_free_probe_ blkid_probe b = NULL;
- const char *fstype = NULL, *uuid_string = NULL;
- sd_id128_t loader_uuid, part_uuid;
+ sd_id128_t loader_uuid;
/* If this is an EFI boot, be extra careful, and only mount the ESP if it was the ESP used for booting. */
@@ -494,43 +458,7 @@ static int add_boot(const char *what) {
if (r < 0)
return log_error_errno(r, "Failed to read ESP partition UUID: %m");
- errno = 0;
- b = blkid_new_probe_from_filename(what);
- if (!b) {
- if (errno == 0)
- return log_oom();
- return log_error_errno(errno, "Failed to allocate prober: %m");
- }
-
- blkid_probe_enable_partitions(b, 1);
- blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
-
- errno = 0;
- r = blkid_do_safeprobe(b);
- if (r == -2 || r == 1) /* no result or uncertain */
- return 0;
- else if (r != 0)
- return log_error_errno(errno ?: EIO, "Failed to probe %s: %m", what);
-
- (void) blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);
- if (!streq_ptr(fstype, "vfat")) {
- log_debug("Partition for %s is not a FAT filesystem, ignoring.", esp);
- return 0;
- }
-
- errno = 0;
- r = blkid_probe_lookup_value(b, "PART_ENTRY_UUID", &uuid_string, NULL);
- if (r != 0) {
- log_debug_errno(errno, "Partition for %s does not have a UUID, ignoring.", esp);
- return 0;
- }
-
- if (sd_id128_from_string(uuid_string, &part_uuid) < 0) {
- log_debug("Partition for %s does not have a valid UUID, ignoring.", esp);
- return 0;
- }
-
- if (!sd_id128_equal(part_uuid, loader_uuid)) {
+ if (!sd_id128_equal(p->uuid, loader_uuid)) {
log_debug("Partition for %s does not appear to be the partition we are booted from.", esp);
return 0;
}
@@ -538,35 +466,29 @@ static int add_boot(const char *what) {
log_debug("Not an EFI boot, skipping ESP check.");
return add_automount("boot",
- what,
- esp,
- "vfat",
- true,
- "umask=0077",
- "EFI System Partition Automount",
- 120 * USEC_PER_SEC);
+ p->node,
+ esp,
+ p->fstype,
+ true,
+ "umask=0077",
+ "EFI System Partition Automount",
+ 120 * USEC_PER_SEC);
}
#else
-static int add_boot(const char *what) {
+static int add_esp(DissectedPartition *p) {
return 0;
}
#endif
-static int enumerate_partitions(dev_t devnum) {
-
- _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
+static int open_parent(dev_t devnum, int *ret) {
_cleanup_udev_device_unref_ struct udev_device *d = NULL;
- _cleanup_blkid_free_probe_ blkid_probe b = NULL;
_cleanup_udev_unref_ struct udev *udev = NULL;
- _cleanup_free_ char *boot = NULL, *home = NULL, *srv = NULL;
- struct udev_list_entry *first, *item;
- struct udev_device *parent = NULL;
- const char *name, *node, *pttype, *devtype;
- int boot_nr = -1, home_nr = -1, srv_nr = -1;
- bool home_rw = true, srv_rw = true;
- blkid_partlist pl;
- int r, k;
+ const char *name, *devtype, *node;
+ struct udev_device *parent;
dev_t pn;
+ int fd;
+
+ assert(ret);
udev = udev_new();
if (!udev)
@@ -580,228 +502,94 @@ static int enumerate_partitions(dev_t devnum) {
if (!name)
name = udev_device_get_syspath(d);
if (!name) {
- log_debug("Device %u:%u does not have a name, ignoring.",
- major(devnum), minor(devnum));
- return 0;
+ log_debug("Device %u:%u does not have a name, ignoring.", major(devnum), minor(devnum));
+ goto not_found;
}
parent = udev_device_get_parent(d);
if (!parent) {
log_debug("%s: not a partitioned device, ignoring.", name);
- return 0;
+ goto not_found;
}
/* Does it have a devtype? */
devtype = udev_device_get_devtype(parent);
if (!devtype) {
log_debug("%s: parent doesn't have a device type, ignoring.", name);
- return 0;
+ goto not_found;
}
/* Is this a disk or a partition? We only care for disks... */
if (!streq(devtype, "disk")) {
log_debug("%s: parent isn't a raw disk, ignoring.", name);
- return 0;
+ goto not_found;
}
/* Does it have a device node? */
node = udev_device_get_devnode(parent);
if (!node) {
log_debug("%s: parent device does not have device node, ignoring.", name);
- return 0;
+ goto not_found;
}
log_debug("%s: root device %s.", name, node);
pn = udev_device_get_devnum(parent);
- if (major(pn) == 0)
- return 0;
-
- errno = 0;
- b = blkid_new_probe_from_filename(node);
- if (!b) {
- if (errno == 0)
- return log_oom();
-
- return log_error_errno(errno, "%s: failed to allocate prober: %m", node);
+ if (major(pn) == 0) {
+ log_debug("%s: parent device is not a proper block device, ignoring.", name);
+ goto not_found;
}
- blkid_probe_enable_partitions(b, 1);
- blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
+ fd = open(node, O_RDONLY|O_CLOEXEC|O_NOCTTY);
+ if (fd < 0)
+ return log_error_errno(errno, "Failed to open %s: %m", node);
- errno = 0;
- r = blkid_do_safeprobe(b);
- if (r == 1)
- return 0; /* no results */
- else if (r == -2) {
- log_warning("%s: probe gave ambiguous results, ignoring.", node);
- return 0;
- } else if (r != 0)
- return log_error_errno(errno ?: EIO, "%s: failed to probe: %m", node);
+ *ret = fd;
+ return 1;
- errno = 0;
- r = blkid_probe_lookup_value(b, "PTTYPE", &pttype, NULL);
- if (r != 0) {
- if (errno == 0)
- return 0; /* No partition table found. */
+not_found:
+ *ret = -1;
+ return 0;
+}
- return log_error_errno(errno, "%s: failed to determine partition table type: %m", node);
- }
+static int enumerate_partitions(dev_t devnum) {
- /* We only do this all for GPT... */
- if (!streq_ptr(pttype, "gpt")) {
- log_debug("%s: not a GPT partition table, ignoring.", node);
- return 0;
- }
+ _cleanup_close_ int fd = -1;
+ _cleanup_(dissected_image_unrefp) DissectedImage *m = NULL;
+ int r, k;
- errno = 0;
- pl = blkid_probe_get_partitions(b);
- if (!pl) {
- if (errno == 0)
- return log_oom();
+ r = open_parent(devnum, &fd);
+ if (r <= 0)
+ return r;
- return log_error_errno(errno, "%s: failed to list partitions: %m", node);
+ r = dissect_image(fd, NULL, 0, DISSECT_IMAGE_GPT_ONLY, &m);
+ if (r == -ENOPKG) {
+ log_debug_errno(r, "No suitable partition table found, ignoring.");
+ return 0;
}
-
- e = udev_enumerate_new(udev);
- if (!e)
- return log_oom();
-
- r = udev_enumerate_add_match_parent(e, parent);
- if (r < 0)
- return log_oom();
-
- r = udev_enumerate_add_match_subsystem(e, "block");
- if (r < 0)
- return log_oom();
-
- r = udev_enumerate_scan_devices(e);
if (r < 0)
- return log_error_errno(r, "%s: failed to enumerate partitions: %m", node);
-
- first = udev_enumerate_get_list_entry(e);
- udev_list_entry_foreach(item, first) {
- _cleanup_udev_device_unref_ struct udev_device *q;
- unsigned long long flags;
- const char *stype, *subnode;
- sd_id128_t type_id;
- blkid_partition pp;
- dev_t qn;
- int nr;
-
- q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
- if (!q)
- continue;
-
- qn = udev_device_get_devnum(q);
- if (major(qn) == 0)
- continue;
-
- if (qn == devnum)
- continue;
-
- if (qn == pn)
- continue;
-
- subnode = udev_device_get_devnode(q);
- if (!subnode)
- continue;
-
- pp = blkid_partlist_devno_to_partition(pl, qn);
- if (!pp)
- continue;
-
- nr = blkid_partition_get_partno(pp);
- if (nr < 0)
- continue;
-
- stype = blkid_partition_get_type_string(pp);
- if (!stype)
- continue;
-
- if (sd_id128_from_string(stype, &type_id) < 0)
- continue;
-
- flags = blkid_partition_get_flags(pp);
-
- if (sd_id128_equal(type_id, GPT_SWAP)) {
-
- if (flags & GPT_FLAG_NO_AUTO)
- continue;
-
- if (flags & GPT_FLAG_READ_ONLY) {
- log_debug("%s marked as read-only swap partition, which is bogus. Ignoring.", subnode);
- continue;
- }
-
- k = add_swap(subnode);
- if (k < 0)
- r = k;
-
- } else if (sd_id128_equal(type_id, GPT_ESP)) {
-
- /* We only care for the first /boot partition */
- if (boot && nr >= boot_nr)
- continue;
-
- /* Note that we do not honour the "no-auto"
- * flag for the ESP, as it is often unset, to
- * hide it from Windows. */
-
- boot_nr = nr;
-
- r = free_and_strdup(&boot, subnode);
- if (r < 0)
- return log_oom();
-
- } else if (sd_id128_equal(type_id, GPT_HOME)) {
+ return log_error_errno(r, "Failed to dissect: %m");
- if (flags & GPT_FLAG_NO_AUTO)
- continue;
-
- /* We only care for the first /home partition */
- if (home && nr >= home_nr)
- continue;
-
- home_nr = nr;
- home_rw = !(flags & GPT_FLAG_READ_ONLY),
-
- r = free_and_strdup(&home, subnode);
- if (r < 0)
- return log_oom();
-
- } else if (sd_id128_equal(type_id, GPT_SRV)) {
-
- if (flags & GPT_FLAG_NO_AUTO)
- continue;
-
- /* We only care for the first /srv partition */
- if (srv && nr >= srv_nr)
- continue;
-
- srv_nr = nr;
- srv_rw = !(flags & GPT_FLAG_READ_ONLY),
-
- r = free_and_strdup(&srv, subnode);
- if (r < 0)
- return log_oom();
- }
+ if (m->partitions[PARTITION_SWAP].found) {
+ k = add_swap(m->partitions[PARTITION_SWAP].node);
+ if (k < 0)
+ r = k;
}
- if (boot) {
- k = add_boot(boot);
+ if (m->partitions[PARTITION_ESP].found) {
+ k = add_esp(m->partitions + PARTITION_ESP);
if (k < 0)
r = k;
}
- if (home) {
- k = probe_and_add_mount("home", home, "/home", home_rw, "Home Partition", SPECIAL_LOCAL_FS_TARGET);
+ if (m->partitions[PARTITION_HOME].found) {
+ k = add_partition_mount(m->partitions + PARTITION_HOME, "home", "/home", "Home Partition");
if (k < 0)
r = k;
}
- if (srv) {
- k = probe_and_add_mount("srv", srv, "/srv", srv_rw, "Server Data Partition", SPECIAL_LOCAL_FS_TARGET);
+ if (m->partitions[PARTITION_SRV].found) {
+ k = add_partition_mount(m->partitions + PARTITION_SRV, "srv", "/srv", "Server Data Partition");
if (k < 0)
r = k;
}
@@ -870,14 +658,46 @@ static int get_block_device_harder(const char *path, dev_t *dev) {
FOREACH_DIRENT_ALL(de, d, return -errno) {
- if (STR_IN_SET(de->d_name, ".", ".."))
+ if (dot_or_dot_dot(de->d_name))
continue;
if (!IN_SET(de->d_type, DT_LNK, DT_UNKNOWN))
continue;
- if (found) /* Don't try to support multiple backing block devices */
- goto fallback;
+ if (found) {
+ _cleanup_free_ char *u = NULL, *v = NULL, *a = NULL, *b = NULL;
+
+ /* We found a device backed by multiple other devices. We don't really support automatic
+ * discovery on such setups, with the exception of dm-verity partitions. In this case there are
+ * two backing devices: the data partition and the hash partition. We are fine with such
+ * setups, however, only if both partitions are on the same physical device. Hence, let's
+ * verify this. */
+
+ u = strjoin(p, "/", de->d_name, "/../dev");
+ if (!u)
+ return -ENOMEM;
+
+ v = strjoin(p, "/", found->d_name, "/../dev");
+ if (!v)
+ return -ENOMEM;
+
+ r = read_one_line_file(u, &a);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to read %s: %m", u);
+ goto fallback;
+ }
+
+ r = read_one_line_file(v, &b);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to read %s: %m", v);
+ goto fallback;
+ }
+
+ /* Check if the parent device is the same. If not, then the two backing devices are on
+ * different physical devices, and we don't support that. */
+ if (!streq(a, b))
+ goto fallback;
+ }
found = de;
}
@@ -912,21 +732,33 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
assert(key);
- if (STR_IN_SET(key, "systemd.gpt_auto", "rd.systemd.gpt_auto") && value) {
+ if (STR_IN_SET(key, "systemd.gpt_auto", "rd.systemd.gpt_auto")) {
- r = parse_boolean(value);
+ r = value ? parse_boolean(value) : 1;
if (r < 0)
log_warning("Failed to parse gpt-auto switch \"%s\". Ignoring.", value);
else
arg_enabled = r;
- } else if (streq(key, "root") && value) {
+ } else if (streq(key, "root")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
/* Disable root disk logic if there's a root= value
* specified (unless it happens to be "gpt-auto") */
arg_root_enabled = streq(value, "gpt-auto");
+ } else if (streq(key, "roothash")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
+ /* Disable root disk logic if there's roothash= defined (i.e. verity enabled) */
+
+ arg_root_enabled = false;
+
} else if (streq(key, "rw") && !value)
arg_root_rw = true;
else if (streq(key, "ro") && !value)
@@ -935,6 +767,16 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
return 0;
}
+#ifdef ENABLE_EFI
+static int add_root_cryptsetup(void) {
+
+ /* If a device /dev/gpt-auto-root-luks appears, then make it pull in systemd-cryptsetup-root.service, which
+ * sets it up, and causes /dev/gpt-auto-root to appear which is all we are looking for. */
+
+ return add_cryptsetup("root", "/dev/gpt-auto-root-luks", true, false, NULL);
+}
+#endif
+
static int add_root_mount(void) {
#ifdef ENABLE_EFI
@@ -960,6 +802,10 @@ static int add_root_mount(void) {
r = generator_write_initrd_root_device_deps(arg_dest, "/dev/gpt-auto-root");
if (r < 0)
return 0;
+
+ r = add_root_cryptsetup();
+ if (r < 0)
+ return r;
}
return add_mount(
@@ -983,11 +829,11 @@ static int add_mounts(void) {
r = get_block_device_harder("/", &devno);
if (r < 0)
return log_error_errno(r, "Failed to determine block device of root file system: %m");
- else if (r == 0) {
+ if (r == 0) {
r = get_block_device_harder("/usr", &devno);
if (r < 0)
return log_error_errno(r, "Failed to determine block device of /usr file system: %m");
- else if (r == 0) {
+ if (r == 0) {
log_debug("Neither root nor /usr file system are on a (single) block device.");
return 0;
}
@@ -997,7 +843,7 @@ static int add_mounts(void) {
}
int main(int argc, char *argv[]) {
- int r = 0;
+ int r = 0, k;
if (argc > 1 && argc != 4) {
log_error("This program takes three or no arguments.");
@@ -1018,7 +864,7 @@ int main(int argc, char *argv[]) {
return EXIT_SUCCESS;
}
- r = parse_proc_cmdline(parse_proc_cmdline_item, NULL, false);
+ r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
if (r < 0)
log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
@@ -1031,8 +877,6 @@ int main(int argc, char *argv[]) {
r = add_root_mount();
if (!in_initrd()) {
- int k;
-
k = add_mounts();
if (k < 0)
r = k;
diff --git a/src/hibernate-resume/hibernate-resume-generator.c b/src/hibernate-resume/hibernate-resume-generator.c
index 17e670604e..a97fe668d5 100644
--- a/src/hibernate-resume/hibernate-resume-generator.c
+++ b/src/hibernate-resume/hibernate-resume-generator.c
@@ -31,15 +31,22 @@
#include "util.h"
static const char *arg_dest = "/tmp";
-static char *arg_resume_dev = NULL;
+static char *arg_resume_device = NULL;
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
- if (streq(key, "resume") && value) {
- free(arg_resume_dev);
- arg_resume_dev = fstab_node_to_udev_node(value);
- if (!arg_resume_dev)
+ if (streq(key, "resume")) {
+ char *s;
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
+ s = fstab_node_to_udev_node(value);
+ if (!s)
return log_oom();
+
+ free(arg_resume_device);
+ arg_resume_device = s;
}
return 0;
@@ -49,14 +56,14 @@ static int process_resume(void) {
_cleanup_free_ char *name = NULL, *lnk = NULL;
int r;
- if (!arg_resume_dev)
+ if (!arg_resume_device)
return 0;
- r = unit_name_from_path_instance("systemd-hibernate-resume", arg_resume_dev, ".service", &name);
+ r = unit_name_from_path_instance("systemd-hibernate-resume", arg_resume_device, ".service", &name);
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
- lnk = strjoin(arg_dest, "/" SPECIAL_SYSINIT_TARGET ".wants/", name, NULL);
+ lnk = strjoin(arg_dest, "/" SPECIAL_SYSINIT_TARGET ".wants/", name);
if (!lnk)
return log_oom();
@@ -88,12 +95,12 @@ int main(int argc, char *argv[]) {
if (!in_initrd())
return EXIT_SUCCESS;
- r = parse_proc_cmdline(parse_proc_cmdline_item, NULL, false);
+ r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
if (r < 0)
log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
r = process_resume();
- free(arg_resume_dev);
+ free(arg_resume_device);
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/src/hostname/hostnamectl.c b/src/hostname/hostnamectl.c
index 07c57fb567..f5a9de94a6 100644
--- a/src/hostname/hostnamectl.c
+++ b/src/hostname/hostnamectl.c
@@ -137,10 +137,8 @@ static int show_one_name(sd_bus *bus, const char* attr) {
"org.freedesktop.hostname1",
attr,
&error, &reply, "s");
- if (r < 0) {
- log_error("Could not get property: %s", bus_error_message(&error, -r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Could not get property: %s", bus_error_message(&error, r));
r = sd_bus_message_read(reply, "s", &s);
if (r < 0)
@@ -151,7 +149,7 @@ static int show_one_name(sd_bus *bus, const char* attr) {
return 0;
}
-static int show_all_names(sd_bus *bus) {
+static int show_all_names(sd_bus *bus, sd_bus_error *error) {
StatusInfo info = {};
static const struct bus_properties_map hostname_map[] = {
@@ -181,6 +179,7 @@ static int show_all_names(sd_bus *bus) {
"org.freedesktop.hostname1",
"/org/freedesktop/hostname1",
hostname_map,
+ error,
&info);
if (r < 0)
goto fail;
@@ -189,6 +188,7 @@ static int show_all_names(sd_bus *bus) {
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
manager_map,
+ error,
&info);
print_status_info(&info);
@@ -212,6 +212,8 @@ fail:
}
static int show_status(sd_bus *bus, char **args, unsigned n) {
+ int r;
+
assert(args);
if (arg_pretty || arg_static || arg_transient) {
@@ -226,8 +228,15 @@ static int show_status(sd_bus *bus, char **args, unsigned n) {
arg_static ? "StaticHostname" : "Hostname";
return show_one_name(bus, attr);
- } else
- return show_all_names(bus);
+ } else {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+
+ r = show_all_names(bus, &error);
+ if (r < 0)
+ return log_error_errno(r, "Failed to query system properties: %s", bus_error_message(&error, r));
+
+ return 0;
+ }
}
static int set_simple_string(sd_bus *bus, const char *method, const char *value) {
diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c
index 197f905b7d..fe0aa00efb 100644
--- a/src/hostname/hostnamed.c
+++ b/src/hostname/hostnamed.c
@@ -133,6 +133,7 @@ static bool valid_chassis(const char *chassis) {
"container\0"
"desktop\0"
"laptop\0"
+ "convertible\0"
"server\0"
"tablet\0"
"handset\0"
@@ -199,6 +200,10 @@ static const char* fallback_chassis(void) {
case 0x1E: /* Tablet */
return "tablet";
+
+ case 0x1F: /* Convertible */
+ case 0x20: /* Detachable */
+ return "convertible";
}
try_acpi:
@@ -283,7 +288,7 @@ static int context_update_kernel_hostname(Context *c) {
/* ... and the ultimate fallback */
else
- hn = "localhost";
+ hn = FALLBACK_HOSTNAME;
if (sethostname_idempotent(hn) < 0)
return -errno;
@@ -335,7 +340,7 @@ static int context_write_data_machine_info(Context *c) {
continue;
}
- t = strjoin(name[p], "=", c->data[p], NULL);
+ t = strjoin(name[p], "=", c->data[p]);
if (!t)
return -ENOMEM;
@@ -419,7 +424,7 @@ static int method_set_hostname(sd_bus_message *m, void *userdata, sd_bus_error *
name = c->data[PROP_STATIC_HOSTNAME];
if (isempty(name))
- name = "localhost";
+ name = FALLBACK_HOSTNAME;
if (!hostname_is_valid(name, false))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid hostname '%s'", name);
diff --git a/src/hwdb/hwdb.c b/src/hwdb/hwdb.c
index ab1feb435b..df79fbc275 100644
--- a/src/hwdb/hwdb.c
+++ b/src/hwdb/hwdb.c
@@ -31,6 +31,7 @@
#include "hwdb-util.h"
#include "label.h"
#include "mkdir.h"
+#include "path-util.h"
#include "selinux-util.h"
#include "strbuf.h"
#include "string-util.h"
@@ -39,7 +40,7 @@
#include "verbs.h"
/*
- * Generic udev properties, key/value database based on modalias strings.
+ * Generic udev properties, key-value database based on modalias strings.
* Uses a Patricia/radix trie to index all matches for efficient lookup.
*/
@@ -70,7 +71,7 @@ struct trie_node {
struct trie_child_entry *children;
uint8_t children_count;
- /* sorted array of key/value pairs */
+ /* sorted array of key-value pairs */
struct trie_value_entry *values;
size_t values_count;
};
@@ -81,12 +82,13 @@ struct trie_child_entry {
struct trie_node *child;
};
-/* value array item with key/value pairs */
+/* value array item with key-value pairs */
struct trie_value_entry {
size_t key_off;
size_t value_off;
size_t filename_off;
- size_t line_number;
+ uint32_t line_number;
+ uint16_t file_priority;
};
static int trie_children_cmp(const void *v1, const void *v2) {
@@ -160,10 +162,9 @@ static int trie_values_cmp(const void *v1, const void *v2, void *arg) {
static int trie_node_add_value(struct trie *trie, struct trie_node *node,
const char *key, const char *value,
- const char *filename, size_t line_number) {
+ const char *filename, uint16_t file_priority, uint32_t line_number) {
ssize_t k, v, fn;
struct trie_value_entry *val;
- int r;
k = strbuf_add_string(trie->strings, key, strlen(key));
if (k < 0)
@@ -183,19 +184,12 @@ static int trie_node_add_value(struct trie *trie, struct trie_node *node,
val = xbsearch_r(&search, node->values, node->values_count, sizeof(struct trie_value_entry), trie_values_cmp, trie);
if (val) {
- /*
- * At this point we have 2 identical properties on the same match-string. We
- * strictly order them by filename+line-number, since we know the dynamic
- * runtime lookup does the same for multiple matching nodes.
+ /* At this point we have 2 identical properties on the same match-string.
+ * Since we process files in order, we just replace the previous value.
*/
- r = strcmp(filename, trie->strings->buf + val->filename_off);
- if (r < 0 ||
- (r == 0 && line_number < val->line_number))
- return 0;
-
- /* replace existing earlier key with new value */
val->value_off = v;
val->filename_off = fn;
+ val->file_priority = file_priority;
val->line_number = line_number;
return 0;
}
@@ -210,6 +204,7 @@ static int trie_node_add_value(struct trie *trie, struct trie_node *node,
node->values[node->values_count].key_off = k;
node->values[node->values_count].value_off = v;
node->values[node->values_count].filename_off = fn;
+ node->values[node->values_count].file_priority = file_priority;
node->values[node->values_count].line_number = line_number;
node->values_count++;
qsort_r(node->values, node->values_count, sizeof(struct trie_value_entry), trie_values_cmp, trie);
@@ -218,9 +213,9 @@ static int trie_node_add_value(struct trie *trie, struct trie_node *node,
static int trie_insert(struct trie *trie, struct trie_node *node, const char *search,
const char *key, const char *value,
- const char *filename, uint64_t line_number) {
+ const char *filename, uint16_t file_priority, uint32_t line_number) {
size_t i = 0;
- int err = 0;
+ int r = 0;
for (;;) {
size_t p;
@@ -261,9 +256,9 @@ static int trie_insert(struct trie *trie, struct trie_node *node, const char *se
node->children_count = 0;
node->values = NULL;
node->values_count = 0;
- err = node_add_child(trie, node, new_child, c);
- if (err < 0)
- return err;
+ r = node_add_child(trie, node, new_child, c);
+ if (r < 0)
+ return r;
new_child = NULL; /* avoid cleanup */
break;
@@ -272,7 +267,7 @@ static int trie_insert(struct trie *trie, struct trie_node *node, const char *se
c = search[i];
if (c == '\0')
- return trie_node_add_value(trie, node, key, value, filename, line_number);
+ return trie_node_add_value(trie, node, key, value, filename, file_priority, line_number);
child = node_lookup(node, c);
if (!child) {
@@ -290,13 +285,13 @@ static int trie_insert(struct trie *trie, struct trie_node *node, const char *se
}
child->prefix_off = off;
- err = node_add_child(trie, node, child, c);
- if (err < 0) {
+ r = node_add_child(trie, node, child, c);
+ if (r < 0) {
free(child);
- return err;
+ return r;
}
- return trie_node_add_value(trie, child, key, value, filename, line_number);
+ return trie_node_add_value(trie, child, key, value, filename, file_priority, line_number);
}
node = child;
@@ -335,11 +330,11 @@ static int64_t trie_store_nodes(struct trie_f *trie, struct trie_node *node) {
.children_count = node->children_count,
.values_count = htole64(node->values_count),
};
- struct trie_child_entry_f *children = NULL;
+ _cleanup_free_ struct trie_child_entry_f *children = NULL;
int64_t node_off;
if (node->children_count) {
- children = new0(struct trie_child_entry_f, node->children_count);
+ children = new(struct trie_child_entry_f, node->children_count);
if (!children)
return -ENOMEM;
}
@@ -349,12 +344,13 @@ static int64_t trie_store_nodes(struct trie_f *trie, struct trie_node *node) {
int64_t child_off;
child_off = trie_store_nodes(trie, node->children[i].child);
- if (child_off < 0) {
- free(children);
+ if (child_off < 0)
return child_off;
- }
- children[i].c = node->children[i].c;
- children[i].child_off = htole64(child_off);
+
+ children[i] = (struct trie_child_entry_f) {
+ .c = node->children[i].c,
+ .child_off = htole64(child_off),
+ };
}
/* write node */
@@ -366,7 +362,6 @@ static int64_t trie_store_nodes(struct trie_f *trie, struct trie_node *node) {
if (node->children_count) {
fwrite(children, sizeof(struct trie_child_entry_f), node->children_count, trie->f);
trie->children_count += node->children_count;
- free(children);
}
/* append values array */
@@ -375,12 +370,13 @@ static int64_t trie_store_nodes(struct trie_f *trie, struct trie_node *node) {
.key_off = htole64(trie->strings_off + node->values[i].key_off),
.value_off = htole64(trie->strings_off + node->values[i].value_off),
.filename_off = htole64(trie->strings_off + node->values[i].filename_off),
- .line_number = htole64(node->values[i].line_number),
+ .line_number = htole32(node->values[i].line_number),
+ .file_priority = htole16(node->values[i].file_priority),
};
fwrite(&v, sizeof(struct trie_value_entry2_f), 1, trie->f);
- trie->values_count++;
}
+ trie->values_count += node->values_count;
return node_off;
}
@@ -401,24 +397,21 @@ static int trie_store(struct trie *trie, const char *filename) {
.child_entry_size = htole64(sizeof(struct trie_child_entry_f)),
.value_entry_size = htole64(sizeof(struct trie_value_entry2_f)),
};
- int err;
+ int r;
/* calculate size of header, nodes, children entries, value entries */
t.strings_off = sizeof(struct trie_header_f);
trie_store_nodes_size(&t, trie->root);
- err = fopen_temporary(filename , &t.f, &filename_tmp);
- if (err < 0)
- return err;
+ r = fopen_temporary(filename , &t.f, &filename_tmp);
+ if (r < 0)
+ return r;
fchmod(fileno(t.f), 0444);
/* write nodes */
- err = fseeko(t.f, sizeof(struct trie_header_f), SEEK_SET);
- if (err < 0) {
- fclose(t.f);
- unlink_noerrno(filename_tmp);
- return -errno;
- }
+ if (fseeko(t.f, sizeof(struct trie_header_f), SEEK_SET) < 0)
+ goto error;
+
root_off = trie_store_nodes(&t, trie->root);
h.nodes_root_off = htole64(root_off);
pos = ftello(t.f);
@@ -431,20 +424,13 @@ static int trie_store(struct trie *trie, const char *filename) {
/* write header */
size = ftello(t.f);
h.file_size = htole64(size);
- err = fseeko(t.f, 0, SEEK_SET);
- if (err < 0) {
- fclose(t.f);
- unlink_noerrno(filename_tmp);
- return -errno;
- }
+ if (fseeko(t.f, 0, SEEK_SET) < 0)
+ goto error;
+
fwrite(&h, sizeof(struct trie_header_f), 1, t.f);
- err = ferror(t.f);
- if (err)
- err = -errno;
- fclose(t.f);
- if (err < 0 || rename(filename_tmp, filename) < 0) {
+ if (fclose(t.f) < 0 || rename(filename_tmp, filename) < 0) {
unlink_noerrno(filename_tmp);
- return err < 0 ? err : -errno;
+ return -errno;
}
log_debug("=== trie on-disk ===");
@@ -458,39 +444,46 @@ static int trie_store(struct trie *trie, const char *filename) {
t.values_count * sizeof(struct trie_value_entry2_f), t.values_count);
log_debug("string store: %8zu bytes", trie->strings->len);
log_debug("strings start: %8"PRIu64, t.strings_off);
-
return 0;
+
+ error:
+ r = -errno;
+ fclose(t.f);
+ unlink(filename_tmp);
+ return r;
}
static int insert_data(struct trie *trie, char **match_list, char *line,
- const char *filename, size_t line_number) {
+ const char *filename, uint16_t file_priority, uint32_t line_number) {
char *value, **entry;
+ assert(line[0] == ' ');
+
value = strchr(line, '=');
- if (!value) {
- log_error("Error, key/value pair expected but got '%s' in '%s':", line, filename);
- return -EINVAL;
- }
+ if (!value)
+ return log_syntax(NULL, LOG_WARNING, filename, line_number, EINVAL,
+ "Key-value pair expected but got \"%s\", ignoring", line);
value[0] = '\0';
value++;
- /* libudev requires properties to start with a space */
+ /* Replace multiple leading spaces by a single space */
while (isblank(line[0]) && isblank(line[1]))
line++;
- if (line[0] == '\0' || value[0] == '\0') {
- log_error("Error, empty key or value '%s' in '%s':", line, filename);
- return -EINVAL;
- }
+ if (isempty(line + 1) || isempty(value))
+ return log_syntax(NULL, LOG_WARNING, filename, line_number, EINVAL,
+ "Empty %s in \"%s=%s\", ignoring",
+ isempty(line + 1) ? "key" : "value",
+ line, value);
STRV_FOREACH(entry, match_list)
- trie_insert(trie, trie->root, *entry, line, value, filename, line_number);
+ trie_insert(trie, trie->root, *entry, line, value, filename, file_priority, line_number);
return 0;
}
-static int import_file(struct trie *trie, const char *filename) {
+static int import_file(struct trie *trie, const char *filename, uint16_t file_priority) {
enum {
HW_NONE,
HW_MATCH,
@@ -499,7 +492,7 @@ static int import_file(struct trie *trie, const char *filename) {
_cleanup_fclose_ FILE *f = NULL;
char line[LINE_MAX];
_cleanup_strv_free_ char **match_list = NULL;
- size_t line_number = 0;
+ uint32_t line_number = 0;
char *match = NULL;
int r;
@@ -534,7 +527,8 @@ static int import_file(struct trie *trie, const char *filename) {
break;
if (line[0] == ' ') {
- log_error("Error, MATCH expected but got '%s' in '%s':", line, filename);
+ log_syntax(NULL, LOG_WARNING, filename, line_number, EINVAL,
+ "Match expected but got indented property \"%s\", ignoring line", line);
break;
}
@@ -553,14 +547,16 @@ static int import_file(struct trie *trie, const char *filename) {
case HW_MATCH:
if (len == 0) {
- log_error("Error, DATA expected but got empty line in '%s':", filename);
+ log_syntax(NULL, LOG_WARNING, filename, line_number, EINVAL,
+ "Property expected, ignoring record with no properties");
+
state = HW_NONE;
strv_clear(match_list);
break;
}
- /* another match */
if (line[0] != ' ') {
+ /* another match */
match = strdup(line);
if (!match)
return -ENOMEM;
@@ -574,29 +570,34 @@ static int import_file(struct trie *trie, const char *filename) {
/* first data */
state = HW_DATA;
- insert_data(trie, match_list, line, filename, line_number);
+ insert_data(trie, match_list, line, filename, file_priority, line_number);
break;
case HW_DATA:
- /* end of record */
if (len == 0) {
+ /* end of record */
state = HW_NONE;
strv_clear(match_list);
break;
}
if (line[0] != ' ') {
- log_error("Error, DATA expected but got '%s' in '%s':", line, filename);
+ log_syntax(NULL, LOG_WARNING, filename, line_number, EINVAL,
+ "Property or empty line expected, got \"%s\", ignoring record", line);
state = HW_NONE;
strv_clear(match_list);
break;
}
- insert_data(trie, match_list, line, filename, line_number);
+ insert_data(trie, match_list, line, filename, file_priority, line_number);
break;
};
}
+ if (state == HW_MATCH)
+ log_syntax(NULL, LOG_WARNING, filename, line_number, EINVAL,
+ "Property expected, ignoring record with no properties");
+
return 0;
}
@@ -624,7 +625,9 @@ static int hwdb_query(int argc, char *argv[], void *userdata) {
static int hwdb_update(int argc, char *argv[], void *userdata) {
_cleanup_free_ char *hwdb_bin = NULL;
_cleanup_(trie_freep) struct trie *trie = NULL;
- char **files, **f;
+ _cleanup_strv_free_ char **files = NULL;
+ char **f;
+ uint16_t file_priority = 1;
int r;
trie = new0(struct trie, 1);
@@ -645,13 +648,12 @@ static int hwdb_update(int argc, char *argv[], void *userdata) {
r = conf_files_list_strv(&files, ".hwdb", arg_root, conf_file_dirs);
if (r < 0)
- return log_error_errno(r, "failed to enumerate hwdb files: %m");
+ return log_error_errno(r, "Failed to enumerate hwdb files: %m");
STRV_FOREACH(f, files) {
- log_debug("reading file '%s'", *f);
- import_file(trie, *f);
+ log_debug("Reading file \"%s\"", *f);
+ import_file(trie, *f, file_priority++);
}
- strv_free(files);
strbuf_complete(trie->strings);
@@ -669,7 +671,7 @@ static int hwdb_update(int argc, char *argv[], void *userdata) {
log_debug("strings dedup'ed: %8zu bytes (%8zu)",
trie->strings->dedup_len, trie->strings->dedup_count);
- hwdb_bin = strjoin(arg_root, "/", arg_hwdb_bin_dir, "/hwdb.bin", NULL);
+ hwdb_bin = path_join(arg_root, arg_hwdb_bin_dir, "hwdb.bin");
if (!hwdb_bin)
return -ENOMEM;
diff --git a/src/import/curl-util.c b/src/import/curl-util.c
index 734e1560e6..0e8f3fb918 100644
--- a/src/import/curl-util.c
+++ b/src/import/curl-util.c
@@ -400,7 +400,7 @@ int curl_header_strdup(const void *contents, size_t sz, const char *field, char
sz--;
}
- /* Truncate trailing whitespace*/
+ /* Truncate trailing whitespace */
while (sz > 0 && strchr(WHITESPACE, p[sz-1]))
sz--;
diff --git a/src/import/import-raw.c b/src/import/import-raw.c
index 29f3f896e5..55cf8e8edd 100644
--- a/src/import/import-raw.c
+++ b/src/import/import-raw.c
@@ -267,7 +267,7 @@ static int raw_import_open_disk(RawImport *i) {
assert(!i->temp_path);
assert(i->output_fd < 0);
- i->final_path = strjoin(i->image_root, "/", i->local, ".raw", NULL);
+ i->final_path = strjoin(i->image_root, "/", i->local, ".raw");
if (!i->final_path)
return log_oom();
@@ -355,7 +355,7 @@ static int raw_import_process(RawImport *i) {
}
if (l == 0) {
if (i->compress.type == IMPORT_COMPRESS_UNKNOWN) {
- log_error("Premature end of file: %m");
+ log_error("Premature end of file.");
r = -EIO;
goto finish;
}
@@ -369,7 +369,7 @@ static int raw_import_process(RawImport *i) {
if (i->compress.type == IMPORT_COMPRESS_UNKNOWN) {
r = import_uncompress_detect(&i->compress, i->buffer, i->buffer_size);
if (r < 0) {
- log_error("Failed to detect file compression: %m");
+ log_error_errno(r, "Failed to detect file compression: %m");
goto finish;
}
if (r == 0) /* Need more data */
diff --git a/src/import/import-tar.c b/src/import/import-tar.c
index 22f9b8c5ea..ba140bccbd 100644
--- a/src/import/import-tar.c
+++ b/src/import/import-tar.c
@@ -222,7 +222,7 @@ static int tar_import_fork_tar(TarImport *i) {
assert(!i->temp_path);
assert(i->tar_fd < 0);
- i->final_path = strjoin(i->image_root, "/", i->local, NULL);
+ i->final_path = strjoin(i->image_root, "/", i->local);
if (!i->final_path)
return log_oom();
@@ -284,7 +284,7 @@ static int tar_import_process(TarImport *i) {
}
if (l == 0) {
if (i->compress.type == IMPORT_COMPRESS_UNKNOWN) {
- log_error("Premature end of file: %m");
+ log_error("Premature end of file.");
r = -EIO;
goto finish;
}
@@ -298,7 +298,7 @@ static int tar_import_process(TarImport *i) {
if (i->compress.type == IMPORT_COMPRESS_UNKNOWN) {
r = import_uncompress_detect(&i->compress, i->buffer, i->buffer_size);
if (r < 0) {
- log_error("Failed to detect file compression: %m");
+ log_error_errno(r, "Failed to detect file compression: %m");
goto finish;
}
if (r == 0) /* Need more data */
diff --git a/src/import/importd.c b/src/import/importd.c
index 9d31a956a5..3d379d6de9 100644
--- a/src/import/importd.c
+++ b/src/import/importd.c
@@ -449,8 +449,11 @@ static int transfer_start(Transfer *t) {
stdio_unset_cloexec();
- setenv("SYSTEMD_LOG_TARGET", "console-prefixed", 1);
- setenv("NOTIFY_SOCKET", "/run/systemd/import/notify", 1);
+ if (setenv("SYSTEMD_LOG_TARGET", "console-prefixed", 1) < 0 ||
+ setenv("NOTIFY_SOCKET", "/run/systemd/import/notify", 1) < 0) {
+ log_error_errno(errno, "setenv() failed: %m");
+ _exit(EXIT_FAILURE);
+ }
if (IN_SET(t->type, TRANSFER_IMPORT_TAR, TRANSFER_IMPORT_RAW))
cmd[k++] = SYSTEMD_IMPORT_PATH;
diff --git a/src/import/pull-common.c b/src/import/pull-common.c
index 2ae2a4174c..62a9195cc4 100644
--- a/src/import/pull-common.c
+++ b/src/import/pull-common.c
@@ -144,12 +144,12 @@ int pull_make_local_copy(const char *final, const char *image_root, const char *
if (force_local)
(void) rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
- r = btrfs_subvol_snapshot(final, p, BTRFS_SNAPSHOT_QUOTA);
- if (r == -ENOTTY) {
- r = copy_tree(final, p, false);
- if (r < 0)
- return log_error_errno(r, "Failed to copy image: %m");
- } else if (r < 0)
+ r = btrfs_subvol_snapshot(final, p,
+ BTRFS_SNAPSHOT_QUOTA|
+ BTRFS_SNAPSHOT_FALLBACK_COPY|
+ BTRFS_SNAPSHOT_FALLBACK_DIRECTORY|
+ BTRFS_SNAPSHOT_RECURSIVE);
+ if (r < 0)
return log_error_errno(r, "Failed to create local image: %m");
log_info("Created new local image '%s'.", local);
@@ -218,37 +218,40 @@ int pull_make_path(const char *url, const char *etag, const char *image_root, co
return 0;
}
-int pull_make_settings_job(
+int pull_make_auxiliary_job(
PullJob **ret,
const char *url,
+ int (*strip_suffixes)(const char *name, char **ret),
+ const char *suffix,
CurlGlue *glue,
PullJobFinished on_finished,
void *userdata) {
- _cleanup_free_ char *last_component = NULL, *ll = NULL, *settings_url = NULL;
+ _cleanup_free_ char *last_component = NULL, *ll = NULL, *auxiliary_url = NULL;
_cleanup_(pull_job_unrefp) PullJob *job = NULL;
const char *q;
int r;
assert(ret);
assert(url);
+ assert(strip_suffixes);
assert(glue);
r = import_url_last_component(url, &last_component);
if (r < 0)
return r;
- r = tar_strip_suffixes(last_component, &ll);
+ r = strip_suffixes(last_component, &ll);
if (r < 0)
return r;
- q = strjoina(ll, ".nspawn");
+ q = strjoina(ll, suffix);
- r = import_url_change_last_component(url, q, &settings_url);
+ r = import_url_change_last_component(url, q, &auxiliary_url);
if (r < 0)
return r;
- r = pull_job_new(&job, settings_url, glue, userdata);
+ r = pull_job_new(&job, auxiliary_url, glue, userdata);
if (r < 0)
return r;
@@ -320,45 +323,39 @@ int pull_make_verification_jobs(
return 0;
}
-int pull_verify(PullJob *main_job,
- PullJob *settings_job,
- PullJob *checksum_job,
- PullJob *signature_job) {
-
- _cleanup_close_pair_ int gpg_pipe[2] = { -1, -1 };
+static int verify_one(PullJob *checksum_job, PullJob *job) {
_cleanup_free_ char *fn = NULL;
- _cleanup_close_ int sig_file = -1;
- const char *p, *line;
- char sig_file_path[] = "/tmp/sigXXXXXX", gpg_home[] = "/tmp/gpghomeXXXXXX";
- _cleanup_(sigkill_waitp) pid_t pid = 0;
- bool gpg_home_created = false;
+ const char *line, *p;
int r;
- assert(main_job);
- assert(main_job->state == PULL_JOB_DONE);
+ assert(checksum_job);
- if (!checksum_job)
+ if (!job)
return 0;
- assert(main_job->calc_checksum);
- assert(main_job->checksum);
- assert(checksum_job->state == PULL_JOB_DONE);
+ assert(IN_SET(job->state, PULL_JOB_DONE, PULL_JOB_FAILED));
- if (!checksum_job->payload || checksum_job->payload_size <= 0) {
- log_error("Checksum is empty, cannot verify.");
- return -EBADMSG;
- }
+ /* Don't verify the checksum if we didn't actually successfully download something new */
+ if (job->state != PULL_JOB_DONE)
+ return 0;
+ if (job->error != 0)
+ return 0;
+ if (job->etag_exists)
+ return 0;
+
+ assert(job->calc_checksum);
+ assert(job->checksum);
- r = import_url_last_component(main_job->url, &fn);
+ r = import_url_last_component(job->url, &fn);
if (r < 0)
return log_oom();
if (!filename_is_valid(fn)) {
- log_error("Cannot verify checksum, could not determine valid server-side file name.");
+ log_error("Cannot verify checksum, could not determine server-side file name.");
return -EBADMSG;
}
- line = strjoina(main_job->checksum, " *", fn, "\n");
+ line = strjoina(job->checksum, " *", fn, "\n");
p = memmem(checksum_job->payload,
checksum_job->payload_size,
@@ -366,47 +363,55 @@ int pull_verify(PullJob *main_job,
strlen(line));
if (!p || (p != (char*) checksum_job->payload && p[-1] != '\n')) {
- log_error("DOWNLOAD INVALID: Checksum did not check out, payload has been tampered with.");
+ log_error("DOWNLOAD INVALID: Checksum of %s file did not checkout, file has been tampered with.", fn);
return -EBADMSG;
}
- log_info("SHA256 checksum of %s is valid.", main_job->url);
+ log_info("SHA256 checksum of %s is valid.", job->url);
+ return 1;
+}
- assert(!settings_job || IN_SET(settings_job->state, PULL_JOB_DONE, PULL_JOB_FAILED));
+int pull_verify(PullJob *main_job,
+ PullJob *roothash_job,
+ PullJob *settings_job,
+ PullJob *checksum_job,
+ PullJob *signature_job) {
- if (settings_job &&
- settings_job->state == PULL_JOB_DONE &&
- settings_job->error == 0 &&
- !settings_job->etag_exists) {
+ _cleanup_close_pair_ int gpg_pipe[2] = { -1, -1 };
+ _cleanup_free_ char *fn = NULL;
+ _cleanup_close_ int sig_file = -1;
+ char sig_file_path[] = "/tmp/sigXXXXXX", gpg_home[] = "/tmp/gpghomeXXXXXX";
+ _cleanup_(sigkill_waitp) pid_t pid = 0;
+ bool gpg_home_created = false;
+ int r;
- _cleanup_free_ char *settings_fn = NULL;
+ assert(main_job);
+ assert(main_job->state == PULL_JOB_DONE);
- assert(settings_job->calc_checksum);
- assert(settings_job->checksum);
+ if (!checksum_job)
+ return 0;
- r = import_url_last_component(settings_job->url, &settings_fn);
- if (r < 0)
- return log_oom();
+ assert(main_job->calc_checksum);
+ assert(main_job->checksum);
- if (!filename_is_valid(settings_fn)) {
- log_error("Cannot verify checksum, could not determine server-side settings file name.");
- return -EBADMSG;
- }
+ assert(checksum_job->state == PULL_JOB_DONE);
- line = strjoina(settings_job->checksum, " *", settings_fn, "\n");
+ if (!checksum_job->payload || checksum_job->payload_size <= 0) {
+ log_error("Checksum is empty, cannot verify.");
+ return -EBADMSG;
+ }
- p = memmem(checksum_job->payload,
- checksum_job->payload_size,
- line,
- strlen(line));
+ r = verify_one(checksum_job, main_job);
+ if (r < 0)
+ return r;
- if (!p || (p != (char*) checksum_job->payload && p[-1] != '\n')) {
- log_error("DOWNLOAD INVALID: Checksum of settings file did not checkout, settings file has been tampered with.");
- return -EBADMSG;
- }
+ r = verify_one(checksum_job, roothash_job);
+ if (r < 0)
+ return r;
- log_info("SHA256 checksum of %s is valid.", settings_job->url);
- }
+ r = verify_one(checksum_job, settings_job);
+ if (r < 0)
+ return r;
if (!signature_job)
return 0;
diff --git a/src/import/pull-common.h b/src/import/pull-common.h
index 929a131c88..f1f1a17fa9 100644
--- a/src/import/pull-common.h
+++ b/src/import/pull-common.h
@@ -30,7 +30,7 @@ int pull_find_old_etags(const char *url, const char *root, int dt, const char *p
int pull_make_path(const char *url, const char *etag, const char *image_root, const char *prefix, const char *suffix, char **ret);
-int pull_make_settings_job(PullJob **ret, const char *url, CurlGlue *glue, PullJobFinished on_finished, void *userdata);
+int pull_make_auxiliary_job(PullJob **ret, const char *url, int (*strip_suffixes)(const char *name, char **ret), const char *suffix, CurlGlue *glue, PullJobFinished on_finished, void *userdata);
int pull_make_verification_jobs(PullJob **ret_checksum_job, PullJob **ret_signature_job, ImportVerify verify, const char *url, CurlGlue *glue, PullJobFinished on_finished, void *userdata);
-int pull_verify(PullJob *main_job, PullJob *settings_job, PullJob *checksum_job, PullJob *signature_job);
+int pull_verify(PullJob *main_job, PullJob *roothash_job, PullJob *settings_job, PullJob *checksum_job, PullJob *signature_job);
diff --git a/src/import/pull-job.c b/src/import/pull-job.c
index e550df2c57..70aaa5c291 100644
--- a/src/import/pull-job.c
+++ b/src/import/pull-job.c
@@ -527,7 +527,7 @@ int pull_job_new(PullJob **ret, const char *url, CurlGlue *glue, void *userdata)
j->glue = glue;
j->content_length = (uint64_t) -1;
j->start_usec = now(CLOCK_MONOTONIC);
- j->compressed_max = j->uncompressed_max = 8LLU * 1024LLU * 1024LLU * 1024LLU; /* 8GB */
+ j->compressed_max = j->uncompressed_max = 64LLU * 1024LLU * 1024LLU * 1024LLU; /* 64GB safety limit */
j->url = strdup(url);
if (!j->url)
diff --git a/src/import/pull-raw.c b/src/import/pull-raw.c
index 0cf410a5d9..60a769e944 100644
--- a/src/import/pull-raw.c
+++ b/src/import/pull-raw.c
@@ -63,6 +63,7 @@ struct RawPull {
char *image_root;
PullJob *raw_job;
+ PullJob *roothash_job;
PullJob *settings_job;
PullJob *checksum_job;
PullJob *signature_job;
@@ -74,6 +75,7 @@ struct RawPull {
bool force_local;
bool grow_machine_directory;
bool settings;
+ bool roothash;
char *final_path;
char *temp_path;
@@ -81,6 +83,9 @@ struct RawPull {
char *settings_path;
char *settings_temp_path;
+ char *roothash_path;
+ char *roothash_temp_path;
+
ImportVerify verify;
};
@@ -90,6 +95,7 @@ RawPull* raw_pull_unref(RawPull *i) {
pull_job_unref(i->raw_job);
pull_job_unref(i->settings_job);
+ pull_job_unref(i->roothash_job);
pull_job_unref(i->checksum_job);
pull_job_unref(i->signature_job);
@@ -101,12 +107,18 @@ RawPull* raw_pull_unref(RawPull *i) {
free(i->temp_path);
}
+ if (i->roothash_temp_path) {
+ (void) unlink(i->roothash_temp_path);
+ free(i->roothash_temp_path);
+ }
+
if (i->settings_temp_path) {
(void) unlink(i->settings_temp_path);
free(i->settings_temp_path);
}
free(i->final_path);
+ free(i->roothash_path);
free(i->settings_path);
free(i->image_root);
free(i->local);
@@ -176,6 +188,11 @@ static void raw_pull_report_progress(RawPull *i, RawProgress p) {
remain -= 5;
}
+ if (i->roothash_job) {
+ percent += i->roothash_job->progress_percent * 5 / 100;
+ remain -= 5;
+ }
+
if (i->checksum_job) {
percent += i->checksum_job->progress_percent * 5 / 100;
remain -= 5;
@@ -262,6 +279,55 @@ static int raw_pull_maybe_convert_qcow2(RawPull *i) {
return 1;
}
+static int raw_pull_determine_path(RawPull *i, const char *suffix, char **field) {
+ int r;
+
+ assert(i);
+ assert(field);
+
+ if (*field)
+ return 0;
+
+ assert(i->raw_job);
+
+ r = pull_make_path(i->raw_job->url, i->raw_job->etag, i->image_root, ".raw-", suffix, field);
+ if (r < 0)
+ return log_oom();
+
+ return 1;
+}
+
+static int raw_pull_copy_auxiliary_file(
+ RawPull *i,
+ const char *suffix,
+ char **path) {
+
+ const char *local;
+ int r;
+
+ assert(i);
+ assert(suffix);
+ assert(path);
+
+ r = raw_pull_determine_path(i, suffix, path);
+ if (r < 0)
+ return r;
+
+ local = strjoina(i->image_root, "/", i->local, suffix);
+
+ r = copy_file_atomic(*path, local, 0644, 0, COPY_REFLINK | (i->force_local ? COPY_REPLACE : 0));
+ if (r == -EEXIST)
+ log_warning_errno(r, "File %s already exists, not replacing.", local);
+ else if (r == -ENOENT)
+ log_debug_errno(r, "Skipping creation of auxiliary file, since none was found.");
+ else if (r < 0)
+ log_warning_errno(r, "Failed to copy file %s, ignoring: %m", local);
+ else
+ log_info("Created new file %s.", local);
+
+ return 0;
+}
+
static int raw_pull_make_local_copy(RawPull *i) {
_cleanup_free_ char *tp = NULL;
_cleanup_close_ int dfd = -1;
@@ -274,12 +340,6 @@ static int raw_pull_make_local_copy(RawPull *i) {
if (!i->local)
return 0;
- if (!i->final_path) {
- r = pull_make_path(i->raw_job->url, i->raw_job->etag, i->image_root, ".raw-", ".raw", &i->final_path);
- if (r < 0)
- return log_oom();
- }
-
if (i->raw_job->etag_exists) {
/* We have downloaded this one previously, reopen it */
@@ -318,7 +378,7 @@ static int raw_pull_make_local_copy(RawPull *i) {
if (r < 0)
log_warning_errno(r, "Failed to set file attributes on %s: %m", tp);
- r = copy_bytes(i->raw_job->disk_fd, dfd, (uint64_t) -1, true);
+ r = copy_bytes(i->raw_job->disk_fd, dfd, (uint64_t) -1, COPY_REFLINK);
if (r < 0) {
unlink(tp);
return log_error_errno(r, "Failed to make writable copy of image: %m");
@@ -338,27 +398,16 @@ static int raw_pull_make_local_copy(RawPull *i) {
log_info("Created new local image '%s'.", i->local);
- if (i->settings) {
- const char *local_settings;
- assert(i->settings_job);
-
- if (!i->settings_path) {
- r = pull_make_path(i->settings_job->url, i->settings_job->etag, i->image_root, ".settings-", NULL, &i->settings_path);
- if (r < 0)
- return log_oom();
- }
-
- local_settings = strjoina(i->image_root, "/", i->local, ".nspawn");
+ if (i->roothash) {
+ r = raw_pull_copy_auxiliary_file(i, ".roothash", &i->roothash_path);
+ if (r < 0)
+ return r;
+ }
- r = copy_file_atomic(i->settings_path, local_settings, 0644, i->force_local, 0);
- if (r == -EEXIST)
- log_warning_errno(r, "Settings file %s already exists, not replacing.", local_settings);
- else if (r == -ENOENT)
- log_debug_errno(r, "Skipping creation of settings file, since none was found.");
- else if (r < 0)
- log_warning_errno(r, "Failed to copy settings files %s, ignoring: %m", local_settings);
- else
- log_info("Created new settings file %s.", local_settings);
+ if (i->settings) {
+ r = raw_pull_copy_auxiliary_file(i, ".nspawn", &i->settings_path);
+ if (r < 0)
+ return r;
}
return 0;
@@ -370,6 +419,8 @@ static bool raw_pull_is_done(RawPull *i) {
if (!PULL_JOB_IS_COMPLETE(i->raw_job))
return false;
+ if (i->roothash_job && !PULL_JOB_IS_COMPLETE(i->roothash_job))
+ return false;
if (i->settings_job && !PULL_JOB_IS_COMPLETE(i->settings_job))
return false;
if (i->checksum_job && !PULL_JOB_IS_COMPLETE(i->checksum_job))
@@ -380,6 +431,39 @@ static bool raw_pull_is_done(RawPull *i) {
return true;
}
+static int raw_pull_rename_auxiliary_file(
+ RawPull *i,
+ const char *suffix,
+ char **temp_path,
+ char **path) {
+
+ int r;
+
+ assert(i);
+ assert(temp_path);
+ assert(suffix);
+ assert(path);
+
+ /* Regenerate final name for this auxiliary file, we might know the etag of the raw file now, and we shoud
+ * incorporate it in the file name if we can */
+ *path = mfree(*path);
+ r = raw_pull_determine_path(i, suffix, path);
+ if (r < 0)
+ return r;
+
+ r = import_make_read_only(*temp_path);
+ if (r < 0)
+ return r;
+
+ r = rename_noreplace(AT_FDCWD, *temp_path, AT_FDCWD, *path);
+ if (r < 0)
+ return log_error_errno(r, "Failed to rename file %s to %s: %m", *temp_path, *path);
+
+ *temp_path = mfree(*temp_path);
+
+ return 1;
+}
+
static void raw_pull_job_on_finished(PullJob *j) {
RawPull *i;
int r;
@@ -388,7 +472,10 @@ static void raw_pull_job_on_finished(PullJob *j) {
assert(j->userdata);
i = j->userdata;
- if (j == i->settings_job) {
+ if (j == i->roothash_job) {
+ if (j->error != 0)
+ log_info_errno(j->error, "Root hash file could not be retrieved, proceeding without.");
+ } else if (j == i->settings_job) {
if (j->error != 0)
log_info_errno(j->error, "Settings file could not be retrieved, proceeding without.");
} else if (j->error != 0) {
@@ -413,16 +500,22 @@ static void raw_pull_job_on_finished(PullJob *j) {
if (!raw_pull_is_done(i))
return;
+ if (i->roothash_job)
+ i->roothash_job->disk_fd = safe_close(i->roothash_job->disk_fd);
if (i->settings_job)
i->settings_job->disk_fd = safe_close(i->settings_job->disk_fd);
+ r = raw_pull_determine_path(i, ".raw", &i->final_path);
+ if (r < 0)
+ goto finish;
+
if (!i->raw_job->etag_exists) {
/* This is a new download, verify it, and move it into place */
assert(i->raw_job->disk_fd >= 0);
raw_pull_report_progress(i, RAW_VERIFYING);
- r = pull_verify(i->raw_job, i->settings_job, i->checksum_job, i->signature_job);
+ r = pull_verify(i->raw_job, i->roothash_job, i->settings_job, i->checksum_job, i->signature_job);
if (r < 0)
goto finish;
@@ -446,24 +539,18 @@ static void raw_pull_job_on_finished(PullJob *j) {
i->temp_path = mfree(i->temp_path);
- if (i->settings_job &&
- i->settings_job->error == 0 &&
- !i->settings_job->etag_exists) {
-
- assert(i->settings_temp_path);
- assert(i->settings_path);
-
- r = import_make_read_only(i->settings_temp_path);
+ if (i->roothash_job &&
+ i->roothash_job->error == 0) {
+ r = raw_pull_rename_auxiliary_file(i, ".roothash", &i->roothash_temp_path, &i->roothash_path);
if (r < 0)
goto finish;
+ }
- r = rename_noreplace(AT_FDCWD, i->settings_temp_path, AT_FDCWD, i->settings_path);
- if (r < 0) {
- log_error_errno(r, "Failed to rename settings file: %m");
+ if (i->settings_job &&
+ i->settings_job->error == 0) {
+ r = raw_pull_rename_auxiliary_file(i, ".nspawn", &i->settings_temp_path, &i->settings_path);
+ if (r < 0)
goto finish;
- }
-
- i->settings_temp_path = mfree(i->settings_temp_path);
}
}
@@ -482,6 +569,35 @@ finish:
sd_event_exit(i->event, r);
}
+static int raw_pull_job_on_open_disk_generic(
+ RawPull *i,
+ PullJob *j,
+ const char *extra,
+ char **temp_path) {
+
+ _cleanup_free_ char *p = NULL;
+ int r;
+
+ assert(i);
+ assert(j);
+ assert(extra);
+ assert(temp_path);
+
+ if (!*temp_path) {
+ r = tempfn_random_child(i->image_root, extra, temp_path);
+ if (r < 0)
+ return log_oom();
+ }
+
+ (void) mkdir_parents_label(*temp_path, 0700);
+
+ j->disk_fd = open(*temp_path, O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0664);
+ if (j->disk_fd < 0)
+ return log_error_errno(errno, "Failed to create %s: %m", *temp_path);
+
+ return 0;
+}
+
static int raw_pull_job_on_open_disk_raw(PullJob *j) {
RawPull *i;
int r;
@@ -491,57 +607,40 @@ static int raw_pull_job_on_open_disk_raw(PullJob *j) {
i = j->userdata;
assert(i->raw_job == j);
- assert(!i->final_path);
- assert(!i->temp_path);
-
- r = pull_make_path(j->url, j->etag, i->image_root, ".raw-", ".raw", &i->final_path);
- if (r < 0)
- return log_oom();
- r = tempfn_random(i->final_path, NULL, &i->temp_path);
+ r = raw_pull_job_on_open_disk_generic(i, j, "raw", &i->temp_path);
if (r < 0)
- return log_oom();
-
- (void) mkdir_parents_label(i->temp_path, 0700);
-
- j->disk_fd = open(i->temp_path, O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0664);
- if (j->disk_fd < 0)
- return log_error_errno(errno, "Failed to create %s: %m", i->temp_path);
+ return r;
r = chattr_fd(j->disk_fd, FS_NOCOW_FL, FS_NOCOW_FL);
if (r < 0)
- log_warning_errno(r, "Failed to set file attributes on %s: %m", i->temp_path);
+ log_warning_errno(r, "Failed to set file attributes on %s, ignoring: %m", i->temp_path);
return 0;
}
-static int raw_pull_job_on_open_disk_settings(PullJob *j) {
+static int raw_pull_job_on_open_disk_roothash(PullJob *j) {
RawPull *i;
- int r;
assert(j);
assert(j->userdata);
i = j->userdata;
- assert(i->settings_job == j);
- assert(!i->settings_path);
- assert(!i->settings_temp_path);
+ assert(i->roothash_job == j);
- r = pull_make_path(j->url, j->etag, i->image_root, ".settings-", NULL, &i->settings_path);
- if (r < 0)
- return log_oom();
+ return raw_pull_job_on_open_disk_generic(i, j, "roothash", &i->roothash_temp_path);
+}
- r = tempfn_random(i->settings_path, NULL, &i->settings_temp_path);
- if (r < 0)
- return log_oom();
+static int raw_pull_job_on_open_disk_settings(PullJob *j) {
+ RawPull *i;
- mkdir_parents_label(i->settings_temp_path, 0700);
+ assert(j);
+ assert(j->userdata);
- j->disk_fd = open(i->settings_temp_path, O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0664);
- if (j->disk_fd < 0)
- return log_error_errno(errno, "Failed to create %s: %m", i->settings_temp_path);
+ i = j->userdata;
+ assert(i->settings_job == j);
- return 0;
+ return raw_pull_job_on_open_disk_generic(i, j, "settings", &i->settings_temp_path);
}
static void raw_pull_job_on_progress(PullJob *j) {
@@ -561,7 +660,8 @@ int raw_pull_start(
const char *local,
bool force_local,
ImportVerify verify,
- bool settings) {
+ bool settings,
+ bool roothash) {
int r;
@@ -585,6 +685,7 @@ int raw_pull_start(
i->force_local = force_local;
i->verify = verify;
i->settings = settings;
+ i->roothash = roothash;
/* Queue job for the image itself */
r = pull_job_new(&i->raw_job, url, i->glue, i);
@@ -601,18 +702,24 @@ int raw_pull_start(
if (r < 0)
return r;
+ if (roothash) {
+ r = pull_make_auxiliary_job(&i->roothash_job, url, raw_strip_suffixes, ".roothash", i->glue, raw_pull_job_on_finished, i);
+ if (r < 0)
+ return r;
+
+ i->roothash_job->on_open_disk = raw_pull_job_on_open_disk_roothash;
+ i->roothash_job->on_progress = raw_pull_job_on_progress;
+ i->roothash_job->calc_checksum = verify != IMPORT_VERIFY_NO;
+ }
+
if (settings) {
- r = pull_make_settings_job(&i->settings_job, url, i->glue, raw_pull_job_on_finished, i);
+ r = pull_make_auxiliary_job(&i->settings_job, url, raw_strip_suffixes, ".nspawn", i->glue, raw_pull_job_on_finished, i);
if (r < 0)
return r;
i->settings_job->on_open_disk = raw_pull_job_on_open_disk_settings;
i->settings_job->on_progress = raw_pull_job_on_progress;
i->settings_job->calc_checksum = verify != IMPORT_VERIFY_NO;
-
- r = pull_find_old_etags(i->settings_job->url, i->image_root, DT_REG, ".settings-", NULL, &i->settings_job->old_etags);
- if (r < 0)
- return r;
}
r = pull_make_verification_jobs(&i->checksum_job, &i->signature_job, verify, url, i->glue, raw_pull_job_on_finished, i);
@@ -623,6 +730,12 @@ int raw_pull_start(
if (r < 0)
return r;
+ if (i->roothash_job) {
+ r = pull_job_begin(i->roothash_job);
+ if (r < 0)
+ return r;
+ }
+
if (i->settings_job) {
r = pull_job_begin(i->settings_job);
if (r < 0)
diff --git a/src/import/pull-raw.h b/src/import/pull-raw.h
index 8f6d16eb3a..6954d98994 100644
--- a/src/import/pull-raw.h
+++ b/src/import/pull-raw.h
@@ -33,4 +33,4 @@ RawPull* raw_pull_unref(RawPull *pull);
DEFINE_TRIVIAL_CLEANUP_FUNC(RawPull*, raw_pull_unref);
-int raw_pull_start(RawPull *pull, const char *url, const char *local, bool force_local, ImportVerify verify, bool settings);
+int raw_pull_start(RawPull *pull, const char *url, const char *local, bool force_local, ImportVerify verify, bool settings, bool roothash);
diff --git a/src/import/pull-tar.c b/src/import/pull-tar.c
index 68e2397b02..91833d6174 100644
--- a/src/import/pull-tar.c
+++ b/src/import/pull-tar.c
@@ -215,6 +215,24 @@ static void tar_pull_report_progress(TarPull *i, TarProgress p) {
log_debug("Combined progress %u%%", percent);
}
+static int tar_pull_determine_path(TarPull *i, const char *suffix, char **field) {
+ int r;
+
+ assert(i);
+ assert(field);
+
+ if (*field)
+ return 0;
+
+ assert(i->tar_job);
+
+ r = pull_make_path(i->tar_job->url, i->tar_job->etag, i->image_root, ".tar-", suffix, field);
+ if (r < 0)
+ return log_oom();
+
+ return 1;
+}
+
static int tar_pull_make_local_copy(TarPull *i) {
int r;
@@ -224,12 +242,6 @@ static int tar_pull_make_local_copy(TarPull *i) {
if (!i->local)
return 0;
- if (!i->final_path) {
- r = pull_make_path(i->tar_job->url, i->tar_job->etag, i->image_root, ".tar-", NULL, &i->final_path);
- if (r < 0)
- return log_oom();
- }
-
r = pull_make_local_copy(i->final_path, i->image_root, i->local, i->force_local);
if (r < 0)
return r;
@@ -238,15 +250,13 @@ static int tar_pull_make_local_copy(TarPull *i) {
const char *local_settings;
assert(i->settings_job);
- if (!i->settings_path) {
- r = pull_make_path(i->settings_job->url, i->settings_job->etag, i->image_root, ".settings-", NULL, &i->settings_path);
- if (r < 0)
- return log_oom();
- }
+ r = tar_pull_determine_path(i, ".nspawn", &i->settings_path);
+ if (r < 0)
+ return r;
local_settings = strjoina(i->image_root, "/", i->local, ".nspawn");
- r = copy_file_atomic(i->settings_path, local_settings, 0664, i->force_local, 0);
+ r = copy_file_atomic(i->settings_path, local_settings, 0664, 0, COPY_REFLINK | (i->force_local ? COPY_REPLACE : 0));
if (r == -EEXIST)
log_warning_errno(r, "Settings file %s already exists, not replacing.", local_settings);
else if (r == -ENOENT)
@@ -311,6 +321,10 @@ static void tar_pull_job_on_finished(PullJob *j) {
if (i->settings_job)
i->settings_job->disk_fd = safe_close(i->settings_job->disk_fd);
+ r = tar_pull_determine_path(i, NULL, &i->final_path);
+ if (r < 0)
+ goto finish;
+
if (i->tar_pid > 0) {
r = wait_for_terminate_and_warn("tar", i->tar_pid, true);
i->tar_pid = 0;
@@ -327,7 +341,7 @@ static void tar_pull_job_on_finished(PullJob *j) {
tar_pull_report_progress(i, TAR_VERIFYING);
- r = pull_verify(i->tar_job, i->settings_job, i->checksum_job, i->signature_job);
+ r = pull_verify(i->tar_job, NULL, i->settings_job, i->checksum_job, i->signature_job);
if (r < 0)
goto finish;
@@ -346,16 +360,18 @@ static void tar_pull_job_on_finished(PullJob *j) {
i->temp_path = mfree(i->temp_path);
if (i->settings_job &&
- i->settings_job->error == 0 &&
- !i->settings_job->etag_exists) {
+ i->settings_job->error == 0) {
assert(i->settings_temp_path);
assert(i->settings_path);
- /* Also move the settings file into place, if
- * it exist. Note that we do so only if we
- * also moved the tar file in place, to keep
- * things strictly in sync. */
+ /* Also move the settings file into place, if it exist. Note that we do so only if we also
+ * moved the tar file in place, to keep things strictly in sync. */
+
+ i->settings_path = mfree(i->settings_path);
+ r = tar_pull_determine_path(i, ".nspawn", &i->settings_path);
+ if (r < 0)
+ goto finish;
r = import_make_read_only(i->settings_temp_path);
if (r < 0)
@@ -395,17 +411,13 @@ static int tar_pull_job_on_open_disk_tar(PullJob *j) {
i = j->userdata;
assert(i->tar_job == j);
- assert(!i->final_path);
- assert(!i->temp_path);
assert(i->tar_pid <= 0);
- r = pull_make_path(j->url, j->etag, i->image_root, ".tar-", NULL, &i->final_path);
- if (r < 0)
- return log_oom();
-
- r = tempfn_random(i->final_path, NULL, &i->temp_path);
- if (r < 0)
- return log_oom();
+ if (!i->temp_path) {
+ r = tempfn_random_child(i->image_root, "tar", &i->temp_path);
+ if (r < 0)
+ return log_oom();
+ }
mkdir_parents_label(i->temp_path, 0700);
@@ -434,16 +446,12 @@ static int tar_pull_job_on_open_disk_settings(PullJob *j) {
i = j->userdata;
assert(i->settings_job == j);
- assert(!i->settings_path);
- assert(!i->settings_temp_path);
- r = pull_make_path(j->url, j->etag, i->image_root, ".settings-", NULL, &i->settings_path);
- if (r < 0)
- return log_oom();
-
- r = tempfn_random(i->settings_path, NULL, &i->settings_temp_path);
- if (r < 0)
- return log_oom();
+ if (!i->settings_temp_path) {
+ r = tempfn_random_child(i->image_root, "settings", &i->settings_temp_path);
+ if (r < 0)
+ return log_oom();
+ }
mkdir_parents_label(i->settings_temp_path, 0700);
@@ -513,17 +521,13 @@ int tar_pull_start(
/* Set up download job for the settings file (.nspawn) */
if (settings) {
- r = pull_make_settings_job(&i->settings_job, url, i->glue, tar_pull_job_on_finished, i);
+ r = pull_make_auxiliary_job(&i->settings_job, url, tar_strip_suffixes, ".nspawn", i->glue, tar_pull_job_on_finished, i);
if (r < 0)
return r;
i->settings_job->on_open_disk = tar_pull_job_on_open_disk_settings;
i->settings_job->on_progress = tar_pull_job_on_progress;
i->settings_job->calc_checksum = verify != IMPORT_VERIFY_NO;
-
- r = pull_find_old_etags(i->settings_job->url, i->image_root, DT_REG, ".settings-", NULL, &i->settings_job->old_etags);
- if (r < 0)
- return r;
}
/* Set up download of checksum/signature files */
diff --git a/src/import/pull.c b/src/import/pull.c
index 53b1211965..4af5d9c853 100644
--- a/src/import/pull.c
+++ b/src/import/pull.c
@@ -37,6 +37,7 @@ static bool arg_force = false;
static const char *arg_image_root = "/var/lib/machines";
static ImportVerify arg_verify = IMPORT_VERIFY_SIGNATURE;
static bool arg_settings = true;
+static bool arg_roothash = true;
static int interrupt_signal_handler(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
log_notice("Transfer aborted.");
@@ -204,7 +205,7 @@ static int pull_raw(int argc, char *argv[], void *userdata) {
if (r < 0)
return log_error_errno(r, "Failed to allocate puller: %m");
- r = raw_pull_start(pull, url, local, arg_force, arg_verify, arg_settings);
+ r = raw_pull_start(pull, url, local, arg_force, arg_verify, arg_settings, arg_roothash);
if (r < 0)
return log_error_errno(r, "Failed to pull image: %m");
@@ -226,6 +227,7 @@ static int help(int argc, char *argv[], void *userdata) {
" --verify=MODE Verify downloaded image, one of: 'no',\n"
" 'checksum', 'signature'\n"
" --settings=BOOL Download settings file with image\n"
+ " --roothash=BOOL Download root hash file with image\n"
" --image-root=PATH Image root directory\n\n"
"Commands:\n"
" tar URL [NAME] Download a TAR image\n"
@@ -243,6 +245,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_IMAGE_ROOT,
ARG_VERIFY,
ARG_SETTINGS,
+ ARG_ROOTHASH,
};
static const struct option options[] = {
@@ -252,6 +255,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "image-root", required_argument, NULL, ARG_IMAGE_ROOT },
{ "verify", required_argument, NULL, ARG_VERIFY },
{ "settings", required_argument, NULL, ARG_SETTINGS },
+ { "roothash", required_argument, NULL, ARG_ROOTHASH },
{}
};
@@ -295,6 +299,14 @@ static int parse_argv(int argc, char *argv[]) {
arg_settings = r;
break;
+ case ARG_ROOTHASH:
+ r = parse_boolean(optarg);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse --roothash= parameter '%s'", optarg);
+
+ arg_roothash = r;
+ break;
+
case '?':
return -EINVAL;
diff --git a/src/initctl/initctl.c b/src/initctl/initctl.c
index 41b2237d16..6aeb5ad614 100644
--- a/src/initctl/initctl.c
+++ b/src/initctl/initctl.c
@@ -31,7 +31,7 @@
#include "bus-util.h"
#include "def.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "initreq.h"
#include "list.h"
#include "log.h"
diff --git a/src/journal-remote/journal-gatewayd.c b/src/journal-remote/journal-gatewayd.c
index 6611a355d4..93e5f1ae7d 100644
--- a/src/journal-remote/journal-gatewayd.c
+++ b/src/journal-remote/journal-gatewayd.c
@@ -434,7 +434,7 @@ static int request_parse_arguments_iterator(
return MHD_YES;
}
- p = strjoin(key, "=", strempty(value), NULL);
+ p = strjoin(key, "=", strempty(value));
if (!p) {
m->argument_parse_error = log_oom();
return MHD_NO;
@@ -905,14 +905,14 @@ static int parse_argv(int argc, char *argv[]) {
{ "key", required_argument, NULL, ARG_KEY },
{ "cert", required_argument, NULL, ARG_CERT },
{ "trust", required_argument, NULL, ARG_TRUST },
- { "directory", required_argument, NULL, 'D' },
+ { "directory", required_argument, NULL, 'D' },
{}
};
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
+ while ((c = getopt_long(argc, argv, "hD:", options, NULL)) >= 0)
switch(c) {
@@ -958,6 +958,7 @@ static int parse_argv(int argc, char *argv[]) {
break;
#else
log_error("Option --trust is not available.");
+ return -EINVAL;
#endif
case 'D':
arg_directory = optarg;
@@ -1028,10 +1029,9 @@ int main(int argc, char *argv[]) {
{ MHD_OPTION_END, 0, NULL }};
int opts_pos = 2;
- /* We force MHD_USE_PIPE_FOR_SHUTDOWN here, in order
- * to make sure libmicrohttpd doesn't use shutdown()
- * on our listening socket, which would break socket
- * re-activation. See
+ /* We force MHD_USE_ITC here, in order to make sure
+ * libmicrohttpd doesn't use shutdown() on our listening
+ * socket, which would break socket re-activation. See
*
* https://lists.gnu.org/archive/html/libmicrohttpd/2015-09/msg00014.html
* https://github.com/systemd/systemd/pull/1286
@@ -1040,7 +1040,7 @@ int main(int argc, char *argv[]) {
int flags =
MHD_USE_DEBUG |
MHD_USE_DUAL_STACK |
- MHD_USE_PIPE_FOR_SHUTDOWN |
+ MHD_USE_ITC |
MHD_USE_POLL |
MHD_USE_THREAD_PER_CONNECTION;
diff --git a/src/journal-remote/journal-remote-parse.c b/src/journal-remote/journal-remote-parse.c
index 9ba9ee3fc0..d61d1c18f6 100644
--- a/src/journal-remote/journal-remote-parse.c
+++ b/src/journal-remote/journal-remote-parse.c
@@ -24,20 +24,11 @@
#include "parse-util.h"
#include "string-util.h"
-#define LINE_CHUNK 8*1024u
-
void source_free(RemoteSource *source) {
if (!source)
return;
- if (source->fd >= 0 && !source->passive_fd) {
- log_debug("Closing fd:%d (%s)", source->fd, source->name);
- safe_close(source->fd);
- }
-
- free(source->name);
- free(source->buf);
- iovw_free_contents(&source->iovw);
+ journal_importer_cleanup(&source->importer);
log_debug("Writer ref count %i", source->writer->n_ref);
writer_unref(source->writer);
@@ -50,7 +41,7 @@ void source_free(RemoteSource *source) {
/**
* Initialize zero-filled source with given values. On success, takes
- * ownerhship of fd and writer, otherwise does not touch them.
+ * ownership of fd, name, and writer, otherwise does not touch them.
*/
RemoteSource* source_new(int fd, bool passive_fd, char *name, Writer *writer) {
@@ -65,442 +56,44 @@ RemoteSource* source_new(int fd, bool passive_fd, char *name, Writer *writer) {
if (!source)
return NULL;
- source->fd = fd;
- source->passive_fd = passive_fd;
- source->name = name;
+ source->importer.fd = fd;
+ source->importer.passive_fd = passive_fd;
+ source->importer.name = name;
+
source->writer = writer;
return source;
}
-static char* realloc_buffer(RemoteSource *source, size_t size) {
- char *b, *old = source->buf;
-
- b = GREEDY_REALLOC(source->buf, source->size, size);
- if (!b)
- return NULL;
-
- iovw_rebase(&source->iovw, old, source->buf);
-
- return b;
-}
-
-static int get_line(RemoteSource *source, char **line, size_t *size) {
- ssize_t n;
- char *c = NULL;
-
- assert(source);
- assert(source->state == STATE_LINE);
- assert(source->offset <= source->filled);
- assert(source->filled <= source->size);
- assert(source->buf == NULL || source->size > 0);
- assert(source->fd >= 0);
-
- for (;;) {
- if (source->buf) {
- size_t start = MAX(source->scanned, source->offset);
-
- c = memchr(source->buf + start, '\n',
- source->filled - start);
- if (c != NULL)
- break;
- }
-
- source->scanned = source->filled;
- if (source->scanned >= DATA_SIZE_MAX) {
- log_error("Entry is bigger than %u bytes.", DATA_SIZE_MAX);
- return -E2BIG;
- }
-
- if (source->passive_fd)
- /* we have to wait for some data to come to us */
- return -EAGAIN;
-
- /* We know that source->filled is at most DATA_SIZE_MAX, so if
- we reallocate it, we'll increase the size at least a bit. */
- assert_cc(DATA_SIZE_MAX < ENTRY_SIZE_MAX);
- if (source->size - source->filled < LINE_CHUNK &&
- !realloc_buffer(source, MIN(source->filled + LINE_CHUNK, ENTRY_SIZE_MAX)))
- return log_oom();
-
- assert(source->buf);
- assert(source->size - source->filled >= LINE_CHUNK ||
- source->size == ENTRY_SIZE_MAX);
-
- n = read(source->fd,
- source->buf + source->filled,
- source->size - source->filled);
- if (n < 0) {
- if (errno != EAGAIN)
- log_error_errno(errno, "read(%d, ..., %zu): %m",
- source->fd,
- source->size - source->filled);
- return -errno;
- } else if (n == 0)
- return 0;
-
- source->filled += n;
- }
-
- *line = source->buf + source->offset;
- *size = c + 1 - source->buf - source->offset;
- source->offset += *size;
-
- return 1;
-}
-
-int push_data(RemoteSource *source, const char *data, size_t size) {
- assert(source);
- assert(source->state != STATE_EOF);
-
- if (!realloc_buffer(source, source->filled + size)) {
- log_error("Failed to store received data of size %zu "
- "(in addition to existing %zu bytes with %zu filled): %s",
- size, source->size, source->filled, strerror(ENOMEM));
- return -ENOMEM;
- }
-
- memcpy(source->buf + source->filled, data, size);
- source->filled += size;
-
- return 0;
-}
-
-static int fill_fixed_size(RemoteSource *source, void **data, size_t size) {
-
- assert(source);
- assert(source->state == STATE_DATA_START ||
- source->state == STATE_DATA ||
- source->state == STATE_DATA_FINISH);
- assert(size <= DATA_SIZE_MAX);
- assert(source->offset <= source->filled);
- assert(source->filled <= source->size);
- assert(source->buf != NULL || source->size == 0);
- assert(source->buf == NULL || source->size > 0);
- assert(source->fd >= 0);
- assert(data);
-
- while (source->filled - source->offset < size) {
- int n;
-
- if (source->passive_fd)
- /* we have to wait for some data to come to us */
- return -EAGAIN;
-
- if (!realloc_buffer(source, source->offset + size))
- return log_oom();
-
- n = read(source->fd, source->buf + source->filled,
- source->size - source->filled);
- if (n < 0) {
- if (errno != EAGAIN)
- log_error_errno(errno, "read(%d, ..., %zu): %m", source->fd,
- source->size - source->filled);
- return -errno;
- } else if (n == 0)
- return 0;
-
- source->filled += n;
- }
-
- *data = source->buf + source->offset;
- source->offset += size;
-
- return 1;
-}
-
-static int get_data_size(RemoteSource *source) {
- int r;
- void *data;
-
- assert(source);
- assert(source->state == STATE_DATA_START);
- assert(source->data_size == 0);
-
- r = fill_fixed_size(source, &data, sizeof(uint64_t));
- if (r <= 0)
- return r;
-
- source->data_size = le64toh( *(uint64_t *) data );
- if (source->data_size > DATA_SIZE_MAX) {
- log_error("Stream declares field with size %zu > DATA_SIZE_MAX = %u",
- source->data_size, DATA_SIZE_MAX);
- return -EINVAL;
- }
- if (source->data_size == 0)
- log_warning("Binary field with zero length");
-
- return 1;
-}
-
-static int get_data_data(RemoteSource *source, void **data) {
- int r;
-
- assert(source);
- assert(data);
- assert(source->state == STATE_DATA);
-
- r = fill_fixed_size(source, data, source->data_size);
- if (r <= 0)
- return r;
-
- return 1;
-}
-
-static int get_data_newline(RemoteSource *source) {
- int r;
- char *data;
-
- assert(source);
- assert(source->state == STATE_DATA_FINISH);
-
- r = fill_fixed_size(source, (void**) &data, 1);
- if (r <= 0)
- return r;
-
- assert(data);
- if (*data != '\n') {
- log_error("expected newline, got '%c'", *data);
- return -EINVAL;
- }
-
- return 1;
-}
-
-static int process_dunder(RemoteSource *source, char *line, size_t n) {
- const char *timestamp;
- int r;
-
- assert(line);
- assert(n > 0);
- assert(line[n-1] == '\n');
-
- /* XXX: is it worth to support timestamps in extended format?
- * We don't produce them, but who knows... */
-
- timestamp = startswith(line, "__CURSOR=");
- if (timestamp)
- /* ignore __CURSOR */
- return 1;
-
- timestamp = startswith(line, "__REALTIME_TIMESTAMP=");
- if (timestamp) {
- long long unsigned x;
- line[n-1] = '\0';
- r = safe_atollu(timestamp, &x);
- if (r < 0)
- log_warning("Failed to parse __REALTIME_TIMESTAMP: '%s'", timestamp);
- else
- source->ts.realtime = x;
- return r < 0 ? r : 1;
- }
-
- timestamp = startswith(line, "__MONOTONIC_TIMESTAMP=");
- if (timestamp) {
- long long unsigned x;
- line[n-1] = '\0';
- r = safe_atollu(timestamp, &x);
- if (r < 0)
- log_warning("Failed to parse __MONOTONIC_TIMESTAMP: '%s'", timestamp);
- else
- source->ts.monotonic = x;
- return r < 0 ? r : 1;
- }
-
- timestamp = startswith(line, "__");
- if (timestamp) {
- log_notice("Unknown dunder line %s", line);
- return 1;
- }
-
- /* no dunder */
- return 0;
-}
-
-static int process_data(RemoteSource *source) {
- int r;
-
- switch(source->state) {
- case STATE_LINE: {
- char *line, *sep;
- size_t n = 0;
-
- assert(source->data_size == 0);
-
- r = get_line(source, &line, &n);
- if (r < 0)
- return r;
- if (r == 0) {
- source->state = STATE_EOF;
- return r;
- }
- assert(n > 0);
- assert(line[n-1] == '\n');
-
- if (n == 1) {
- log_trace("Received empty line, event is ready");
- return 1;
- }
-
- r = process_dunder(source, line, n);
- if (r != 0)
- return r < 0 ? r : 0;
-
- /* MESSAGE=xxx\n
- or
- COREDUMP\n
- LLLLLLLL0011223344...\n
- */
- sep = memchr(line, '=', n);
- if (sep) {
- /* chomp newline */
- n--;
-
- r = iovw_put(&source->iovw, line, n);
- if (r < 0)
- return r;
- } else {
- /* replace \n with = */
- line[n-1] = '=';
-
- source->field_len = n;
- source->state = STATE_DATA_START;
-
- /* we cannot put the field in iovec until we have all data */
- }
-
- log_trace("Received: %.*s (%s)", (int) n, line, sep ? "text" : "binary");
-
- return 0; /* continue */
- }
-
- case STATE_DATA_START:
- assert(source->data_size == 0);
-
- r = get_data_size(source);
- // log_debug("get_data_size() -> %d", r);
- if (r < 0)
- return r;
- if (r == 0) {
- source->state = STATE_EOF;
- return 0;
- }
-
- source->state = source->data_size > 0 ?
- STATE_DATA : STATE_DATA_FINISH;
-
- return 0; /* continue */
-
- case STATE_DATA: {
- void *data;
- char *field;
-
- assert(source->data_size > 0);
-
- r = get_data_data(source, &data);
- // log_debug("get_data_data() -> %d", r);
- if (r < 0)
- return r;
- if (r == 0) {
- source->state = STATE_EOF;
- return 0;
- }
-
- assert(data);
-
- field = (char*) data - sizeof(uint64_t) - source->field_len;
- memmove(field + sizeof(uint64_t), field, source->field_len);
-
- r = iovw_put(&source->iovw, field + sizeof(uint64_t), source->field_len + source->data_size);
- if (r < 0)
- return r;
-
- source->state = STATE_DATA_FINISH;
-
- return 0; /* continue */
- }
-
- case STATE_DATA_FINISH:
- r = get_data_newline(source);
- // log_debug("get_data_newline() -> %d", r);
- if (r < 0)
- return r;
- if (r == 0) {
- source->state = STATE_EOF;
- return 0;
- }
-
- source->data_size = 0;
- source->state = STATE_LINE;
-
- return 0; /* continue */
- default:
- assert_not_reached("wtf?");
- }
-}
-
int process_source(RemoteSource *source, bool compress, bool seal) {
- size_t remain, target;
int r;
assert(source);
assert(source->writer);
- r = process_data(source);
+ r = journal_importer_process_data(&source->importer);
if (r <= 0)
return r;
/* We have a full event */
log_trace("Received full event from source@%p fd:%d (%s)",
- source, source->fd, source->name);
+ source, source->importer.fd, source->importer.name);
- if (!source->iovw.count) {
+ if (source->importer.iovw.count == 0) {
log_warning("Entry with no payload, skipping");
goto freeing;
}
- assert(source->iovw.iovec);
- assert(source->iovw.count);
+ assert(source->importer.iovw.iovec);
- r = writer_write(source->writer, &source->iovw, &source->ts, compress, seal);
+ r = writer_write(source->writer, &source->importer.iovw, &source->importer.ts, compress, seal);
if (r < 0)
log_error_errno(r, "Failed to write entry of %zu bytes: %m",
- iovw_size(&source->iovw));
+ iovw_size(&source->importer.iovw));
else
r = 1;
freeing:
- iovw_free_contents(&source->iovw);
-
- /* possibly reset buffer position */
- remain = source->filled - source->offset;
-
- if (remain == 0) /* no brainer */
- source->offset = source->scanned = source->filled = 0;
- else if (source->offset > source->size - source->filled &&
- source->offset > remain) {
- memcpy(source->buf, source->buf + source->offset, remain);
- source->offset = source->scanned = 0;
- source->filled = remain;
- }
-
- target = source->size;
- while (target > 16 * LINE_CHUNK && source->filled < target / 2)
- target /= 2;
- if (target < source->size) {
- char *tmp;
-
- tmp = realloc(source->buf, target);
- if (!tmp)
- log_warning("Failed to reallocate buffer to (smaller) size %zu",
- target);
- else {
- log_debug("Reallocated buffer from %zu to %zu bytes",
- source->size, target);
- source->buf = tmp;
- source->size = target;
- }
- }
-
+ journal_importer_drop_iovw(&source->importer);
return r;
}
diff --git a/src/journal-remote/journal-remote-parse.h b/src/journal-remote/journal-remote-parse.h
index 1740a21f92..e3632528cf 100644
--- a/src/journal-remote/journal-remote-parse.h
+++ b/src/journal-remote/journal-remote-parse.h
@@ -21,34 +21,11 @@
#include "sd-event.h"
+#include "journal-importer.h"
#include "journal-remote-write.h"
-typedef enum {
- STATE_LINE = 0, /* waiting to read, or reading line */
- STATE_DATA_START, /* reading binary data header */
- STATE_DATA, /* reading binary data */
- STATE_DATA_FINISH, /* expecting newline */
- STATE_EOF, /* done */
-} source_state;
-
typedef struct RemoteSource {
- char *name;
- int fd;
- bool passive_fd;
-
- char *buf;
- size_t size; /* total size of the buffer */
- size_t offset; /* offset to the beginning of live data in the buffer */
- size_t scanned; /* number of bytes since the beginning of data without a newline */
- size_t filled; /* total number of bytes in the buffer */
-
- size_t field_len; /* used for binary fields: the field name length */
- size_t data_size; /* and the size of the binary data chunk being processed */
-
- struct iovec_wrapper iovw;
-
- source_state state;
- dual_timestamp ts;
+ JournalImporter importer;
Writer *writer;
@@ -57,13 +34,5 @@ typedef struct RemoteSource {
} RemoteSource;
RemoteSource* source_new(int fd, bool passive_fd, char *name, Writer *writer);
-
-static inline size_t source_non_empty(RemoteSource *source) {
- assert(source);
-
- return source->filled;
-}
-
void source_free(RemoteSource *source);
-int push_data(RemoteSource *source, const char *data, size_t size);
int process_source(RemoteSource *source, bool compress, bool seal);
diff --git a/src/journal-remote/journal-remote-write.c b/src/journal-remote/journal-remote-write.c
index 8729372aa3..734cad333f 100644
--- a/src/journal-remote/journal-remote-write.c
+++ b/src/journal-remote/journal-remote-write.c
@@ -20,39 +20,6 @@
#include "alloc-util.h"
#include "journal-remote.h"
-int iovw_put(struct iovec_wrapper *iovw, void* data, size_t len) {
- if (!GREEDY_REALLOC(iovw->iovec, iovw->size_bytes, iovw->count + 1))
- return log_oom();
-
- iovw->iovec[iovw->count++] = (struct iovec) {data, len};
- return 0;
-}
-
-void iovw_free_contents(struct iovec_wrapper *iovw) {
- iovw->iovec = mfree(iovw->iovec);
- iovw->size_bytes = iovw->count = 0;
-}
-
-size_t iovw_size(struct iovec_wrapper *iovw) {
- size_t n = 0, i;
-
- for (i = 0; i < iovw->count; i++)
- n += iovw->iovec[i].iov_len;
-
- return n;
-}
-
-void iovw_rebase(struct iovec_wrapper *iovw, char *old, char *new) {
- size_t i;
-
- for (i = 0; i < iovw->count; i++)
- iovw->iovec[i].iov_base = (char*) iovw->iovec[i].iov_base - old + new;
-}
-
-/**********************************************************************
- **********************************************************************
- **********************************************************************/
-
static int do_rotate(JournalFile **f, bool compress, bool seal) {
int r = journal_file_rotate(f, compress, seal, NULL);
if (r < 0) {
diff --git a/src/journal-remote/journal-remote-write.h b/src/journal-remote/journal-remote-write.h
index 53ba45fc04..e04af54e55 100644
--- a/src/journal-remote/journal-remote-write.h
+++ b/src/journal-remote/journal-remote-write.h
@@ -20,20 +20,10 @@
***/
#include "journal-file.h"
+#include "journal-importer.h"
typedef struct RemoteServer RemoteServer;
-struct iovec_wrapper {
- struct iovec *iovec;
- size_t size_bytes;
- size_t count;
-};
-
-int iovw_put(struct iovec_wrapper *iovw, void* data, size_t len);
-void iovw_free_contents(struct iovec_wrapper *iovw);
-size_t iovw_size(struct iovec_wrapper *iovw);
-void iovw_rebase(struct iovec_wrapper *iovw, char *old, char *new);
-
typedef struct Writer {
JournalFile *journal;
JournalMetrics metrics;
diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c
index d86c3681b1..202a5a3f97 100644
--- a/src/journal-remote/journal-remote.c
+++ b/src/journal-remote/journal-remote.c
@@ -512,7 +512,8 @@ static int process_http_upload(
if (*upload_data_size) {
log_trace("Received %zu bytes", *upload_data_size);
- r = push_data(source, upload_data, *upload_data_size);
+ r = journal_importer_push_data(&source->importer,
+ upload_data, *upload_data_size);
if (r < 0)
return mhd_respond_oom(connection);
@@ -542,7 +543,7 @@ static int process_http_upload(
/* The upload is finished */
- remaining = source_non_empty(source);
+ remaining = journal_importer_bytes_remaining(&source->importer);
if (remaining > 0) {
log_warning("Premature EOF byte. %zu bytes lost.", remaining);
return mhd_respondf(connection,
@@ -648,9 +649,9 @@ static int setup_microhttpd_server(RemoteServer *s,
int flags =
MHD_USE_DEBUG |
MHD_USE_DUAL_STACK |
- MHD_USE_EPOLL_LINUX_ONLY |
+ MHD_USE_EPOLL |
MHD_USE_PEDANTIC_CHECKS |
- MHD_USE_PIPE_FOR_SHUTDOWN;
+ MHD_USE_ITC;
const union MHD_DaemonInfo *info;
int r, epoll_fd;
@@ -1036,19 +1037,19 @@ static int handle_raw_source(sd_event_source *event,
assert(fd >= 0 && fd < (ssize_t) s->sources_size);
source = s->sources[fd];
- assert(source->fd == fd);
+ assert(source->importer.fd == fd);
r = process_source(source, arg_compress, arg_seal);
- if (source->state == STATE_EOF) {
+ if (journal_importer_eof(&source->importer)) {
size_t remaining;
- log_debug("EOF reached with source fd:%d (%s)",
- source->fd, source->name);
+ log_debug("EOF reached with source %s (fd=%d)",
+ source->importer.name, source->importer.fd);
- remaining = source_non_empty(source);
+ remaining = journal_importer_bytes_remaining(&source->importer);
if (remaining > 0)
log_notice("Premature EOF. %zu bytes lost.", remaining);
- remove_source(s, source->fd);
+ remove_source(s, source->importer.fd);
log_debug("%zu active sources remaining", s->active);
return 0;
} else if (r == -E2BIG) {
@@ -1072,7 +1073,7 @@ static int dispatch_raw_source_until_block(sd_event_source *event,
/* Make sure event stays around even if source is destroyed */
sd_event_source_ref(event);
- r = handle_raw_source(event, source->fd, EPOLLIN, server);
+ r = handle_raw_source(event, source->importer.fd, EPOLLIN, server);
if (r != 1)
/* No more data for now */
sd_event_source_set_enabled(event, SD_EVENT_OFF);
@@ -1105,7 +1106,7 @@ static int dispatch_blocking_source_event(sd_event_source *event,
void *userdata) {
RemoteSource *source = userdata;
- return handle_raw_source(event, source->fd, EPOLLIN, server);
+ return handle_raw_source(event, source->importer.fd, EPOLLIN, server);
}
static int accept_connection(const char* type, int fd,
diff --git a/src/journal-remote/journal-upload.c b/src/journal-remote/journal-upload.c
index 61190ff83c..371b6acc64 100644
--- a/src/journal-remote/journal-upload.c
+++ b/src/journal-remote/journal-upload.c
@@ -30,7 +30,7 @@
#include "def.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "glob-util.h"
#include "journal-upload.h"
#include "log.h"
@@ -438,7 +438,7 @@ static int setup_uploader(Uploader *u, const char *url, const char *state_file)
}
if (strchr(host, ':'))
- u->url = strjoin(proto, url, "/upload", NULL);
+ u->url = strjoin(proto, url, "/upload");
else {
char *t;
size_t x;
@@ -448,7 +448,7 @@ static int setup_uploader(Uploader *u, const char *url, const char *state_file)
while (x > 0 && t[x - 1] == '/')
t[x - 1] = '\0';
- u->url = strjoin(proto, t, ":" STRINGIFY(DEFAULT_PORT), "/upload", NULL);
+ u->url = strjoin(proto, t, ":" STRINGIFY(DEFAULT_PORT), "/upload");
}
if (!u->url)
return log_oom();
diff --git a/src/journal-remote/log-generator.py b/src/journal-remote/log-generator.py
index fd6964e758..7b434b334e 100755
--- a/src/journal-remote/log-generator.py
+++ b/src/journal-remote/log-generator.py
@@ -1,5 +1,4 @@
-#!/usr/bin/python
-from __future__ import print_function
+#!/usr/bin/python3
import sys
import argparse
@@ -30,7 +29,7 @@ _SOURCE_REALTIME_TIMESTAMP={source_realtime_ts}
DATA={data}
"""
-m = 0x198603b12d7
+m = 0x198603b12d7
realtime_ts = 1404101101501873
monotonic_ts = 1753961140951
source_realtime_ts = 1404101101483516
@@ -72,5 +71,5 @@ for i in range(OPTIONS.n):
print('.', file=sys.stderr, end='', flush=True)
if OPTIONS.dots:
- print(file=sys.stderr)
+ print(file=sys.stderr)
print('Wrote {} bytes'.format(bytes), file=sys.stderr)
diff --git a/src/journal-remote/microhttpd-util.h b/src/journal-remote/microhttpd-util.h
index af26ab69fe..49def4f630 100644
--- a/src/journal-remote/microhttpd-util.h
+++ b/src/journal-remote/microhttpd-util.h
@@ -24,13 +24,25 @@
#include "macro.h"
+/* Those defines are added when options are renamed, hence the check for the *old* name. */
+
/* Compatiblity with libmicrohttpd < 0.9.38 */
#ifndef MHD_HTTP_NOT_ACCEPTABLE
-#define MHD_HTTP_NOT_ACCEPTABLE MHD_HTTP_METHOD_NOT_ACCEPTABLE
+# define MHD_HTTP_NOT_ACCEPTABLE MHD_HTTP_METHOD_NOT_ACCEPTABLE
+#endif
+
+/* Renamed in µhttpd 0.9.52 */
+#ifndef MHD_USE_EPOLL_LINUX_ONLY
+# define MHD_USE_EPOLL MHD_USE_EPOLL_LINUX_ONLY
+#endif
+
+/* Renamed in µhttpd 0.9.51 */
+#ifndef MHD_USE_PIPE_FOR_SHUTDOWN
+# define MHD_USE_ITC MHD_USE_PIPE_FOR_SHUTDOWN
#endif
#if MHD_VERSION < 0x00094203
-#define MHD_create_response_from_fd_at_offset64 MHD_create_response_from_fd_at_offset
+# define MHD_create_response_from_fd_at_offset64 MHD_create_response_from_fd_at_offset
#endif
void microhttpd_logger(void *arg, const char *fmt, va_list ap) _printf_(2, 0);
diff --git a/src/journal/compress.c b/src/journal/compress.c
index ba734b5561..818a720ba8 100644
--- a/src/journal/compress.c
+++ b/src/journal/compress.c
@@ -112,7 +112,11 @@ int compress_blob_lz4(const void *src, uint64_t src_size,
if (src_size < 9)
return -ENOBUFS;
+#if LZ4_VERSION_NUMBER >= 10700
+ r = LZ4_compress_default(src, (char*)dst + 8, src_size, (int) dst_alloc_size - 8);
+#else
r = LZ4_compress_limitedOutput(src, (char*)dst + 8, src_size, (int) dst_alloc_size - 8);
+#endif
if (r <= 0)
return -ENOBUFS;
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index e45d1905e7..243d5198d9 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -42,6 +42,7 @@
#include "sd-event.h"
#include "set.h"
#include "string-util.h"
+#include "strv.h"
#include "xattr-util.h"
#define DEFAULT_DATA_HASH_TABLE_SIZE (2047ULL*sizeof(HashItem))
@@ -507,57 +508,79 @@ static int journal_file_refresh_header(JournalFile *f) {
return r;
}
-static int journal_file_verify_header(JournalFile *f) {
+static bool warn_wrong_flags(const JournalFile *f, bool compatible) {
+ const uint32_t any = compatible ? HEADER_COMPATIBLE_ANY : HEADER_INCOMPATIBLE_ANY,
+ supported = compatible ? HEADER_COMPATIBLE_SUPPORTED : HEADER_INCOMPATIBLE_SUPPORTED;
+ const char *type = compatible ? "compatible" : "incompatible";
uint32_t flags;
+ flags = le32toh(compatible ? f->header->compatible_flags : f->header->incompatible_flags);
+
+ if (flags & ~supported) {
+ if (flags & ~any)
+ log_debug("Journal file %s has unknown %s flags 0x%"PRIx32,
+ f->path, type, flags & ~any);
+ flags = (flags & any) & ~supported;
+ if (flags) {
+ const char* strv[3];
+ unsigned n = 0;
+ _cleanup_free_ char *t = NULL;
+
+ if (compatible && (flags & HEADER_COMPATIBLE_SEALED))
+ strv[n++] = "sealed";
+ if (!compatible && (flags & HEADER_INCOMPATIBLE_COMPRESSED_XZ))
+ strv[n++] = "xz-compressed";
+ if (!compatible && (flags & HEADER_INCOMPATIBLE_COMPRESSED_LZ4))
+ strv[n++] = "lz4-compressed";
+ strv[n] = NULL;
+ assert(n < ELEMENTSOF(strv));
+
+ t = strv_join((char**) strv, ", ");
+ log_debug("Journal file %s uses %s %s %s disabled at compilation time.",
+ f->path, type, n > 1 ? "flags" : "flag", strnull(t));
+ }
+ return true;
+ }
+
+ return false;
+}
+
+static int journal_file_verify_header(JournalFile *f) {
+ uint64_t arena_size, header_size;
+
assert(f);
assert(f->header);
if (memcmp(f->header->signature, HEADER_SIGNATURE, 8))
return -EBADMSG;
- /* In both read and write mode we refuse to open files with
- * incompatible flags we don't know */
- flags = le32toh(f->header->incompatible_flags);
- if (flags & ~HEADER_INCOMPATIBLE_SUPPORTED) {
- if (flags & ~HEADER_INCOMPATIBLE_ANY)
- log_debug("Journal file %s has unknown incompatible flags %"PRIx32,
- f->path, flags & ~HEADER_INCOMPATIBLE_ANY);
- flags = (flags & HEADER_INCOMPATIBLE_ANY) & ~HEADER_INCOMPATIBLE_SUPPORTED;
- if (flags)
- log_debug("Journal file %s uses incompatible flags %"PRIx32
- " disabled at compilation time.", f->path, flags);
+ /* In both read and write mode we refuse to open files with incompatible
+ * flags we don't know. */
+ if (warn_wrong_flags(f, false))
return -EPROTONOSUPPORT;
- }
- /* When open for writing we refuse to open files with
- * compatible flags, too */
- flags = le32toh(f->header->compatible_flags);
- if (f->writable && (flags & ~HEADER_COMPATIBLE_SUPPORTED)) {
- if (flags & ~HEADER_COMPATIBLE_ANY)
- log_debug("Journal file %s has unknown compatible flags %"PRIx32,
- f->path, flags & ~HEADER_COMPATIBLE_ANY);
- flags = (flags & HEADER_COMPATIBLE_ANY) & ~HEADER_COMPATIBLE_SUPPORTED;
- if (flags)
- log_debug("Journal file %s uses compatible flags %"PRIx32
- " disabled at compilation time.", f->path, flags);
+ /* When open for writing we refuse to open files with compatible flags, too. */
+ if (f->writable && warn_wrong_flags(f, true))
return -EPROTONOSUPPORT;
- }
if (f->header->state >= _STATE_MAX)
return -EBADMSG;
+ header_size = le64toh(f->header->header_size);
+
/* The first addition was n_data, so check that we are at least this large */
- if (le64toh(f->header->header_size) < HEADER_SIZE_MIN)
+ if (header_size < HEADER_SIZE_MIN)
return -EBADMSG;
if (JOURNAL_HEADER_SEALED(f->header) && !JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays))
return -EBADMSG;
- if ((le64toh(f->header->header_size) + le64toh(f->header->arena_size)) > (uint64_t) f->last_stat.st_size)
+ arena_size = le64toh(f->header->arena_size);
+
+ if (UINT64_MAX - header_size < arena_size || header_size + arena_size > (uint64_t) f->last_stat.st_size)
return -ENODATA;
- if (le64toh(f->header->tail_object_offset) > (le64toh(f->header->header_size) + le64toh(f->header->arena_size)))
+ if (le64toh(f->header->tail_object_offset) > header_size + arena_size)
return -ENODATA;
if (!VALID64(le64toh(f->header->data_hash_table_offset)) ||
@@ -580,16 +603,19 @@ static int journal_file_verify_header(JournalFile *f) {
state = f->header->state;
- if (state == STATE_ONLINE) {
+ if (state == STATE_ARCHIVED)
+ return -ESHUTDOWN; /* Already archived */
+ else if (state == STATE_ONLINE) {
log_debug("Journal file %s is already online. Assuming unclean closing.", f->path);
return -EBUSY;
- } else if (state == STATE_ARCHIVED)
- return -ESHUTDOWN;
- else if (state != STATE_OFFLINE) {
+ } else if (state != STATE_OFFLINE) {
log_debug("Journal file %s has unknown state %i.", f->path, state);
return -EBUSY;
}
+ if (f->header->field_hash_table_size == 0 || f->header->data_hash_table_size == 0)
+ return -EBADMSG;
+
/* Don't permit appending to files from the future. Because otherwise the realtime timestamps wouldn't
* be strictly ordered in the entries in the file anymore, and we can't have that since it breaks
* bisection. */
@@ -3087,13 +3113,18 @@ int journal_file_open(
}
}
- if (fname)
+ if (fname) {
f->path = strdup(fname);
- else /* If we don't know the path, fill in something explanatory and vaguely useful */
- asprintf(&f->path, "/proc/self/%i", fd);
- if (!f->path) {
- r = -ENOMEM;
- goto fail;
+ if (!f->path) {
+ r = -ENOMEM;
+ goto fail;
+ }
+ } else {
+ /* If we don't know the path, fill in something explanatory and vaguely useful */
+ if (asprintf(&f->path, "/proc/self/%i", fd) < 0) {
+ r = -ENOMEM;
+ goto fail;
+ }
}
f->chain_cache = ordered_hashmap_new(&uint64_hash_ops);
@@ -3261,7 +3292,7 @@ int journal_file_rotate(JournalFile **f, bool compress, bool seal, Set *deferred
return -EINVAL;
/* Is this a journal file that was passed to us as fd? If so, we synthesized a path name for it, and we refuse
- * rotation, since we don't know the actual path, and couldn't rename the file hence.*/
+ * rotation, since we don't know the actual path, and couldn't rename the file hence. */
if (path_startswith(old_file->path, "/proc/self/fd"))
return -EINVAL;
@@ -3330,12 +3361,12 @@ int journal_file_open_reliably(
r = journal_file_open(-1, fname, flags, mode, compress, seal, metrics, mmap_cache, deferred_closes, template, ret);
if (!IN_SET(r,
- -EBADMSG, /* corrupted */
- -ENODATA, /* truncated */
- -EHOSTDOWN, /* other machine */
- -EPROTONOSUPPORT, /* incompatible feature */
- -EBUSY, /* unclean shutdown */
- -ESHUTDOWN, /* already archived */
+ -EBADMSG, /* Corrupted */
+ -ENODATA, /* Truncated */
+ -EHOSTDOWN, /* Other machine */
+ -EPROTONOSUPPORT, /* Incompatible feature */
+ -EBUSY, /* Unclean shutdown */
+ -ESHUTDOWN, /* Already archived */
-EIO, /* IO error, including SIGBUS on mmap */
-EIDRM, /* File has been deleted */
-ETXTBSY)) /* File is from the future */
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 7f997487b4..ad11fb314d 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -52,6 +52,7 @@
#include "journal-def.h"
#include "journal-internal.h"
#include "journal-qrcode.h"
+#include "journal-util.h"
#include "journal-vacuum.h"
#include "journal-verify.h"
#include "locale-util.h"
@@ -103,7 +104,7 @@ static const char *arg_directory = NULL;
static char **arg_file = NULL;
static bool arg_file_stdin = false;
static int arg_priorities = 0xFF;
-static const char *arg_verify_key = NULL;
+static char *arg_verify_key = NULL;
#ifdef HAVE_GCRYPT
static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC;
static bool arg_force = false;
@@ -192,7 +193,7 @@ static int add_matches_for_device(sd_journal *j, const char *devpath) {
continue;
}
- match = strjoin("_KERNEL_DEVICE=+", subsys, ":", sysname, NULL);
+ match = strjoin("_KERNEL_DEVICE=+", subsys, ":", sysname);
if (!match)
return log_oom();
@@ -683,7 +684,13 @@ static int parse_argv(int argc, char *argv[]) {
case ARG_VERIFY_KEY:
arg_action = ACTION_VERIFY;
- arg_verify_key = optarg;
+ r = free_and_strdup(&arg_verify_key, optarg);
+ if (r < 0)
+ return r;
+ /* Use memset not string_erase so this doesn't look confusing
+ * in ps or htop output. */
+ memset(optarg, 'x', strlen(optarg));
+
arg_merge = false;
break;
@@ -885,7 +892,7 @@ static int parse_argv(int argc, char *argv[]) {
* to users, and automatically turn --unit= into --user-unit= if combined with --user. */
r = strv_extend_strv(&arg_user_units, arg_system_units, true);
if (r < 0)
- return -ENOMEM;
+ return r;
arg_system_units = strv_free(arg_system_units);
}
@@ -906,7 +913,7 @@ static int generate_new_id128(void) {
SD_ID128_FORMAT_STR "\n\n"
"As UUID:\n"
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n\n"
- "As macro:\n"
+ "As man:sd-id128(3) macro:\n"
"#define MESSAGE_XYZ SD_ID128_MAKE(",
SD_ID128_FORMAT_VAL(id),
SD_ID128_FORMAT_VAL(id));
@@ -938,21 +945,21 @@ static int add_matches(sd_journal *j, char **args) {
have_term = false;
} else if (path_is_absolute(*i)) {
- _cleanup_free_ char *p, *t = NULL, *t2 = NULL, *interpreter = NULL;
- const char *path;
+ _cleanup_free_ char *p = NULL, *t = NULL, *t2 = NULL, *interpreter = NULL;
struct stat st;
- p = canonicalize_file_name(*i);
- path = p ?: *i;
+ r = chase_symlinks(*i, NULL, 0, &p);
+ if (r < 0)
+ return log_error_errno(r, "Couldn't canonicalize path: %m");
- if (lstat(path, &st) < 0)
+ if (lstat(p, &st) < 0)
return log_error_errno(errno, "Couldn't stat file: %m");
if (S_ISREG(st.st_mode) && (0111 & st.st_mode)) {
- if (executable_is_script(path, &interpreter) > 0) {
+ if (executable_is_script(p, &interpreter) > 0) {
_cleanup_free_ char *comm;
- comm = strndup(basename(path), 15);
+ comm = strndup(basename(p), 15);
if (!comm)
return log_oom();
@@ -968,7 +975,7 @@ static int add_matches(sd_journal *j, char **args) {
return log_oom();
}
} else {
- t = strappend("_EXE=", path);
+ t = strappend("_EXE=", p);
if (!t)
return log_oom();
}
@@ -979,7 +986,7 @@ static int add_matches(sd_journal *j, char **args) {
r = sd_journal_add_match(j, t2, 0);
} else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
- r = add_matches_for_device(j, path);
+ r = add_matches_for_device(j, p);
if (r < 0)
return r;
} else {
@@ -1799,129 +1806,6 @@ static int verify(sd_journal *j) {
return r;
}
-static int access_check_var_log_journal(sd_journal *j) {
-#ifdef HAVE_ACL
- _cleanup_strv_free_ char **g = NULL;
- const char* dir;
-#endif
- int r;
-
- assert(j);
-
- if (arg_quiet)
- return 0;
-
- /* If we are root, we should have access, don't warn. */
- if (getuid() == 0)
- return 0;
-
- /* If we are in the 'systemd-journal' group, we should have
- * access too. */
- r = in_group("systemd-journal");
- if (r < 0)
- return log_error_errno(r, "Failed to check if we are in the 'systemd-journal' group: %m");
- if (r > 0)
- return 0;
-
-#ifdef HAVE_ACL
- if (laccess("/run/log/journal", F_OK) >= 0)
- dir = "/run/log/journal";
- else
- dir = "/var/log/journal";
-
- /* If we are in any of the groups listed in the journal ACLs,
- * then all is good, too. Let's enumerate all groups from the
- * default ACL of the directory, which generally should allow
- * access to most journal files too. */
- r = acl_search_groups(dir, &g);
- if (r < 0)
- return log_error_errno(r, "Failed to search journal ACL: %m");
- if (r > 0)
- return 0;
-
- /* Print a pretty list, if there were ACLs set. */
- if (!strv_isempty(g)) {
- _cleanup_free_ char *s = NULL;
-
- /* Thre are groups in the ACL, let's list them */
- r = strv_extend(&g, "systemd-journal");
- if (r < 0)
- return log_oom();
-
- strv_sort(g);
- strv_uniq(g);
-
- s = strv_join(g, "', '");
- if (!s)
- return log_oom();
-
- log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
- " Users in groups '%s' can see all messages.\n"
- " Pass -q to turn off this notice.", s);
- return 1;
- }
-#endif
-
- /* If no ACLs were found, print a short version of the message. */
- log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
- " Users in the 'systemd-journal' group can see all messages. Pass -q to\n"
- " turn off this notice.");
-
- return 1;
-}
-
-static int access_check(sd_journal *j) {
- Iterator it;
- void *code;
- char *path;
- int r = 0;
-
- assert(j);
-
- if (hashmap_isempty(j->errors)) {
- if (ordered_hashmap_isempty(j->files))
- log_notice("No journal files were found.");
-
- return 0;
- }
-
- if (hashmap_contains(j->errors, INT_TO_PTR(-EACCES))) {
- (void) access_check_var_log_journal(j);
-
- if (ordered_hashmap_isempty(j->files))
- r = log_error_errno(EACCES, "No journal files were opened due to insufficient permissions.");
- }
-
- HASHMAP_FOREACH_KEY(path, code, j->errors, it) {
- int err;
-
- err = abs(PTR_TO_INT(code));
-
- switch (err) {
- case EACCES:
- continue;
-
- case ENODATA:
- log_warning_errno(err, "Journal file %s is truncated, ignoring file.", path);
- break;
-
- case EPROTONOSUPPORT:
- log_warning_errno(err, "Journal file %s uses an unsupported feature, ignoring file.", path);
- break;
-
- case EBADMSG:
- log_warning_errno(err, "Journal file %s corrupted, ignoring file.", path);
- break;
-
- default:
- log_warning_errno(err, "An error was encountered while opening journal file or directory %s, ignoring file: %m", path);
- break;
- }
- }
-
- return r;
-}
-
static int flush_to_var(void) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
@@ -2233,7 +2117,7 @@ int main(int argc, char *argv[]) {
goto finish;
}
- r = access_check(j);
+ r = journal_access_check_and_warn(j, arg_quiet);
if (r < 0)
goto finish;
@@ -2318,7 +2202,7 @@ int main(int argc, char *argv[]) {
if (arg_boot_offset != 0 &&
sd_journal_has_runtime_files(j) > 0 &&
sd_journal_has_persistent_files(j) == 0) {
- log_info("Specifying boot ID has no effect, no persistent journal was found");
+ log_info("Specifying boot ID or boot offset has no effect, no persistent journal was found.");
r = 0;
goto finish;
}
@@ -2621,6 +2505,7 @@ finish:
strv_free(arg_user_units);
free(arg_root);
+ free(arg_verify_key);
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/src/journal/journald-console.c b/src/journal/journald-console.c
index 3a9fba42a3..5fbcdb43c2 100644
--- a/src/journal/journald-console.c
+++ b/src/journal/journald-console.c
@@ -24,7 +24,7 @@
#include "alloc-util.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "io-util.h"
#include "journald-console.h"
#include "journald-server.h"
@@ -72,9 +72,9 @@ void server_forward_console(
/* First: timestamp */
if (prefix_timestamp()) {
assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);
- xsprintf(tbuf, "[%5"PRI_TIME".%06ld] ",
+ xsprintf(tbuf, "[%5"PRI_TIME".%06"PRI_NSEC"] ",
ts.tv_sec,
- ts.tv_nsec / 1000);
+ (nsec_t)ts.tv_nsec / 1000);
IOVEC_SET_STRING(iovec[n++], tbuf);
}
diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c
index f64abdd431..8afaec0ced 100644
--- a/src/journal/journald-kmsg.c
+++ b/src/journal/journald-kmsg.c
@@ -28,7 +28,7 @@
#include "escape.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "io-util.h"
#include "journald-kmsg.h"
#include "journald-server.h"
@@ -156,7 +156,8 @@ static void dev_kmsg_record(Server *s, const char *p, size_t l) {
/* Did we lose any? */
if (serial > *s->kernel_seqnum)
- server_driver_message(s, SD_MESSAGE_JOURNAL_MISSED,
+ server_driver_message(s,
+ "MESSAGE_ID=" SD_MESSAGE_JOURNAL_MISSED_STR,
LOG_MESSAGE("Missed %"PRIu64" kernel messages",
serial - *s->kernel_seqnum),
NULL);
diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c
index 0a1ce205c2..db3fdcf1df 100644
--- a/src/journal/journald-native.c
+++ b/src/journal/journald-native.c
@@ -27,6 +27,7 @@
#include "fd-util.h"
#include "fs-util.h"
#include "io-util.h"
+#include "journal-importer.h"
#include "journald-console.h"
#include "journald-kmsg.h"
#include "journald-native.h"
@@ -39,6 +40,7 @@
#include "selinux-util.h"
#include "socket-util.h"
#include "string-util.h"
+#include "unaligned.h"
bool valid_user_field(const char *p, size_t l, bool allow_protected) {
const char *a;
@@ -79,60 +81,110 @@ static bool allow_object_pid(const struct ucred *ucred) {
return ucred && ucred->uid == 0;
}
-void server_process_native_message(
+static void server_process_entry_meta(
+ const char *p, size_t l,
+ const struct ucred *ucred,
+ int *priority,
+ char **identifier,
+ char **message,
+ pid_t *object_pid) {
+
+ /* We need to determine the priority of this entry for the rate limiting logic */
+
+ if (l == 10 &&
+ startswith(p, "PRIORITY=") &&
+ p[9] >= '0' && p[9] <= '9')
+ *priority = (*priority & LOG_FACMASK) | (p[9] - '0');
+
+ else if (l == 17 &&
+ startswith(p, "SYSLOG_FACILITY=") &&
+ p[16] >= '0' && p[16] <= '9')
+ *priority = (*priority & LOG_PRIMASK) | ((p[16] - '0') << 3);
+
+ else if (l == 18 &&
+ startswith(p, "SYSLOG_FACILITY=") &&
+ p[16] >= '0' && p[16] <= '9' &&
+ p[17] >= '0' && p[17] <= '9')
+ *priority = (*priority & LOG_PRIMASK) | (((p[16] - '0')*10 + (p[17] - '0')) << 3);
+
+ else if (l >= 19 &&
+ startswith(p, "SYSLOG_IDENTIFIER=")) {
+ char *t;
+
+ t = strndup(p + 18, l - 18);
+ if (t) {
+ free(*identifier);
+ *identifier = t;
+ }
+
+ } else if (l >= 8 &&
+ startswith(p, "MESSAGE=")) {
+ char *t;
+
+ t = strndup(p + 8, l - 8);
+ if (t) {
+ free(*message);
+ *message = t;
+ }
+
+ } else if (l > strlen("OBJECT_PID=") &&
+ l < strlen("OBJECT_PID=") + DECIMAL_STR_MAX(pid_t) &&
+ startswith(p, "OBJECT_PID=") &&
+ allow_object_pid(ucred)) {
+ char buf[DECIMAL_STR_MAX(pid_t)];
+ memcpy(buf, p + strlen("OBJECT_PID="), l - strlen("OBJECT_PID="));
+ buf[l-strlen("OBJECT_PID=")] = '\0';
+
+ (void) parse_pid(buf, object_pid);
+ }
+}
+
+static int server_process_entry(
Server *s,
- const void *buffer, size_t buffer_size,
+ const void *buffer, size_t *remaining,
const struct ucred *ucred,
const struct timeval *tv,
const char *label, size_t label_len) {
+ /* Process a single entry from a native message.
+ * Returns 0 if nothing special happened and the message processing should continue,
+ * and a negative or positive value otherwise.
+ *
+ * Note that *remaining is altered on both success and failure. */
+
struct iovec *iovec = NULL;
unsigned n = 0, j, tn = (unsigned) -1;
const char *p;
- size_t remaining, m = 0, entry_size = 0;
+ size_t m = 0, entry_size = 0;
int priority = LOG_INFO;
char *identifier = NULL, *message = NULL;
pid_t object_pid = 0;
-
- assert(s);
- assert(buffer || buffer_size == 0);
+ int r = 0;
p = buffer;
- remaining = buffer_size;
- while (remaining > 0) {
+ while (*remaining > 0) {
const char *e, *q;
- e = memchr(p, '\n', remaining);
+ e = memchr(p, '\n', *remaining);
if (!e) {
/* Trailing noise, let's ignore it, and flush what we collected */
log_debug("Received message with trailing noise, ignoring.");
+ r = 1; /* finish processing of the message */
break;
}
if (e == p) {
/* Entry separator */
-
- if (entry_size + n + 1 > ENTRY_SIZE_MAX) { /* data + separators + trailer */
- log_debug("Entry is too big with %u properties and %zu bytes, ignoring.", n, entry_size);
- continue;
- }
-
- server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority, object_pid);
- n = 0;
- priority = LOG_INFO;
- entry_size = 0;
-
- p++;
- remaining--;
- continue;
+ *remaining -= 1;
+ break;
}
if (*p == '.' || *p == '#') {
/* Ignore control commands for now, and
* comments too. */
- remaining -= (e - p) + 1;
+ *remaining -= (e - p) + 1;
p = e + 1;
continue;
}
@@ -141,7 +193,7 @@ void server_process_native_message(
/* n existing properties, 1 new, +1 for _TRANSPORT */
if (!GREEDY_REALLOC(iovec, m, n + 2 + N_IOVEC_META_FIELDS + N_IOVEC_OBJECT_FIELDS)) {
- log_oom();
+ r = log_oom();
break;
}
@@ -154,87 +206,40 @@ void server_process_native_message(
/* If the field name starts with an
* underscore, skip the variable,
- * since that indidates a trusted
+ * since that indicates a trusted
* field */
iovec[n].iov_base = (char*) p;
iovec[n].iov_len = l;
- entry_size += iovec[n].iov_len;
+ entry_size += l;
n++;
- /* We need to determine the priority
- * of this entry for the rate limiting
- * logic */
- if (l == 10 &&
- startswith(p, "PRIORITY=") &&
- p[9] >= '0' && p[9] <= '9')
- priority = (priority & LOG_FACMASK) | (p[9] - '0');
-
- else if (l == 17 &&
- startswith(p, "SYSLOG_FACILITY=") &&
- p[16] >= '0' && p[16] <= '9')
- priority = (priority & LOG_PRIMASK) | ((p[16] - '0') << 3);
-
- else if (l == 18 &&
- startswith(p, "SYSLOG_FACILITY=") &&
- p[16] >= '0' && p[16] <= '9' &&
- p[17] >= '0' && p[17] <= '9')
- priority = (priority & LOG_PRIMASK) | (((p[16] - '0')*10 + (p[17] - '0')) << 3);
-
- else if (l >= 19 &&
- startswith(p, "SYSLOG_IDENTIFIER=")) {
- char *t;
-
- t = strndup(p + 18, l - 18);
- if (t) {
- free(identifier);
- identifier = t;
- }
-
- } else if (l >= 8 &&
- startswith(p, "MESSAGE=")) {
- char *t;
-
- t = strndup(p + 8, l - 8);
- if (t) {
- free(message);
- message = t;
- }
-
- } else if (l > strlen("OBJECT_PID=") &&
- l < strlen("OBJECT_PID=") + DECIMAL_STR_MAX(pid_t) &&
- startswith(p, "OBJECT_PID=") &&
- allow_object_pid(ucred)) {
- char buf[DECIMAL_STR_MAX(pid_t)];
- memcpy(buf, p + strlen("OBJECT_PID="), l - strlen("OBJECT_PID="));
- buf[l-strlen("OBJECT_PID=")] = '\0';
-
- /* ignore error */
- parse_pid(buf, &object_pid);
- }
+ server_process_entry_meta(p, l, ucred,
+ &priority,
+ &identifier,
+ &message,
+ &object_pid);
}
- remaining -= (e - p) + 1;
+ *remaining -= (e - p) + 1;
p = e + 1;
continue;
} else {
- le64_t l_le;
uint64_t l;
char *k;
- if (remaining < e - p + 1 + sizeof(uint64_t) + 1) {
+ if (*remaining < e - p + 1 + sizeof(uint64_t) + 1) {
log_debug("Failed to parse message, ignoring.");
break;
}
- memcpy(&l_le, e + 1, sizeof(uint64_t));
- l = le64toh(l_le);
+ l = unaligned_read_le64(e + 1);
if (l > DATA_SIZE_MAX) {
log_debug("Received binary data block of %"PRIu64" bytes is too large, ignoring.", l);
break;
}
- if ((uint64_t) remaining < e - p + 1 + sizeof(uint64_t) + l + 1 ||
+ if ((uint64_t) *remaining < e - p + 1 + sizeof(uint64_t) + l + 1 ||
e[1+sizeof(uint64_t)+l] != '\n') {
log_debug("Failed to parse message, ignoring.");
break;
@@ -255,16 +260,24 @@ void server_process_native_message(
iovec[n].iov_len = (e - p) + 1 + l;
entry_size += iovec[n].iov_len;
n++;
+
+ server_process_entry_meta(k, (e - p) + 1 + l, ucred,
+ &priority,
+ &identifier,
+ &message,
+ &object_pid);
} else
free(k);
- remaining -= (e - p) + 1 + sizeof(uint64_t) + l + 1;
+ *remaining -= (e - p) + 1 + sizeof(uint64_t) + l + 1;
p = e + 1 + sizeof(uint64_t) + l + 1;
}
}
- if (n <= 0)
+ if (n <= 0) {
+ r = 1;
goto finish;
+ }
tn = n++;
IOVEC_SET_STRING(iovec[tn], "_TRANSPORT=journal");
@@ -278,7 +291,7 @@ void server_process_native_message(
if (message) {
if (s->forward_to_syslog)
- server_forward_syslog(s, priority, identifier, message, ucred, tv);
+ server_forward_syslog(s, syslog_fixup_facility(priority), identifier, message, ucred, tv);
if (s->forward_to_kmsg)
server_forward_kmsg(s, priority, identifier, message, ucred);
@@ -298,13 +311,35 @@ finish:
continue;
if (iovec[j].iov_base < buffer ||
- (const uint8_t*) iovec[j].iov_base >= (const uint8_t*) buffer + buffer_size)
+ (const char*) iovec[j].iov_base >= p + *remaining)
free(iovec[j].iov_base);
}
free(iovec);
free(identifier);
free(message);
+
+ return r;
+}
+
+void server_process_native_message(
+ Server *s,
+ const void *buffer, size_t buffer_size,
+ const struct ucred *ucred,
+ const struct timeval *tv,
+ const char *label, size_t label_len) {
+
+ int r;
+ size_t remaining = buffer_size;
+
+ assert(s);
+ assert(buffer || buffer_size == 0);
+
+ do {
+ r = server_process_entry(s,
+ (const uint8_t*) buffer + (buffer_size - remaining), &remaining,
+ ucred, tv, label, label_len);
+ } while (r == 0);
}
void server_process_native_file(
diff --git a/src/journal/journald-native.h b/src/journal/journald-native.h
index c13b80aa4f..1ab415ac85 100644
--- a/src/journal/journald-native.h
+++ b/src/journal/journald-native.h
@@ -21,11 +21,6 @@
#include "journald-server.h"
-/* Make sure not to make this smaller than the maximum coredump
- * size. See COREDUMP_MAX in coredump.c */
-#define ENTRY_SIZE_MAX (1024*1024*770u)
-#define DATA_SIZE_MAX (1024*1024*768u)
-
bool valid_user_field(const char *p, size_t l, bool allow_protected);
void server_process_native_message(Server *s, const void *buffer, size_t buffer_size, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len);
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 50bd83fc6e..da85260ccd 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -40,7 +40,7 @@
#include "extract-word.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "fs-util.h"
#include "hashmap.h"
#include "hostname-util.h"
@@ -214,7 +214,7 @@ void server_space_usage_message(Server *s, JournalStorage *storage) {
format_bytes(fb5, sizeof(fb5), storage->space.limit);
format_bytes(fb6, sizeof(fb6), storage->space.available);
- server_driver_message(s, SD_MESSAGE_JOURNAL_USAGE,
+ server_driver_message(s, "MESSAGE_ID=" SD_MESSAGE_JOURNAL_USAGE_STR,
LOG_MESSAGE("%s (%s) is %s, max %s, %s free.",
storage->name, storage->path, fb1, fb5, fb6),
"JOURNAL_NAME=%s", storage->name,
@@ -283,17 +283,16 @@ static int open_journal(
}
static bool flushed_flag_is_set(void) {
- return (access("/run/systemd/journal/flushed", F_OK) >= 0);
+ return access("/run/systemd/journal/flushed", F_OK) >= 0;
}
static int system_journal_open(Server *s, bool flush_requested) {
- bool flushed = false;
const char *fn;
int r = 0;
if (!s->system_journal &&
- (s->storage == STORAGE_PERSISTENT || s->storage == STORAGE_AUTO) &&
- (flush_requested || (flushed = flushed_flag_is_set()))) {
+ IN_SET(s->storage, STORAGE_PERSISTENT, STORAGE_AUTO) &&
+ (flush_requested || flushed_flag_is_set())) {
/* If in auto mode: first try to create the machine
* path, but not the prefix.
@@ -326,8 +325,8 @@ static int system_journal_open(Server *s, bool flush_requested) {
* Perform an implicit flush to var, leaving the runtime
* journal closed, now that the system journal is back.
*/
- if (s->runtime_journal && flushed)
- (void) server_flush_to_var(s);
+ if (!flush_requested)
+ (void) server_flush_to_var(s, true);
}
if (!s->runtime_journal &&
@@ -731,7 +730,7 @@ static int get_invocation_id(const char *cgroup_root, const char *slice, const c
if (!escaped)
return -ENOMEM;
- p = strjoin(cgroup_root, "/", slice_path, "/", escaped, NULL);
+ p = strjoin(cgroup_root, "/", slice_path, "/", escaped);
if (!p)
return -ENOMEM;
@@ -761,7 +760,8 @@ static void dispatch_message_real(
const char *label, size_t label_len,
const char *unit_id,
int priority,
- pid_t object_pid) {
+ pid_t object_pid,
+ char *cgroup) {
char pid[sizeof("_PID=") + DECIMAL_STR_MAX(pid_t)],
uid[sizeof("_UID=") + DECIMAL_STR_MAX(uid_t)],
@@ -847,7 +847,12 @@ static void dispatch_message_real(
}
#endif
- r = cg_pid_get_path_shifted(ucred->pid, s->cgroup_root, &c);
+ r = 0;
+ if (cgroup)
+ c = cgroup;
+ else
+ r = cg_pid_get_path_shifted(ucred->pid, s->cgroup_root, &c);
+
if (r >= 0) {
_cleanup_free_ char *raw_unit = NULL, *raw_slice = NULL;
char *session = NULL;
@@ -905,7 +910,8 @@ static void dispatch_message_real(
}
}
- free(c);
+ if (!cgroup)
+ free(c);
} else if (unit_id) {
x = strjoina("_SYSTEMD_UNIT=", unit_id);
IOVEC_SET_STRING(iovec[n++], x);
@@ -1062,8 +1068,7 @@ static void dispatch_message_real(
write_to_journal(s, journal_uid, iovec, n, priority);
}
-void server_driver_message(Server *s, sd_id128_t message_id, const char *format, ...) {
- char mid[11 + 32 + 1];
+void server_driver_message(Server *s, const char *message_id, const char *format, ...) {
struct iovec iovec[N_IOVEC_META_FIELDS + 5 + N_IOVEC_PAYLOAD_FIELDS];
unsigned n = 0, m;
int r;
@@ -1081,11 +1086,8 @@ void server_driver_message(Server *s, sd_id128_t message_id, const char *format,
assert_cc(6 == LOG_INFO);
IOVEC_SET_STRING(iovec[n++], "PRIORITY=6");
- if (!sd_id128_is_null(message_id)) {
- snprintf(mid, sizeof(mid), LOG_MESSAGE_ID(message_id));
- IOVEC_SET_STRING(iovec[n++], mid);
- }
-
+ if (message_id)
+ IOVEC_SET_STRING(iovec[n++], message_id);
m = n;
va_start(ap, format);
@@ -1098,7 +1100,7 @@ void server_driver_message(Server *s, sd_id128_t message_id, const char *format,
ucred.gid = getgid();
if (r >= 0)
- dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL, LOG_INFO, 0);
+ dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL, LOG_INFO, 0, NULL);
while (m < n)
free(iovec[m++].iov_base);
@@ -1112,7 +1114,7 @@ void server_driver_message(Server *s, sd_id128_t message_id, const char *format,
n = 3;
IOVEC_SET_STRING(iovec[n++], "PRIORITY=4");
IOVEC_SET_STRING(iovec[n++], buf);
- dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL, LOG_INFO, 0);
+ dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL, LOG_INFO, 0, NULL);
}
}
@@ -1129,7 +1131,7 @@ void server_dispatch_message(
int rl, r;
_cleanup_free_ char *path = NULL;
uint64_t available = 0;
- char *c;
+ char *c = NULL;
assert(s);
assert(iovec || n == 0);
@@ -1175,15 +1177,18 @@ void server_dispatch_message(
/* Write a suppression message if we suppressed something */
if (rl > 1)
- server_driver_message(s, SD_MESSAGE_JOURNAL_DROPPED,
+ server_driver_message(s, "MESSAGE_ID=" SD_MESSAGE_JOURNAL_DROPPED_STR,
LOG_MESSAGE("Suppressed %u messages from %s", rl - 1, path),
NULL);
finish:
- dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len, unit_id, priority, object_pid);
+ /* restore cgroup path for logging */
+ if (c)
+ *c = '/';
+ dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len, unit_id, priority, object_pid, path);
}
-int server_flush_to_var(Server *s) {
+int server_flush_to_var(Server *s, bool require_flag_file) {
sd_id128_t machine;
sd_journal *j = NULL;
char ts[FORMAT_TIMESPAN_MAX];
@@ -1193,13 +1198,15 @@ int server_flush_to_var(Server *s) {
assert(s);
- if (s->storage != STORAGE_AUTO &&
- s->storage != STORAGE_PERSISTENT)
+ if (!IN_SET(s->storage, STORAGE_AUTO, STORAGE_PERSISTENT))
return 0;
if (!s->runtime_journal)
return 0;
+ if (require_flag_file && !flushed_flag_is_set())
+ return 0;
+
(void) system_journal_open(s, true);
if (!s->system_journal)
@@ -1272,7 +1279,7 @@ finish:
sd_journal_close(j);
- server_driver_message(s, SD_ID128_NULL,
+ server_driver_message(s, NULL,
LOG_MESSAGE("Time spent on flushing to /var is %s for %u entries.",
format_timespan(ts, sizeof(ts), now(CLOCK_MONOTONIC) - start, 0),
n),
@@ -1411,7 +1418,7 @@ static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo *
log_info("Received request to flush runtime journal from PID " PID_FMT, si->ssi_pid);
- (void) server_flush_to_var(s);
+ (void) server_flush_to_var(s, false);
server_sync(s);
server_vacuum(s, false);
@@ -1480,7 +1487,7 @@ static int setup_signals(Server *s) {
assert(s);
- assert(sigprocmask_many(SIG_SETMASK, NULL, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, SIGRTMIN+1, -1) >= 0);
+ assert_se(sigprocmask_many(SIG_SETMASK, NULL, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, SIGRTMIN+1, -1) >= 0);
r = sd_event_add_signal(s->event, &s->sigusr1_event_source, SIGUSR1, dispatch_sigusr1, s);
if (r < 0)
@@ -1532,60 +1539,93 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
assert(s);
- if (streq(key, "systemd.journald.forward_to_syslog")) {
+ if (proc_cmdline_key_streq(key, "systemd.journald.forward_to_syslog")) {
+
r = value ? parse_boolean(value) : true;
if (r < 0)
log_warning("Failed to parse forward to syslog switch \"%s\". Ignoring.", value);
else
s->forward_to_syslog = r;
- } else if (streq(key, "systemd.journald.forward_to_kmsg")) {
+
+ } else if (proc_cmdline_key_streq(key, "systemd.journald.forward_to_kmsg")) {
+
r = value ? parse_boolean(value) : true;
if (r < 0)
log_warning("Failed to parse forward to kmsg switch \"%s\". Ignoring.", value);
else
s->forward_to_kmsg = r;
- } else if (streq(key, "systemd.journald.forward_to_console")) {
+
+ } else if (proc_cmdline_key_streq(key, "systemd.journald.forward_to_console")) {
+
r = value ? parse_boolean(value) : true;
if (r < 0)
log_warning("Failed to parse forward to console switch \"%s\". Ignoring.", value);
else
s->forward_to_console = r;
- } else if (streq(key, "systemd.journald.forward_to_wall")) {
+
+ } else if (proc_cmdline_key_streq(key, "systemd.journald.forward_to_wall")) {
+
r = value ? parse_boolean(value) : true;
if (r < 0)
log_warning("Failed to parse forward to wall switch \"%s\". Ignoring.", value);
else
s->forward_to_wall = r;
- } else if (streq(key, "systemd.journald.max_level_console") && value) {
+
+ } else if (proc_cmdline_key_streq(key, "systemd.journald.max_level_console")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
r = log_level_from_string(value);
if (r < 0)
log_warning("Failed to parse max level console value \"%s\". Ignoring.", value);
else
s->max_level_console = r;
- } else if (streq(key, "systemd.journald.max_level_store") && value) {
+
+ } else if (proc_cmdline_key_streq(key, "systemd.journald.max_level_store")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
r = log_level_from_string(value);
if (r < 0)
log_warning("Failed to parse max level store value \"%s\". Ignoring.", value);
else
s->max_level_store = r;
- } else if (streq(key, "systemd.journald.max_level_syslog") && value) {
+
+ } else if (proc_cmdline_key_streq(key, "systemd.journald.max_level_syslog")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
r = log_level_from_string(value);
if (r < 0)
log_warning("Failed to parse max level syslog value \"%s\". Ignoring.", value);
else
s->max_level_syslog = r;
- } else if (streq(key, "systemd.journald.max_level_kmsg") && value) {
+
+ } else if (proc_cmdline_key_streq(key, "systemd.journald.max_level_kmsg")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
r = log_level_from_string(value);
if (r < 0)
log_warning("Failed to parse max level kmsg value \"%s\". Ignoring.", value);
else
s->max_level_kmsg = r;
- } else if (streq(key, "systemd.journald.max_level_wall") && value) {
+
+ } else if (proc_cmdline_key_streq(key, "systemd.journald.max_level_wall")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
r = log_level_from_string(value);
if (r < 0)
log_warning("Failed to parse max level wall value \"%s\". Ignoring.", value);
else
s->max_level_wall = r;
+
} else if (startswith(key, "systemd.journald"))
log_warning("Unknown journald kernel command line option \"%s\". Ignoring.", key);
@@ -1898,7 +1938,10 @@ int server_init(Server *s) {
journal_reset_metrics(&s->runtime_storage.metrics);
server_parse_config_file(s);
- parse_proc_cmdline(parse_proc_cmdline_item, s, true);
+
+ r = proc_cmdline_parse(parse_proc_cmdline_item, s, PROC_CMDLINE_STRIP_RD_PREFIX);
+ if (r < 0)
+ log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
if (!!s->rate_limit_interval ^ !!s->rate_limit_burst) {
log_debug("Setting both rate limit interval and burst from "USEC_FMT",%u to 0,0",
@@ -2051,8 +2094,8 @@ int server_init(Server *s) {
s->runtime_storage.name = "Runtime journal";
s->system_storage.name = "System journal";
- s->runtime_storage.path = strjoin("/run/log/journal/", SERVER_MACHINE_ID(s), NULL);
- s->system_storage.path = strjoin("/var/log/journal/", SERVER_MACHINE_ID(s), NULL);
+ s->runtime_storage.path = strjoin("/run/log/journal/", SERVER_MACHINE_ID(s));
+ s->system_storage.path = strjoin("/var/log/journal/", SERVER_MACHINE_ID(s));
if (!s->runtime_storage.path || !s->system_storage.path)
return -ENOMEM;
@@ -2134,6 +2177,8 @@ void server_done(Server *s) {
free(s->tty_path);
free(s->cgroup_root);
free(s->hostname_field);
+ free(s->runtime_storage.path);
+ free(s->system_storage.path);
if (s->mmap)
mmap_cache_unref(s->mmap);
diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h
index d1520c45dd..203460c50a 100644
--- a/src/journal/journald-server.h
+++ b/src/journal/journald-server.h
@@ -61,7 +61,7 @@ typedef struct JournalStorageSpace {
typedef struct JournalStorage {
const char *name;
- const char *path;
+ char *path;
JournalMetrics metrics;
JournalStorageSpace space;
@@ -176,7 +176,7 @@ struct Server {
#define N_IOVEC_PAYLOAD_FIELDS 15
void server_dispatch_message(Server *s, struct iovec *iovec, unsigned n, unsigned m, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len, const char *unit_id, int priority, pid_t object_pid);
-void server_driver_message(Server *s, sd_id128_t message_id, const char *format, ...) _printf_(3,0) _sentinel_;
+void server_driver_message(Server *s, const char *message_id, const char *format, ...) _printf_(3,0) _sentinel_;
/* gperf lookup function */
const struct ConfigPerfItem* journald_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
@@ -197,7 +197,7 @@ void server_sync(Server *s);
int server_vacuum(Server *s, bool verbose);
void server_rotate(Server *s);
int server_schedule_sync(Server *s, int priority);
-int server_flush_to_var(Server *s);
+int server_flush_to_var(Server *s, bool require_flag_file);
void server_maybe_append_tags(Server *s);
int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void *userdata);
void server_space_usage_message(Server *s, JournalStorage *storage);
diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c
index 0609b4b694..474369039a 100644
--- a/src/journal/journald-syslog.c
+++ b/src/journal/journald-syslog.c
@@ -25,7 +25,7 @@
#include "alloc-util.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "io-util.h"
#include "journald-console.h"
#include "journald-kmsg.h"
@@ -444,7 +444,8 @@ void server_maybe_warn_forward_syslog_missed(Server *s) {
if (s->last_warn_forward_syslog_missed + WARN_FORWARD_SYSLOG_MISSED_USEC > n)
return;
- server_driver_message(s, SD_MESSAGE_FORWARD_SYSLOG_MISSED,
+ server_driver_message(s,
+ "MESSAGE_ID=" SD_MESSAGE_FORWARD_SYSLOG_MISSED_STR,
LOG_MESSAGE("Forwarding to syslog missed %u messages.",
s->n_forward_syslog_missed),
NULL);
diff --git a/src/journal/journald-wall.c b/src/journal/journald-wall.c
index 4d91fafffe..bfe53ce39d 100644
--- a/src/journal/journald-wall.c
+++ b/src/journal/journald-wall.c
@@ -18,7 +18,7 @@
***/
#include "alloc-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "journald-server.h"
#include "journald-wall.h"
#include "process-util.h"
@@ -57,7 +57,7 @@ void server_forward_wall(
} else if (identifier) {
- l = l_buf = strjoin(identifier, ": ", message, NULL);
+ l = l_buf = strjoin(identifier, ": ", message);
if (!l_buf) {
log_oom();
return;
diff --git a/src/journal/journald.c b/src/journal/journald.c
index 7f47ca22dd..1aaef387b4 100644
--- a/src/journal/journald.c
+++ b/src/journal/journald.c
@@ -22,7 +22,7 @@
#include "sd-daemon.h"
#include "sd-messages.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "journal-authenticate.h"
#include "journald-kmsg.h"
#include "journald-server.h"
@@ -52,11 +52,12 @@ int main(int argc, char *argv[]) {
goto finish;
server_vacuum(&server, false);
- server_flush_to_var(&server);
+ server_flush_to_var(&server, true);
server_flush_dev_kmsg(&server);
log_debug("systemd-journald running as pid "PID_FMT, getpid());
- server_driver_message(&server, SD_MESSAGE_JOURNAL_START,
+ server_driver_message(&server,
+ "MESSAGE_ID=" SD_MESSAGE_JOURNAL_START_STR,
LOG_MESSAGE("Journal started"),
NULL);
@@ -114,7 +115,8 @@ int main(int argc, char *argv[]) {
}
log_debug("systemd-journald stopped as pid "PID_FMT, getpid());
- server_driver_message(&server, SD_MESSAGE_JOURNAL_STOP,
+ server_driver_message(&server,
+ "MESSAGE_ID=" SD_MESSAGE_JOURNAL_STOP_STR,
LOG_MESSAGE("Journal stopped"),
NULL);
diff --git a/src/journal/lookup3.c b/src/journal/lookup3.c
index d8f1a4977d..ec725ce46c 100644
--- a/src/journal/lookup3.c
+++ b/src/journal/lookup3.c
@@ -48,6 +48,10 @@ on 1 byte), but shoehorning those bytes into integers efficiently is messy.
# include <endian.h> /* attempt to define endianness */
#endif
+#if __GNUC__ >= 7
+_Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
+#endif
+
/*
* My best guess at if you are big-endian or little-endian. This may
* need adjustment.
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index f2f8546086..86afb4985d 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -35,7 +35,7 @@
#include "dirent-util.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "fs-util.h"
#include "hashmap.h"
#include "hostname-util.h"
@@ -405,7 +405,7 @@ static char *match_make_string(Match *m) {
return mfree(p);
if (p) {
- k = strjoin(p, m->type == MATCH_OR_TERM ? " OR " : " AND ", t, NULL);
+ k = strjoin(p, m->type == MATCH_OR_TERM ? " OR " : " AND ", t);
free(p);
free(t);
@@ -420,7 +420,7 @@ static char *match_make_string(Match *m) {
}
if (enclose) {
- r = strjoin("(", p, ")", NULL);
+ r = strjoin("(", p, ")");
free(p);
return r;
}
@@ -1416,7 +1416,7 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname)
* and reenumerates directory contents */
if (dirname)
- path = strjoin(prefix, "/", dirname, NULL);
+ path = strjoin(prefix, "/", dirname);
else
path = strdup(prefix);
if (!path) {
@@ -1661,6 +1661,9 @@ static int add_search_paths(sd_journal *j) {
NULSTR_FOREACH(p, search_paths)
(void) add_root_directory(j, p, true);
+ if (!(j->flags & SD_JOURNAL_LOCAL_ONLY))
+ (void) add_root_directory(j, "/var/log/journal/remote", true);
+
return 0;
}
@@ -2421,6 +2424,7 @@ _public_ int sd_journal_process(sd_journal *j) {
assert_return(!journal_pid_changed(j), -ECHILD);
j->last_process_usec = now(CLOCK_MONOTONIC);
+ j->last_invalidate_counter = j->current_invalidate_counter;
for (;;) {
union inotify_event_buffer buffer;
diff --git a/src/journal/test-compress.c b/src/journal/test-compress.c
index 72cadf1771..44a2cf5217 100644
--- a/src/journal/test-compress.c
+++ b/src/journal/test-compress.c
@@ -109,7 +109,7 @@ static void test_decompress_startswith(int compression,
size_t csize, usize = 0, len;
int r;
- log_info("/* testing decompress_startswith with %s on %.20s text*/",
+ log_info("/* testing decompress_startswith with %s on %.20s text */",
object_compressed_to_string(compression), data);
#define BUFSIZE_1 512
@@ -216,7 +216,11 @@ static void test_lz4_decompress_partial(void) {
memset(huge, 'x', HUGE_SIZE);
memcpy(huge, "HUGE=", 5);
+#if LZ4_VERSION_NUMBER >= 10700
+ r = LZ4_compress_default(huge, buf, HUGE_SIZE, buf_size);
+#else
r = LZ4_compress_limitedOutput(huge, buf, HUGE_SIZE, buf_size);
+#endif
assert_se(r >= 0);
compressed = r;
log_info("Compressed %i → %zu", HUGE_SIZE, compressed);
diff --git a/src/kernel-install/kernel-install b/src/kernel-install/kernel-install
index 0c0ee718ac..c7d9f4eea9 100644
--- a/src/kernel-install/kernel-install
+++ b/src/kernel-install/kernel-install
@@ -34,7 +34,7 @@ dropindirs_sort()
local -a files
local f d i
- readarray -t files < <(
+ readarray -t files <<<"$(
for d in "$@"; do
for i in "$d/"*"$suffix"; do
if [[ -e "$i" ]]; then
@@ -42,7 +42,7 @@ dropindirs_sort()
fi
done
done | sort -Vu
- )
+ )"
for f in "${files[@]}"; do
for d in "$@"; do
@@ -104,11 +104,11 @@ fi
ret=0
-readarray -t PLUGINS < <(
+readarray -t PLUGINS <<<"$(
dropindirs_sort ".install" \
"/etc/kernel/install.d" \
"/usr/lib/kernel/install.d"
-)
+)"
case $COMMAND in
add)
@@ -127,7 +127,7 @@ case $COMMAND in
"$f" add "$KERNEL_VERSION" "$BOOT_DIR_ABS" "$KERNEL_IMAGE"
x=$?
if [[ $x == $SKIP_REMAINING ]]; then
- return 0
+ exit 0
fi
((ret+=$x))
fi
@@ -140,7 +140,7 @@ case $COMMAND in
"$f" remove "$KERNEL_VERSION" "$BOOT_DIR_ABS"
x=$?
if [[ $x == $SKIP_REMAINING ]]; then
- return 0
+ exit 0
fi
((ret+=$x))
fi
diff --git a/src/libsystemd-network/arp-util.c b/src/libsystemd-network/arp-util.c
index 02028bf28a..2e02b3fa66 100644
--- a/src/libsystemd-network/arp-util.c
+++ b/src/libsystemd-network/arp-util.c
@@ -58,7 +58,7 @@ int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_
BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 1), /* A == 0 ? */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
- /* Sender Protocol Address or Target Protocol Address must be equal to the one we care about*/
+ /* Sender Protocol Address or Target Protocol Address must be equal to the one we care about */
BPF_STMT(BPF_LD + BPF_IMM, htobe32(address)), /* A <- clients IP */
BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct ether_arp, arp_spa)), /* A <- SPA */
diff --git a/src/libsystemd-network/dhcp-internal.h b/src/libsystemd-network/dhcp-internal.h
index 99f690897d..3fdf02da3e 100644
--- a/src/libsystemd-network/dhcp-internal.h
+++ b/src/libsystemd-network/dhcp-internal.h
@@ -30,10 +30,11 @@
#include "dhcp-protocol.h"
#include "socket-util.h"
-int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link,
+int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,
uint32_t xid, const uint8_t *mac_addr,
- size_t mac_addr_len, uint16_t arp_type);
-int dhcp_network_bind_udp_socket(be32_t address, uint16_t port);
+ size_t mac_addr_len, uint16_t arp_type,
+ uint16_t port);
+int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port);
int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
const void *packet, size_t len);
int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,
@@ -57,7 +58,7 @@ void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr,
uint16_t source, be32_t destination_addr,
uint16_t destination, uint16_t len);
-int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum);
+int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum, uint16_t port);
/* If we are invoking callbacks of a dhcp-client, ensure unreffing the
* client from the callback doesn't destroy the object we are working
diff --git a/src/libsystemd-network/dhcp-network.c b/src/libsystemd-network/dhcp-network.c
index a9f5a0a5de..65405dcce0 100644
--- a/src/libsystemd-network/dhcp-network.c
+++ b/src/libsystemd-network/dhcp-network.c
@@ -19,6 +19,7 @@
#include <errno.h>
#include <net/ethernet.h>
+#include <net/if.h>
#include <net/if_arp.h>
#include <stdio.h>
#include <string.h>
@@ -36,7 +37,8 @@ static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
size_t mac_addr_len,
const uint8_t *bcast_addr,
const struct ether_addr *eth_mac,
- uint16_t arp_type, uint8_t dhcp_hlen) {
+ uint16_t arp_type, uint8_t dhcp_hlen,
+ uint16_t port) {
struct sock_filter filter[] = {
BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0), /* A <- packet length */
BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(DHCPPacket), 1, 0), /* packet >= DHCPPacket ? */
@@ -53,7 +55,7 @@ static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0), /* A == 0 ? */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(DHCPPacket, udp.dest)), /* A <- UDP destination port */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP_PORT_CLIENT, 1, 0), /* UDP destination port == DHCP client port ? */
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, port, 1, 0), /* UDP destination port == DHCP client port ? */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.op)), /* A <- DHCP op */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, BOOTREPLY, 1, 0), /* op == BOOTREPLY ? */
@@ -125,7 +127,8 @@ static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,
uint32_t xid, const uint8_t *mac_addr,
- size_t mac_addr_len, uint16_t arp_type) {
+ size_t mac_addr_len, uint16_t arp_type,
+ uint16_t port) {
static const uint8_t eth_bcast[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
/* Default broadcast address for IPoIB */
static const uint8_t ib_bcast[] = {
@@ -151,16 +154,17 @@ int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,
return -EINVAL;
return _bind_raw_socket(ifindex, link, xid, mac_addr, mac_addr_len,
- bcast_addr, &eth_mac, arp_type, dhcp_hlen);
+ bcast_addr, &eth_mac, arp_type, dhcp_hlen, port);
}
-int dhcp_network_bind_udp_socket(be32_t address, uint16_t port) {
+int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port) {
union sockaddr_union src = {
.in.sin_family = AF_INET,
.in.sin_port = htobe16(port),
.in.sin_addr.s_addr = address,
};
_cleanup_close_ int s = -1;
+ char ifname[IF_NAMESIZE] = "";
int r, on = 1, tos = IPTOS_CLASS_CS6;
s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
@@ -175,6 +179,15 @@ int dhcp_network_bind_udp_socket(be32_t address, uint16_t port) {
if (r < 0)
return -errno;
+ if (ifindex > 0) {
+ if (if_indextoname(ifindex, ifname) == 0)
+ return -errno;
+
+ r = setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname));
+ if (r < 0)
+ return -errno;
+ }
+
if (address == INADDR_ANY) {
r = setsockopt(s, IPPROTO_IP, IP_PKTINFO, &on, sizeof(on));
if (r < 0)
@@ -183,6 +196,7 @@ int dhcp_network_bind_udp_socket(be32_t address, uint16_t port) {
r = setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
if (r < 0)
return -errno;
+
} else {
r = setsockopt(s, IPPROTO_IP, IP_FREEBIND, &on, sizeof(on));
if (r < 0)
diff --git a/src/libsystemd-network/dhcp-packet.c b/src/libsystemd-network/dhcp-packet.c
index 8be774061d..40442b3636 100644
--- a/src/libsystemd-network/dhcp-packet.c
+++ b/src/libsystemd-network/dhcp-packet.c
@@ -114,7 +114,7 @@ void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr,
packet->ip.check = dhcp_packet_checksum((uint8_t*)&packet->ip, DHCP_IP_SIZE);
}
-int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum) {
+int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum, uint16_t port) {
size_t hdrlen;
assert(packet);
@@ -160,10 +160,10 @@ int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum) {
return -EINVAL;
}
- if (be16toh(packet->udp.dest) != DHCP_PORT_CLIENT) {
+ if (be16toh(packet->udp.dest) != port) {
log_debug("ignoring packet: to port %u, which "
"is not the DHCP client port (%u)",
- be16toh(packet->udp.dest), DHCP_PORT_CLIENT);
+ be16toh(packet->udp.dest), port);
return -EINVAL;
}
diff --git a/src/libsystemd-network/dhcp6-option.c b/src/libsystemd-network/dhcp6-option.c
index 5462e03476..f8056dbc4b 100644
--- a/src/libsystemd-network/dhcp6-option.c
+++ b/src/libsystemd-network/dhcp6-option.c
@@ -339,7 +339,7 @@ int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char ***str_arr) {
size_t pos = 0, idx = 0;
- _cleanup_free_ char **names = NULL;
+ _cleanup_strv_free_ char **names = NULL;
int r;
assert_return(optlen > 1, -ENODATA);
diff --git a/src/libsystemd-network/lldp-network.c b/src/libsystemd-network/lldp-network.c
index 59c25598e9..ae2f6744d5 100644
--- a/src/libsystemd-network/lldp-network.c
+++ b/src/libsystemd-network/lldp-network.c
@@ -47,6 +47,13 @@ int lldp_network_bind_raw_socket(int ifindex) {
.filter = (struct sock_filter*) filter,
};
+ struct packet_mreq mreq = {
+ .mr_ifindex = ifindex,
+ .mr_type = PACKET_MR_MULTICAST,
+ .mr_alen = ETH_ALEN,
+ .mr_address = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x00 }
+ };
+
union sockaddr_union saddrll = {
.ll.sll_family = AF_PACKET,
.ll.sll_ifindex = ifindex,
@@ -66,6 +73,20 @@ int lldp_network_bind_raw_socket(int ifindex) {
if (r < 0)
return -errno;
+ r = setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
+ if (r < 0)
+ return -errno;
+
+ mreq.mr_address[ETH_ALEN - 1] = 0x03;
+ r = setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
+ if (r < 0)
+ return -errno;
+
+ mreq.mr_address[ETH_ALEN - 1] = 0x0E;
+ r = setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
+ if (r < 0)
+ return -errno;
+
r = bind(fd, &saddrll.sa, sizeof(saddrll.ll));
if (r < 0)
return -errno;
diff --git a/src/libsystemd-network/ndisc-router.c b/src/libsystemd-network/ndisc-router.c
index 41ff2b353a..845a6b7c6c 100644
--- a/src/libsystemd-network/ndisc-router.c
+++ b/src/libsystemd-network/ndisc-router.c
@@ -91,7 +91,7 @@ _public_ int sd_ndisc_router_get_address(sd_ndisc_router *rt, struct in6_addr *r
assert_return(rt, -EINVAL);
assert_return(ret_addr, -EINVAL);
- if (in6_addr_is_null(&rt->address))
+ if (IN6_IS_ADDR_UNSPECIFIED(&rt->address))
return -ENODATA;
*ret_addr = rt->address;
@@ -459,6 +459,7 @@ _public_ int sd_ndisc_router_prefix_get_preferred_lifetime(sd_ndisc_router *rt,
_public_ int sd_ndisc_router_prefix_get_flags(sd_ndisc_router *rt, uint8_t *ret) {
struct nd_opt_prefix_info *pi;
+ uint8_t flags;
int r;
assert_return(rt, -EINVAL);
@@ -468,7 +469,14 @@ _public_ int sd_ndisc_router_prefix_get_flags(sd_ndisc_router *rt, uint8_t *ret)
if (r < 0)
return r;
- *ret = pi->nd_opt_pi_flags_reserved;
+ flags = pi->nd_opt_pi_flags_reserved;
+
+ if ((flags & ND_OPT_PI_FLAG_AUTO) && (pi->nd_opt_pi_prefix_len != 64)) {
+ log_ndisc("Invalid prefix length, ignoring prefix for stateless autoconfiguration.");
+ flags &= ~ND_OPT_PI_FLAG_AUTO;
+ }
+
+ *ret = flags;
return 0;
}
diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c
index 9d78b953fc..092a1eabb0 100644
--- a/src/libsystemd-network/network-internal.c
+++ b/src/libsystemd-network/network-internal.c
@@ -86,6 +86,28 @@ int net_get_unique_predictable_data(struct udev_device *device, uint64_t *result
return 0;
}
+static bool net_condition_test_strv(char * const *raw_patterns,
+ const char *string) {
+ if (strv_isempty(raw_patterns))
+ return true;
+
+ /* If the patterns begin with "!", edit it out and negate the test. */
+ if (raw_patterns[0][0] == '!') {
+ char **patterns;
+ unsigned i, length;
+
+ length = strv_length(raw_patterns) + 1; /* Include the NULL. */
+ patterns = newa(char*, length);
+ patterns[0] = raw_patterns[0] + 1; /* Skip the "!". */
+ for (i = 1; i < length; i++)
+ patterns[i] = raw_patterns[i];
+
+ return !string || !strv_fnmatch(patterns, string, 0);
+ }
+
+ return string && strv_fnmatch(raw_patterns, string, 0);
+}
+
bool net_match_config(const struct ether_addr *match_mac,
char * const *match_paths,
char * const *match_drivers,
@@ -117,20 +139,16 @@ bool net_match_config(const struct ether_addr *match_mac,
if (match_mac && (!dev_mac || memcmp(match_mac, dev_mac, ETH_ALEN)))
return false;
- if (!strv_isempty(match_paths) &&
- (!dev_path || !strv_fnmatch(match_paths, dev_path, 0)))
+ if (!net_condition_test_strv(match_paths, dev_path))
return false;
- if (!strv_isempty(match_drivers) &&
- (!dev_driver || !strv_fnmatch(match_drivers, dev_driver, 0)))
+ if (!net_condition_test_strv(match_drivers, dev_driver))
return false;
- if (!strv_isempty(match_types) &&
- (!dev_type || !strv_fnmatch_or_empty(match_types, dev_type, 0)))
+ if (!net_condition_test_strv(match_types, dev_type))
return false;
- if (!strv_isempty(match_names) &&
- (!dev_name || !strv_fnmatch_or_empty(match_names, dev_name, 0)))
+ if (!net_condition_test_strv(match_names, dev_name))
return false;
return true;
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index 5ccb23922c..7c0317640f 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -55,6 +55,7 @@ struct sd_dhcp_client {
sd_event_source *timeout_resend;
int ifindex;
int fd;
+ uint16_t port;
union sockaddr_union link;
sd_event_source *receive_message;
bool request_broadcast;
@@ -385,43 +386,32 @@ int sd_dhcp_client_set_hostname(
sd_dhcp_client *client,
const char *hostname) {
- char *new_hostname = NULL;
-
assert_return(client, -EINVAL);
- if (!hostname_is_valid(hostname, false) && !dns_name_is_valid(hostname))
+ /* Refuse hostnames that neither qualify as DNS nor as Linux hosntames */
+ if (hostname &&
+ !(hostname_is_valid(hostname, false) || dns_name_is_valid(hostname) > 0))
return -EINVAL;
- if (streq_ptr(client->hostname, hostname))
- return 0;
-
- if (hostname) {
- new_hostname = strdup(hostname);
- if (!new_hostname)
- return -ENOMEM;
- }
-
- free(client->hostname);
- client->hostname = new_hostname;
-
- return 0;
+ return free_and_strdup(&client->hostname, hostname);
}
int sd_dhcp_client_set_vendor_class_identifier(
sd_dhcp_client *client,
const char *vci) {
- char *new_vci = NULL;
-
assert_return(client, -EINVAL);
- new_vci = strdup(vci);
- if (!new_vci)
- return -ENOMEM;
+ return free_and_strdup(&client->vendor_class_identifier, vci);
+}
- free(client->vendor_class_identifier);
+int sd_dhcp_client_set_client_port(
+ sd_dhcp_client *client,
+ uint16_t port) {
+
+ assert_return(client, -EINVAL);
- client->vendor_class_identifier = new_vci;
+ client->port = port;
return 0;
}
@@ -668,7 +658,7 @@ static int dhcp_client_send_raw(
DHCPPacket *packet,
size_t len) {
- dhcp_packet_append_ip_headers(packet, INADDR_ANY, DHCP_PORT_CLIENT,
+ dhcp_packet_append_ip_headers(packet, INADDR_ANY, client->port,
INADDR_BROADCAST, DHCP_PORT_SERVER, len);
return dhcp_network_send_raw_socket(client->fd, &client->link,
@@ -835,6 +825,15 @@ static int client_send_request(sd_dhcp_client *client) {
return r;
}
+ if (client->vendor_class_identifier) {
+ r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
+ SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER,
+ strlen(client->vendor_class_identifier),
+ client->vendor_class_identifier);
+ if (r < 0)
+ return r;
+ }
+
r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
SD_DHCP_OPTION_END, 0, NULL);
if (r < 0)
@@ -1120,7 +1119,7 @@ static int client_start_delayed(sd_dhcp_client *client) {
r = dhcp_network_bind_raw_socket(client->ifindex, &client->link,
client->xid, client->mac_addr,
- client->mac_addr_len, client->arp_type);
+ client->mac_addr_len, client->arp_type, client->port);
if (r < 0) {
client_stop(client, r);
return r;
@@ -1170,7 +1169,8 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata)
r = dhcp_network_bind_raw_socket(client->ifindex, &client->link,
client->xid, client->mac_addr,
- client->mac_addr_len, client->arp_type);
+ client->mac_addr_len, client->arp_type,
+ client->port);
if (r < 0) {
client_stop(client, r);
return 0;
@@ -1555,8 +1555,7 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
goto error;
}
- r = dhcp_network_bind_udp_socket(client->lease->address,
- DHCP_PORT_CLIENT);
+ r = dhcp_network_bind_udp_socket(client->ifindex, client->lease->address, client->port);
if (r < 0) {
log_dhcp_client(client, "could not bind UDP socket");
goto error;
@@ -1766,7 +1765,7 @@ static int client_receive_message_raw(
}
}
- r = dhcp_packet_verify_headers(packet, len, checksum);
+ r = dhcp_packet_verify_headers(packet, len, checksum, client->port);
if (r < 0)
return 0;
@@ -1891,6 +1890,7 @@ int sd_dhcp_client_new(sd_dhcp_client **ret) {
client->fd = -1;
client->attempt = 1;
client->mtu = DHCP_DEFAULT_MIN_SIZE;
+ client->port = DHCP_PORT_CLIENT;
client->req_opts_size = ELEMENTSOF(default_req_opts);
client->req_opts = memdup(default_req_opts, client->req_opts_size);
diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c
index 8387b185c0..13dc6e4386 100644
--- a/src/libsystemd-network/sd-dhcp-lease.c
+++ b/src/libsystemd-network/sd-dhcp-lease.c
@@ -383,6 +383,23 @@ static int lease_parse_domain(const uint8_t *option, size_t len, char **ret) {
return 0;
}
+static void filter_bogus_addresses(struct in_addr *addresses, size_t *n) {
+ size_t i, j;
+
+ /* Silently filter DNS/NTP servers supplied to us that do not make outside of the local scope. */
+
+ for (i = 0, j = 0; i < *n; i ++) {
+
+ if (in4_addr_is_null(addresses+i) ||
+ in4_addr_is_localhost(addresses+i))
+ continue;
+
+ addresses[j++] = addresses[i];
+ }
+
+ *n = j;
+}
+
static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_addr **ret, size_t *n_ret) {
assert(option);
assert(ret);
@@ -404,6 +421,8 @@ static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_add
if (!addresses)
return -ENOMEM;
+ filter_bogus_addresses(addresses, &n_addresses);
+
free(*ret);
*ret = addresses;
*n_ret = n_addresses;
@@ -575,6 +594,11 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
r = lease_parse_u16(option, len, &lease->mtu, 68);
if (r < 0)
log_debug_errno(r, "Failed to parse MTU, ignoring: %m");
+ if (lease->mtu < DHCP_DEFAULT_MIN_SIZE) {
+ log_debug("MTU value of %" PRIu16 " too small. Using default MTU value of %d instead.", lease->mtu, DHCP_DEFAULT_MIN_SIZE);
+ lease->mtu = DHCP_DEFAULT_MIN_SIZE;
+ }
+
break;
case SD_DHCP_OPTION_DOMAIN_NAME:
diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c
index f16314a37f..315cbf1ac5 100644
--- a/src/libsystemd-network/sd-dhcp-server.c
+++ b/src/libsystemd-network/sd-dhcp-server.c
@@ -197,7 +197,11 @@ int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex) {
server->address = htobe32(INADDR_ANY);
server->netmask = htobe32(INADDR_ANY);
server->ifindex = ifindex;
+
server->leases_by_client_id = hashmap_new(&client_id_hash_ops);
+ if (!server->leases_by_client_id)
+ return -ENOMEM;
+
server->default_lease_time = DIV_ROUND_UP(DHCP_DEFAULT_LEASE_TIME_USEC, USEC_PER_SEC);
server->max_lease_time = DIV_ROUND_UP(DHCP_MAX_LEASE_TIME_USEC, USEC_PER_SEC);
@@ -857,7 +861,9 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
if (!existing_lease) {
lease = new0(DHCPLease, 1);
- lease->address = req->requested_ip;
+ if (!lease)
+ return -ENOMEM;
+ lease->address = address;
lease->client_id.data = memdup(req->client_id.data,
req->client_id.length);
if (!lease->client_id.data) {
@@ -1022,7 +1028,7 @@ int sd_dhcp_server_start(sd_dhcp_server *server) {
}
server->fd_raw = r;
- r = dhcp_network_bind_udp_socket(INADDR_ANY, DHCP_PORT_SERVER);
+ r = dhcp_network_bind_udp_socket(server->ifindex, INADDR_ANY, DHCP_PORT_SERVER);
if (r < 0) {
sd_dhcp_server_stop(server);
return r;
diff --git a/src/libsystemd-network/sd-dhcp6-lease.c b/src/libsystemd-network/sd-dhcp6-lease.c
index ab59977a3f..8396407e9f 100644
--- a/src/libsystemd-network/sd-dhcp6-lease.c
+++ b/src/libsystemd-network/sd-dhcp6-lease.c
@@ -226,7 +226,7 @@ int dhcp6_lease_set_domains(sd_dhcp6_lease *lease, uint8_t *optval,
if (r < 0)
return 0;
- free(lease->domains);
+ strv_free(lease->domains);
lease->domains = domains;
lease->domains_count = r;
diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c
index 4dd343c101..2ebc00f247 100644
--- a/src/libsystemd-network/sd-ipv4acd.c
+++ b/src/libsystemd-network/sd-ipv4acd.c
@@ -242,8 +242,6 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata)
r = ipv4acd_set_next_wakeup(acd, RATE_LIMIT_INTERVAL_USEC, PROBE_WAIT_USEC);
if (r < 0)
goto fail;
-
- acd->n_conflict = 0;
} else {
r = ipv4acd_set_next_wakeup(acd, 0, PROBE_WAIT_USEC);
if (r < 0)
diff --git a/src/libsystemd-network/test-dhcp-client.c b/src/libsystemd-network/test-dhcp-client.c
index 2a101cb1fe..f5f1284e6d 100644
--- a/src/libsystemd-network/test-dhcp-client.c
+++ b/src/libsystemd-network/test-dhcp-client.c
@@ -195,7 +195,7 @@ int dhcp_network_bind_raw_socket(
union sockaddr_union *link,
uint32_t id,
const uint8_t *addr, size_t addr_len,
- uint16_t arp_type) {
+ uint16_t arp_type, uint16_t port) {
if (socketpair(AF_UNIX, SOCK_STREAM, 0, test_fd) < 0)
return -errno;
@@ -203,7 +203,7 @@ int dhcp_network_bind_raw_socket(
return test_fd[0];
}
-int dhcp_network_bind_udp_socket(be32_t address, uint16_t port) {
+int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port) {
int fd;
fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0);
diff --git a/src/libsystemd-network/test-lldp.c b/src/libsystemd-network/test-lldp.c
index 6bcd65de0a..430c58ae60 100644
--- a/src/libsystemd-network/test-lldp.c
+++ b/src/libsystemd-network/test-lldp.c
@@ -98,14 +98,14 @@ static void test_receive_basic_packet(sd_event *e) {
static const uint8_t frame[] = {
/* Ethernet header */
- 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03, /* Destination MAC*/
+ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03, /* Destination MAC */
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, /* Source MAC */
0x88, 0xcc, /* Ethertype */
/* LLDP mandatory TLVs */
0x02, 0x07, 0x04, 0x00, 0x01, 0x02, /* Chassis: MAC, 00:01:02:03:04:05 */
0x03, 0x04, 0x05,
0x04, 0x04, 0x05, 0x31, 0x2f, 0x33, /* Port: interface name, "1/3" */
- 0x06, 0x02, 0x00, 0x78, /* TTL: 120 seconds*/
+ 0x06, 0x02, 0x00, 0x78, /* TTL: 120 seconds */
/* LLDP optional TLVs */
0x08, 0x04, 0x50, 0x6f, 0x72, 0x74, /* Port Description: "Port" */
0x0a, 0x03, 0x53, 0x59, 0x53, /* System Name: "SYS" */
@@ -162,7 +162,7 @@ static void test_receive_incomplete_packet(sd_event *e) {
sd_lldp_neighbor **neighbors;
uint8_t frame[] = {
/* Ethernet header */
- 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03, /* Destination MAC*/
+ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03, /* Destination MAC */
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, /* Source MAC */
0x88, 0xcc, /* Ethertype */
/* LLDP mandatory TLVs */
@@ -189,14 +189,14 @@ static void test_receive_oui_packet(sd_event *e) {
sd_lldp_neighbor **neighbors;
uint8_t frame[] = {
/* Ethernet header */
- 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03, /* Destination MAC*/
+ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03, /* Destination MAC */
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, /* Source MAC */
0x88, 0xcc, /* Ethertype */
/* LLDP mandatory TLVs */
0x02, 0x07, 0x04, 0x00, 0x01, 0x02, /* Chassis: MAC, 00:01:02:03:04:05 */
0x03, 0x04, 0x05,
0x04, 0x04, 0x05, 0x31, 0x2f, 0x33, /* Port TLV: interface name, "1/3" */
- 0x06, 0x02, 0x00, 0x78, /* TTL: 120 seconds*/
+ 0x06, 0x02, 0x00, 0x78, /* TTL: 120 seconds */
/* LLDP optional TLVs */
0xfe, 0x06, 0x00, 0x80, 0xc2, 0x01, /* Port VLAN ID: 0x1234 */
0x12, 0x34,
diff --git a/src/libsystemd/libsystemd.pc.in b/src/libsystemd/libsystemd.pc.in
index e8f79507ea..7e6d4999cb 100644
--- a/src/libsystemd/libsystemd.pc.in
+++ b/src/libsystemd/libsystemd.pc.in
@@ -7,7 +7,7 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
-libdir=@libdir@
+libdir=@rootlibdir@
includedir=@includedir@
Name: systemd
diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym
index d48ef6bbe2..c1135ffa22 100644
--- a/src/libsystemd/libsystemd.sym
+++ b/src/libsystemd/libsystemd.sym
@@ -511,3 +511,9 @@ global:
sd_bus_get_exit_on_disconnect;
sd_id128_get_invocation;
} LIBSYSTEMD_231;
+
+LIBSYSTEMD_233 {
+global:
+ sd_id128_get_machine_app_specific;
+ sd_is_socket_sockaddr;
+} LIBSYSTEMD_232;
diff --git a/src/libsystemd/sd-bus/bus-common-errors.c b/src/libsystemd/sd-bus/bus-common-errors.c
index d2a826bf6e..b40ba2520c 100644
--- a/src/libsystemd/sd-bus/bus-common-errors.c
+++ b/src/libsystemd/sd-bus/bus-common-errors.c
@@ -38,7 +38,7 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = {
SD_BUS_ERROR_MAP(BUS_ERROR_TRANSACTION_JOBS_CONFLICTING, EDEADLK),
SD_BUS_ERROR_MAP(BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC, EDEADLK),
SD_BUS_ERROR_MAP(BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE, EDEADLK),
- SD_BUS_ERROR_MAP(BUS_ERROR_UNIT_MASKED, ESHUTDOWN),
+ SD_BUS_ERROR_MAP(BUS_ERROR_UNIT_MASKED, ERFKILL),
SD_BUS_ERROR_MAP(BUS_ERROR_UNIT_GENERATED, EADDRNOTAVAIL),
SD_BUS_ERROR_MAP(BUS_ERROR_UNIT_LINKED, ELOOP),
SD_BUS_ERROR_MAP(BUS_ERROR_JOB_TYPE_NOT_APPLICABLE, EBADR),
@@ -47,6 +47,7 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = {
SD_BUS_ERROR_MAP(BUS_ERROR_SCOPE_NOT_RUNNING, EHOSTDOWN),
SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_DYNAMIC_USER, ESRCH),
SD_BUS_ERROR_MAP(BUS_ERROR_NOT_REFERENCED, EUNATCH),
+ SD_BUS_ERROR_MAP(BUS_ERROR_DISK_FULL, ENOSPC),
SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_MACHINE, ENXIO),
SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_IMAGE, ENOENT),
diff --git a/src/libsystemd/sd-bus/bus-common-errors.h b/src/libsystemd/sd-bus/bus-common-errors.h
index 525b79fa77..4523be05ce 100644
--- a/src/libsystemd/sd-bus/bus-common-errors.h
+++ b/src/libsystemd/sd-bus/bus-common-errors.h
@@ -43,6 +43,7 @@
#define BUS_ERROR_SCOPE_NOT_RUNNING "org.freedesktop.systemd1.ScopeNotRunning"
#define BUS_ERROR_NO_SUCH_DYNAMIC_USER "org.freedesktop.systemd1.NoSuchDynamicUser"
#define BUS_ERROR_NOT_REFERENCED "org.freedesktop.systemd1.NotReferenced"
+#define BUS_ERROR_DISK_FULL "org.freedesktop.systemd1.DiskFull"
#define BUS_ERROR_NO_SUCH_MACHINE "org.freedesktop.machine1.NoSuchMachine"
#define BUS_ERROR_NO_SUCH_IMAGE "org.freedesktop.machine1.NoSuchImage"
diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c
index 52128e7b5c..9e58ffbd88 100644
--- a/src/libsystemd/sd-bus/bus-control.c
+++ b/src/libsystemd/sd-bus/bus-control.c
@@ -264,7 +264,7 @@ static int kernel_get_list(sd_bus *bus, uint64_t flags, char ***x) {
if ((flags & KDBUS_LIST_UNIQUE) && name->id != previous_id && !(name->flags & KDBUS_HELLO_ACTIVATOR)) {
char *n;
- if (asprintf(&n, ":1.%llu", (unsigned long long) name->id) < 0) {
+ if (asprintf(&n, ":1.%llu", name->id) < 0) {
r = -ENOMEM;
goto fail;
}
@@ -711,7 +711,7 @@ int bus_get_name_creds_kdbus(
}
if (mask & SD_BUS_CREDS_UNIQUE_NAME) {
- if (asprintf(&c->unique_name, ":1.%llu", (unsigned long long) conn_info->id) < 0) {
+ if (asprintf(&c->unique_name, ":1.%llu", conn_info->id) < 0) {
r = -ENOMEM;
goto fail;
}
diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c
index c4f693dee9..349fa57f2d 100644
--- a/src/libsystemd/sd-bus/bus-creds.c
+++ b/src/libsystemd/sd-bus/bus-creds.c
@@ -30,7 +30,7 @@
#include "cgroup-util.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "hexdecoct.h"
#include "parse-util.h"
#include "process-util.h"
diff --git a/src/libsystemd/sd-bus/bus-dump.c b/src/libsystemd/sd-bus/bus-dump.c
index 21a6b20a11..f117c98c11 100644
--- a/src/libsystemd/sd-bus/bus-dump.c
+++ b/src/libsystemd/sd-bus/bus-dump.c
@@ -25,7 +25,7 @@
#include "cap-list.h"
#include "capability-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "locale-util.h"
#include "macro.h"
#include "string-util.h"
diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c
index 59398b841d..c82caeb3fc 100644
--- a/src/libsystemd/sd-bus/bus-kernel.c
+++ b/src/libsystemd/sd-bus/bus-kernel.c
@@ -42,7 +42,7 @@
#include "capability-util.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "memfd-util.h"
#include "parse-util.h"
#include "stdio-util.h"
@@ -848,8 +848,7 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
if (k->src_id == KDBUS_SRC_ID_KERNEL)
bus_message_set_sender_driver(bus, m);
else {
- xsprintf(m->sender_buffer, ":1.%llu",
- (unsigned long long)k->src_id);
+ xsprintf(m->sender_buffer, ":1.%llu", k->src_id);
m->sender = m->creds.unique_name = m->sender_buffer;
}
@@ -860,8 +859,7 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
else if (k->dst_id == KDBUS_DST_ID_NAME)
m->destination = bus->unique_name; /* fill in unique name if the well-known name is missing */
else {
- xsprintf(m->destination_buffer, ":1.%llu",
- (unsigned long long)k->dst_id);
+ xsprintf(m->destination_buffer, ":1.%llu", k->dst_id);
m->destination = m->destination_buffer;
}
@@ -1035,7 +1033,7 @@ int bus_kernel_take_fd(sd_bus *b) {
b->bloom_size = (size_t) bloom->size;
b->bloom_n_hash = (unsigned) bloom->n_hash;
- if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0) {
+ if (asprintf(&b->unique_name, ":1.%llu", hello->id) < 0) {
r = -ENOMEM;
goto fail;
}
@@ -1207,7 +1205,7 @@ int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call
return r;
}
} else {
- log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
+ log_debug("Ignoring message with unknown payload type %llu.", k->payload_type);
close_kdbus_msg(bus, k);
}
}
@@ -1268,7 +1266,7 @@ static int translate_name_change(
if (d->type == KDBUS_ITEM_NAME_ADD || (d->name_change.old_id.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR)))
old_owner[0] = 0;
else
- sprintf(old_owner, ":1.%llu", (unsigned long long) d->name_change.old_id.id);
+ sprintf(old_owner, ":1.%llu", d->name_change.old_id.id);
if (d->type == KDBUS_ITEM_NAME_REMOVE || (d->name_change.new_id.flags & (KDBUS_NAME_IN_QUEUE|KDBUS_NAME_ACTIVATOR))) {
@@ -1277,7 +1275,7 @@ static int translate_name_change(
new_owner[0] = 0;
} else
- sprintf(new_owner, ":1.%llu", (unsigned long long) d->name_change.new_id.id);
+ sprintf(new_owner, ":1.%llu", d->name_change.new_id.id);
return push_name_owner_changed(bus, d->name_change.name, old_owner, new_owner, ts);
}
@@ -1419,7 +1417,7 @@ int bus_kernel_read_message(sd_bus *bus, bool hint_priority, int64_t priority) {
r = bus_kernel_translate_message(bus, k);
close_kdbus_msg(bus, k);
} else {
- log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
+ log_debug("Ignoring message with unknown payload type %llu.", k->payload_type);
r = 0;
close_kdbus_msg(bus, k);
}
@@ -1649,7 +1647,7 @@ int bus_kernel_create_bus(const char *name, bool world, char **s) {
if (s) {
char *p;
- p = strjoin("/sys/fs/kdbus/", n->str, "/bus", NULL);
+ p = strjoin("/sys/fs/kdbus/", n->str, "/bus");
if (!p) {
safe_close(fd);
return -ENOMEM;
diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c
index cfd7753139..e6ed15eb71 100644
--- a/src/libsystemd/sd-bus/bus-socket.c
+++ b/src/libsystemd/sd-bus/bus-socket.c
@@ -30,7 +30,7 @@
#include "bus-message.h"
#include "bus-socket.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "hexdecoct.h"
#include "macro.h"
#include "missing.h"
diff --git a/src/libsystemd/sd-bus/busctl-introspect.c b/src/libsystemd/sd-bus/busctl-introspect.c
index b09509f8e1..a05794941f 100644
--- a/src/libsystemd/sd-bus/busctl-introspect.c
+++ b/src/libsystemd/sd-bus/busctl-introspect.c
@@ -143,9 +143,7 @@ static int parse_xml_annotation(Context *context, uint64_t *flags) {
case STATE_NAME:
if (t == XML_ATTRIBUTE_VALUE) {
- free(field);
- field = name;
- name = NULL;
+ free_and_replace(field, name);
state = STATE_ANNOTATION;
} else {
@@ -158,9 +156,7 @@ static int parse_xml_annotation(Context *context, uint64_t *flags) {
case STATE_VALUE:
if (t == XML_ATTRIBUTE_VALUE) {
- free(value);
- value = name;
- name = NULL;
+ free_and_replace(value, name);
state = STATE_ANNOTATION;
} else {
@@ -194,6 +190,7 @@ static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth
STATE_SIGNAL_ARG,
STATE_SIGNAL_ARG_NAME,
STATE_SIGNAL_ARG_TYPE,
+ STATE_SIGNAL_ARG_DIRECTION,
STATE_PROPERTY,
STATE_PROPERTY_NAME,
STATE_PROPERTY_TYPE,
@@ -285,7 +282,7 @@ static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth
if (endswith(prefix, "/"))
node_path = strappend(prefix, name);
else
- node_path = strjoin(prefix, "/", name, NULL);
+ node_path = strjoin(prefix, "/", name);
if (!node_path)
return log_oom();
}
@@ -350,11 +347,8 @@ static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth
case STATE_INTERFACE_NAME:
if (t == XML_ATTRIBUTE_VALUE) {
- if (n_depth == 0) {
- free(context->interface_name);
- context->interface_name = name;
- name = NULL;
- }
+ if (n_depth == 0)
+ free_and_replace(context->interface_name, name);
state = STATE_INTERFACE;
} else {
@@ -409,12 +403,8 @@ static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth
case STATE_METHOD_NAME:
if (t == XML_ATTRIBUTE_VALUE) {
-
- if (n_depth == 0) {
- free(context->member_name);
- context->member_name = name;
- name = NULL;
- }
+ if (n_depth == 0)
+ free_and_replace(context->member_name, name);
state = STATE_METHOD;
} else {
@@ -432,7 +422,7 @@ static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth
else if (streq_ptr(name, "type"))
state = STATE_METHOD_ARG_TYPE;
else if (streq_ptr(name, "direction"))
- state = STATE_METHOD_ARG_DIRECTION;
+ state = STATE_METHOD_ARG_DIRECTION;
else {
log_error("Unexpected method <arg> attribute %s.", name);
return -EBADMSG;
@@ -458,7 +448,8 @@ static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth
} else if (streq(argument_direction, "out")) {
if (!strextend(&context->member_result, argument_type, NULL))
return log_oom();
- }
+ } else
+ log_error("Unexpected method <arg> direction value '%s'.", argument_direction);
}
argument_type = mfree(argument_type);
@@ -487,9 +478,7 @@ static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth
case STATE_METHOD_ARG_TYPE:
if (t == XML_ATTRIBUTE_VALUE) {
- free(argument_type);
- argument_type = name;
- name = NULL;
+ free_and_replace(argument_type, name);
state = STATE_METHOD_ARG;
} else {
@@ -502,9 +491,7 @@ static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth
case STATE_METHOD_ARG_DIRECTION:
if (t == XML_ATTRIBUTE_VALUE) {
- free(argument_direction);
- argument_direction = name;
- name = NULL;
+ free_and_replace(argument_direction, name);
state = STATE_METHOD_ARG;
} else {
@@ -559,12 +546,8 @@ static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth
case STATE_SIGNAL_NAME:
if (t == XML_ATTRIBUTE_VALUE) {
-
- if (n_depth == 0) {
- free(context->member_name);
- context->member_name = name;
- name = NULL;
- }
+ if (n_depth == 0)
+ free_and_replace(context->member_name, name);
state = STATE_SIGNAL;
} else {
@@ -582,6 +565,8 @@ static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth
state = STATE_SIGNAL_ARG_NAME;
else if (streq_ptr(name, "type"))
state = STATE_SIGNAL_ARG_TYPE;
+ else if (streq_ptr(name, "direction"))
+ state = STATE_SIGNAL_ARG_DIRECTION;
else {
log_error("Unexpected signal <arg> attribute %s.", name);
return -EBADMSG;
@@ -599,8 +584,11 @@ static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth
(t == XML_TAG_CLOSE && streq_ptr(name, "arg"))) {
if (argument_type) {
- if (!strextend(&context->member_signature, argument_type, NULL))
- return log_oom();
+ if (!argument_direction || streq(argument_direction, "out")) {
+ if (!strextend(&context->member_signature, argument_type, NULL))
+ return log_oom();
+ } else
+ log_error("Unexpected signal <arg> direction value '%s'.", argument_direction);
argument_type = mfree(argument_type);
}
@@ -627,9 +615,7 @@ static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth
case STATE_SIGNAL_ARG_TYPE:
if (t == XML_ATTRIBUTE_VALUE) {
- free(argument_type);
- argument_type = name;
- name = NULL;
+ free_and_replace(argument_type, name);
state = STATE_SIGNAL_ARG;
} else {
@@ -639,6 +625,19 @@ static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth
break;
+ case STATE_SIGNAL_ARG_DIRECTION:
+
+ if (t == XML_ATTRIBUTE_VALUE) {
+ free_and_replace(argument_direction, name);
+
+ state = STATE_SIGNAL_ARG;
+ } else {
+ log_error("Unexpected token in signal <arg>. (4)");
+ return -EINVAL;
+ }
+
+ break;
+
case STATE_PROPERTY:
if (t == XML_ATTRIBUTE_NAME) {
@@ -688,12 +687,9 @@ static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth
case STATE_PROPERTY_NAME:
if (t == XML_ATTRIBUTE_VALUE) {
+ if (n_depth == 0)
+ free_and_replace(context->member_name, name);
- if (n_depth == 0) {
- free(context->member_name);
- context->member_name = name;
- name = NULL;
- }
state = STATE_PROPERTY;
} else {
log_error("Unexpected token in <property>. (2)");
@@ -705,12 +701,8 @@ static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth
case STATE_PROPERTY_TYPE:
if (t == XML_ATTRIBUTE_VALUE) {
-
- if (n_depth == 0) {
- free(context->member_signature);
- context->member_signature = name;
- name = NULL;
- }
+ if (n_depth == 0)
+ free_and_replace(context->member_signature, name);
state = STATE_PROPERTY;
} else {
diff --git a/src/libsystemd/sd-bus/busctl.c b/src/libsystemd/sd-bus/busctl.c
index 2c3f591053..9dd3828364 100644
--- a/src/libsystemd/sd-bus/busctl.c
+++ b/src/libsystemd/sd-bus/busctl.c
@@ -1102,7 +1102,7 @@ static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FIL
return -EINVAL;
}
- m = strjoin("sender='", *i, "'", NULL);
+ m = strjoin("sender='", *i, "'");
if (!m)
return log_oom();
@@ -1111,7 +1111,7 @@ static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FIL
return bus_log_create_error(r);
free(m);
- m = strjoin("destination='", *i, "'", NULL);
+ m = strjoin("destination='", *i, "'");
if (!m)
return log_oom();
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index d746348544..e809942278 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -1339,7 +1339,7 @@ int bus_set_address_system_remote(sd_bus *b, const char *host) {
return -ENOMEM;
}
- b->address = strjoin("unixexec:path=ssh,argv1=-xT,argv2=", e, ",argv3=systemd-stdio-bridge", c, NULL);
+ b->address = strjoin("unixexec:path=ssh,argv1=-xT,argv2=", e, ",argv3=systemd-stdio-bridge", c);
if (!b->address)
return -ENOMEM;
@@ -1387,7 +1387,7 @@ int bus_set_address_system_machine(sd_bus *b, const char *machine) {
if (!e)
return -ENOMEM;
- b->address = strjoin("x-machine-kernel:machine=", e, ";x-machine-unix:machine=", e, NULL);
+ b->address = strjoin("x-machine-kernel:machine=", e, ";x-machine-unix:machine=", e);
if (!b->address)
return -ENOMEM;
@@ -3470,7 +3470,7 @@ _public_ int sd_bus_path_encode(const char *prefix, const char *external_id, cha
if (!e)
return -ENOMEM;
- ret = strjoin(prefix, "/", e, NULL);
+ ret = strjoin(prefix, "/", e);
if (!ret)
return -ENOMEM;
diff --git a/src/libsystemd/sd-bus/test-bus-chat.c b/src/libsystemd/sd-bus/test-bus-chat.c
index fc60830059..0fc6fc90ed 100644
--- a/src/libsystemd/sd-bus/test-bus-chat.c
+++ b/src/libsystemd/sd-bus/test-bus-chat.c
@@ -30,7 +30,7 @@
#include "bus-match.h"
#include "bus-util.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "log.h"
#include "macro.h"
#include "util.h"
diff --git a/src/libsystemd/sd-bus/test-bus-creds.c b/src/libsystemd/sd-bus/test-bus-creds.c
index 6fdcfa4128..64bd76a576 100644
--- a/src/libsystemd/sd-bus/test-bus-creds.c
+++ b/src/libsystemd/sd-bus/test-bus-creds.c
@@ -31,7 +31,7 @@ int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
- if (cg_all_unified() == -ENOMEDIUM) {
+ if (cg_unified_flush() == -ENOMEDIUM) {
log_info("Skipping test: /sys/fs/cgroup/ not available");
return EXIT_TEST_SKIP;
}
diff --git a/src/libsystemd/sd-bus/test-bus-objects.c b/src/libsystemd/sd-bus/test-bus-objects.c
index f11cafd888..0b33ab7a3a 100644
--- a/src/libsystemd/sd-bus/test-bus-objects.c
+++ b/src/libsystemd/sd-bus/test-bus-objects.c
@@ -49,7 +49,7 @@ static int something_handler(sd_bus_message *m, void *userdata, sd_bus_error *er
r = sd_bus_message_read(m, "s", &s);
assert_se(r > 0);
- n = strjoin("<<<", s, ">>>", NULL);
+ n = strjoin("<<<", s, ">>>");
assert_se(n);
free(c->something);
@@ -525,8 +525,6 @@ int main(int argc, char *argv[]) {
void *p;
int r, q;
- zero(c);
-
c.automatic_integer_property = 4711;
assert_se(c.automatic_string_property = strdup("dudeldu"));
diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c
index b20a7ebb4c..a9a32dd5a2 100644
--- a/src/libsystemd/sd-daemon/sd-daemon.c
+++ b/src/libsystemd/sd-daemon/sd-daemon.c
@@ -322,6 +322,64 @@ _public_ int sd_is_socket_inet(int fd, int family, int type, int listening, uint
return 1;
}
+_public_ int sd_is_socket_sockaddr(int fd, int type, const struct sockaddr* addr, unsigned addr_len, int listening) {
+ union sockaddr_union sockaddr = {};
+ socklen_t l = sizeof(sockaddr);
+ int r;
+
+ assert_return(fd >= 0, -EBADF);
+ assert_return(addr, -EINVAL);
+ assert_return(addr_len >= sizeof(sa_family_t), -ENOBUFS);
+ assert_return(IN_SET(addr->sa_family, AF_INET, AF_INET6), -EPFNOSUPPORT);
+
+ r = sd_is_socket_internal(fd, type, listening);
+ if (r <= 0)
+ return r;
+
+ if (getsockname(fd, &sockaddr.sa, &l) < 0)
+ return -errno;
+
+ if (l < sizeof(sa_family_t))
+ return -EINVAL;
+
+ if (sockaddr.sa.sa_family != addr->sa_family)
+ return 0;
+
+ if (sockaddr.sa.sa_family == AF_INET) {
+ const struct sockaddr_in *in = (const struct sockaddr_in *) addr;
+
+ if (l < sizeof(struct sockaddr_in) || addr_len < sizeof(struct sockaddr_in))
+ return -EINVAL;
+
+ if (in->sin_port != 0 &&
+ sockaddr.in.sin_port != in->sin_port)
+ return false;
+
+ return sockaddr.in.sin_addr.s_addr == in->sin_addr.s_addr;
+
+ } else {
+ const struct sockaddr_in6 *in = (const struct sockaddr_in6 *) addr;
+
+ if (l < sizeof(struct sockaddr_in6) || addr_len < sizeof(struct sockaddr_in6))
+ return -EINVAL;
+
+ if (in->sin6_port != 0 &&
+ sockaddr.in6.sin6_port != in->sin6_port)
+ return false;
+
+ if (in->sin6_flowinfo != 0 &&
+ sockaddr.in6.sin6_flowinfo != in->sin6_flowinfo)
+ return false;
+
+ if (in->sin6_scope_id != 0 &&
+ sockaddr.in6.sin6_scope_id != in->sin6_scope_id)
+ return false;
+
+ return memcmp(sockaddr.in6.sin6_addr.s6_addr, in->sin6_addr.s6_addr,
+ sizeof(in->sin6_addr.s6_addr)) == 0;
+ }
+}
+
_public_ int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) {
union sockaddr_union sockaddr = {};
socklen_t l = sizeof(sockaddr);
diff --git a/src/libsystemd/sd-device/device-enumerator.c b/src/libsystemd/sd-device/device-enumerator.c
index 62d03ae00d..86f8935a14 100644
--- a/src/libsystemd/sd-device/device-enumerator.c
+++ b/src/libsystemd/sd-device/device-enumerator.c
@@ -773,7 +773,7 @@ static int parent_crawl_children(sd_device_enumerator *enumerator, const char *p
if (dent->d_type != DT_DIR)
continue;
- child = strjoin(path, "/", dent->d_name, NULL);
+ child = strjoin(path, "/", dent->d_name);
if (!child)
return -ENOMEM;
diff --git a/src/libsystemd/sd-device/device-internal.h b/src/libsystemd/sd-device/device-internal.h
index 9fad388953..f4783deef8 100644
--- a/src/libsystemd/sd-device/device-internal.h
+++ b/src/libsystemd/sd-device/device-internal.h
@@ -34,7 +34,7 @@ struct sd_device {
uint64_t properties_generation; /* changes whenever the properties are changed */
uint64_t properties_iterator_generation; /* generation when iteration was started */
- /* the subset of the properties that should be written to the db*/
+ /* the subset of the properties that should be written to the db */
OrderedHashmap *properties_db;
Hashmap *sysattr_values; /* cached sysattr values */
diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c
index 01d34b9a45..81d8d61ba9 100644
--- a/src/libsystemd/sd-device/sd-device.c
+++ b/src/libsystemd/sd-device/sd-device.c
@@ -28,6 +28,7 @@
#include "device-internal.h"
#include "device-private.h"
#include "device-util.h"
+#include "dirent-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
@@ -164,7 +165,7 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) {
}
if (verify) {
- r = readlink_and_canonicalize(_syspath, &syspath);
+ r = readlink_and_canonicalize(_syspath, NULL, &syspath);
if (r == -ENOENT)
/* the device does not exist (any more?) */
return -ENODEV;
@@ -1627,7 +1628,7 @@ static int device_sysattrs_read_all(sd_device *device) {
if (r < 0)
return r;
- for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
+ FOREACH_DIRENT_ALL(dent, dir, return -errno) {
char *path;
struct stat statbuf;
@@ -1858,8 +1859,7 @@ _public_ int sd_device_set_sysattr_value(sd_device *device, const char *sysattr,
_cleanup_free_ char *value = NULL;
const char *syspath;
char *path;
- struct stat statbuf;
- size_t value_len = 0;
+ size_t len = 0;
ssize_t size;
int r;
@@ -1877,8 +1877,14 @@ _public_ int sd_device_set_sysattr_value(sd_device *device, const char *sysattr,
return r;
path = strjoina(syspath, "/", sysattr);
- r = lstat(path, &statbuf);
- if (r < 0) {
+
+ fd = open(path, O_WRONLY | O_CLOEXEC | O_NOFOLLOW);
+ if (fd < 0) {
+ if (errno == ELOOP)
+ return -EINVAL;
+ if (errno == EISDIR)
+ return -EISDIR;
+
value = strdup("");
if (!value)
return -ENOMEM;
@@ -1886,50 +1892,35 @@ _public_ int sd_device_set_sysattr_value(sd_device *device, const char *sysattr,
r = device_add_sysattr_value(device, sysattr, value);
if (r < 0)
return r;
+ value = NULL;
return -ENXIO;
}
- if (S_ISLNK(statbuf.st_mode))
- return -EINVAL;
-
- /* skip directories */
- if (S_ISDIR(statbuf.st_mode))
- return -EISDIR;
-
- /* skip non-readable files */
- if ((statbuf.st_mode & S_IRUSR) == 0)
- return -EACCES;
-
- value_len = strlen(_value);
+ len = strlen(_value);
/* drop trailing newlines */
- while (value_len > 0 && _value[value_len - 1] == '\n')
- _value[--value_len] = '\0';
+ while (len > 0 && _value[len - 1] == '\n')
+ len --;
/* value length is limited to 4k */
- if (value_len > 4096)
+ if (len > 4096)
return -EINVAL;
- fd = open(path, O_WRONLY | O_CLOEXEC);
- if (fd < 0)
- return -errno;
-
- value = strdup(_value);
+ value = strndup(_value, len);
if (!value)
return -ENOMEM;
- size = write(fd, value, value_len);
+ size = write(fd, value, len);
if (size < 0)
return -errno;
- if ((size_t)size != value_len)
+ if ((size_t)size != len)
return -EIO;
r = device_add_sysattr_value(device, sysattr, value);
if (r < 0)
return r;
-
value = NULL;
return 0;
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
index 9857f8b1fc..b4686d0065 100644
--- a/src/libsystemd/sd-event/sd-event.c
+++ b/src/libsystemd/sd-event/sd-event.c
@@ -730,7 +730,6 @@ static void event_unmask_signal_data(sd_event *e, struct signal_data *d, int sig
/* If all the mask is all-zero we can get rid of the structure */
hashmap_remove(e->signal_data, &d->priority);
- assert(!d->current);
safe_close(d->fd);
free(d);
return;
@@ -1539,7 +1538,8 @@ _public_ int sd_event_source_get_priority(sd_event_source *s, int64_t *priority)
assert_return(s, -EINVAL);
assert_return(!event_pid_changed(s->event), -ECHILD);
- return s->priority;
+ *priority = s->priority;
+ return 0;
}
_public_ int sd_event_source_set_priority(sd_event_source *s, int64_t priority) {
@@ -2225,11 +2225,16 @@ static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) {
}
static int source_dispatch(sd_event_source *s) {
+ EventSourceType saved_type;
int r = 0;
assert(s);
assert(s->pending || s->type == SOURCE_EXIT);
+ /* Save the event source type, here, so that we still know it after the event callback which might invalidate
+ * the event. */
+ saved_type = s->type;
+
if (s->type != SOURCE_DEFER && s->type != SOURCE_EXIT) {
r = source_set_pending(s, false);
if (r < 0)
@@ -2317,7 +2322,7 @@ static int source_dispatch(sd_event_source *s) {
if (r < 0)
log_debug_errno(r, "Event source %s (type %s) returned error, disabling: %m",
- strna(s->description), event_source_type_to_string(s->type));
+ strna(s->description), event_source_type_to_string(saved_type));
if (s->n_ref == 0)
source_free(s);
diff --git a/src/libsystemd/sd-event/test-event.c b/src/libsystemd/sd-event/test-event.c
index 289114490c..c0e5e06a18 100644
--- a/src/libsystemd/sd-event/test-event.c
+++ b/src/libsystemd/sd-event/test-event.c
@@ -172,6 +172,7 @@ static void test_basic(void) {
static const char ch = 'x';
int a[2] = { -1, -1 }, b[2] = { -1, -1}, d[2] = { -1, -1}, k[2] = { -1, -1 };
uint64_t event_now;
+ int64_t priority;
assert_se(pipe(a) >= 0);
assert_se(pipe(b) >= 0);
@@ -209,6 +210,8 @@ static void test_basic(void) {
assert_se(sd_event_add_exit(e, &q, exit_handler, INT_TO_PTR('g')) >= 0);
assert_se(sd_event_source_set_priority(x, 99) >= 0);
+ assert_se(sd_event_source_get_priority(x, &priority) >= 0);
+ assert_se(priority == 99);
assert_se(sd_event_source_set_enabled(y, SD_EVENT_ONESHOT) >= 0);
assert_se(sd_event_source_set_prepare(x, prepare_handler) >= 0);
assert_se(sd_event_source_set_priority(z, 50) >= 0);
diff --git a/src/libsystemd/sd-hwdb/hwdb-internal.h b/src/libsystemd/sd-hwdb/hwdb-internal.h
index 4fff94ec76..2f4934ae8b 100644
--- a/src/libsystemd/sd-hwdb/hwdb-internal.h
+++ b/src/libsystemd/sd-hwdb/hwdb-internal.h
@@ -76,5 +76,7 @@ struct trie_value_entry2_f {
le64_t key_off;
le64_t value_off;
le64_t filename_off;
- le64_t line_number;
+ le32_t line_number;
+ le16_t file_priority;
+ le16_t padding;
} _packed_;
diff --git a/src/libsystemd/sd-hwdb/sd-hwdb.c b/src/libsystemd/sd-hwdb/sd-hwdb.c
index 488e101ea8..c155c70162 100644
--- a/src/libsystemd/sd-hwdb/sd-hwdb.c
+++ b/src/libsystemd/sd-hwdb/sd-hwdb.c
@@ -48,8 +48,6 @@ struct sd_hwdb {
const char *map;
};
- char *modalias;
-
OrderedHashmap *properties;
Iterator properties_iterator;
bool properties_modified;
@@ -164,10 +162,38 @@ static int hwdb_add_property(sd_hwdb *hwdb, const struct trie_value_entry_f *ent
entry2 = (const struct trie_value_entry2_f *)entry;
old = ordered_hashmap_get(hwdb->properties, key);
if (old) {
- /* on duplicates, we order by filename and line-number */
- r = strcmp(trie_string(hwdb, entry2->filename_off), trie_string(hwdb, old->filename_off));
- if (r < 0 ||
- (r == 0 && entry2->line_number < old->line_number))
+ /* On duplicates, we order by filename priority and line-number.
+ *
+ *
+ * v2 of the format had 64 bits for the line number.
+ * v3 reuses top 32 bits of line_number to store the priority.
+ * We check the top bits — if they are zero we have v2 format.
+ * This means that v2 clients will print wrong line numbers with
+ * v3 data.
+ *
+ * For v3 data: we compare the priority (of the source file)
+ * and the line number.
+ *
+ * For v2 data: we rely on the fact that the filenames in the hwdb
+ * are added in the order of priority (higher later), because they
+ * are *processed* in the order of priority. So we compare the
+ * indices to determine which file had higher priority. Comparing
+ * the strings alphabetically would be useless, because those are
+ * full paths, and e.g. /usr/lib would sort after /etc, even
+ * though it has lower priority. This is not reliable because of
+ * suffix compression, but should work for the most common case of
+ * /usr/lib/udev/hwbd.d and /etc/udev/hwdb.d, and is better than
+ * not doing the comparison at all.
+ */
+ bool lower;
+
+ if (entry2->file_priority == 0)
+ lower = entry2->filename_off < old->filename_off ||
+ (entry2->filename_off == old->filename_off && entry2->line_number < old->line_number);
+ else
+ lower = entry2->file_priority < old->file_priority ||
+ (entry2->file_priority == old->file_priority && entry2->line_number < old->line_number);
+ if (lower)
return 0;
}
}
@@ -234,7 +260,7 @@ static int trie_search_f(sd_hwdb *hwdb, const char *search) {
uint8_t c;
for (; (c = trie_string(hwdb, node->prefix_off)[p]); p++) {
- if (c == '*' || c == '?' || c == '[')
+ if (IN_SET(c, '*', '?', '['))
return trie_fnmatch_f(hwdb, node, p, &buf, search + i + p);
if (c != search[i + p])
return 0;
@@ -321,7 +347,7 @@ _public_ int sd_hwdb_new(sd_hwdb **ret) {
}
if (!hwdb->f) {
- log_debug("hwdb.bin does not exist, please run udevadm hwdb --update");
+ log_debug("hwdb.bin does not exist, please run systemd-hwdb update");
return -ENOENT;
}
@@ -365,7 +391,6 @@ _public_ sd_hwdb *sd_hwdb_unref(sd_hwdb *hwdb) {
if (hwdb->map)
munmap((void *)hwdb->map, hwdb->st.st_size);
safe_fclose(hwdb->f);
- free(hwdb->modalias);
ordered_hashmap_free(hwdb->properties);
free(hwdb);
}
@@ -399,32 +424,13 @@ bool hwdb_validate(sd_hwdb *hwdb) {
}
static int properties_prepare(sd_hwdb *hwdb, const char *modalias) {
- _cleanup_free_ char *mod = NULL;
- int r;
-
assert(hwdb);
assert(modalias);
- if (streq_ptr(modalias, hwdb->modalias))
- return 0;
-
- mod = strdup(modalias);
- if (!mod)
- return -ENOMEM;
-
ordered_hashmap_clear(hwdb->properties);
-
hwdb->properties_modified = true;
- r = trie_search_f(hwdb, modalias);
- if (r < 0)
- return r;
-
- free(hwdb->modalias);
- hwdb->modalias = mod;
- mod = NULL;
-
- return 0;
+ return trie_search_f(hwdb, modalias);
}
_public_ int sd_hwdb_get(sd_hwdb *hwdb, const char *modalias, const char *key, const char **_value) {
diff --git a/src/libsystemd/sd-id128/id128-util.c b/src/libsystemd/sd-id128/id128-util.c
index 337eae24b4..e6d45c18e3 100644
--- a/src/libsystemd/sd-id128/id128-util.c
+++ b/src/libsystemd/sd-id128/id128-util.c
@@ -186,7 +186,7 @@ int id128_write_fd(int fd, Id128Format f, sd_id128_t id, bool do_sync) {
int id128_write(const char *p, Id128Format f, sd_id128_t id, bool do_sync) {
_cleanup_close_ int fd = -1;
- fd = open(p, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0444);
+ fd = open(p, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_TRUNC, 0444);
if (fd < 0)
return -errno;
diff --git a/src/libsystemd/sd-id128/sd-id128.c b/src/libsystemd/sd-id128/sd-id128.c
index d4450c70a0..0d673ba655 100644
--- a/src/libsystemd/sd-id128/sd-id128.c
+++ b/src/libsystemd/sd-id128/sd-id128.c
@@ -27,6 +27,7 @@
#include "hexdecoct.h"
#include "id128-util.h"
#include "io-util.h"
+#include "khash.h"
#include "macro.h"
#include "random-util.h"
#include "util.h"
@@ -181,3 +182,34 @@ _public_ int sd_id128_randomize(sd_id128_t *ret) {
*ret = make_v4_uuid(t);
return 0;
}
+
+_public_ int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *ret) {
+ _cleanup_(khash_unrefp) khash *h = NULL;
+ sd_id128_t m, result;
+ const void *p;
+ int r;
+
+ assert_return(ret, -EINVAL);
+
+ r = sd_id128_get_machine(&m);
+ if (r < 0)
+ return r;
+
+ r = khash_new_with_key(&h, "hmac(sha256)", &m, sizeof(m));
+ if (r < 0)
+ return r;
+
+ r = khash_put(h, &app_id, sizeof(app_id));
+ if (r < 0)
+ return r;
+
+ r = khash_digest_data(h, &p);
+ if (r < 0)
+ return r;
+
+ /* We chop off the trailing 16 bytes */
+ memcpy(&result, p, MIN(khash_get_size(h), sizeof(result)));
+
+ *ret = make_v4_uuid(result);
+ return 0;
+}
diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c
index 3fcefada3f..cdbdc37856 100644
--- a/src/libsystemd/sd-login/sd-login.c
+++ b/src/libsystemd/sd-login/sd-login.c
@@ -31,7 +31,7 @@
#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "fs-util.h"
#include "hostname-util.h"
#include "io-util.h"
@@ -687,7 +687,7 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui
r = parse_env_file(p, NEWLINE,
"SESSIONS", &s,
- "ACTIVE_SESSIONS", &t,
+ "UIDS", &t,
NULL);
if (r == -ENOENT)
return -ENXIO;
@@ -793,6 +793,7 @@ _public_ int sd_get_sessions(char ***sessions) {
_public_ int sd_get_uids(uid_t **users) {
_cleanup_closedir_ DIR *d;
+ struct dirent *de;
int r = 0;
unsigned n = 0;
_cleanup_free_ uid_t *l = NULL;
@@ -801,19 +802,10 @@ _public_ int sd_get_uids(uid_t **users) {
if (!d)
return -errno;
- for (;;) {
- struct dirent *de;
+ FOREACH_DIRENT_ALL(de, d, return -errno) {
int k;
uid_t uid;
- errno = 0;
- de = readdir(d);
- if (!de && errno > 0)
- return -errno;
-
- if (!de)
- break;
-
dirent_ensure_type(d, de);
if (!dirent_is_file(de))
diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c
index c1fd7dd33e..9de33d85db 100644
--- a/src/libsystemd/sd-login/test-login.c
+++ b/src/libsystemd/sd-login/test-login.c
@@ -24,7 +24,7 @@
#include "alloc-util.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "string-util.h"
#include "strv.h"
#include "util.h"
diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c
index df3b3c922e..654a22fe3b 100644
--- a/src/libsystemd/sd-netlink/netlink-message.c
+++ b/src/libsystemd/sd-netlink/netlink-message.c
@@ -24,7 +24,7 @@
#include "sd-netlink.h"
#include "alloc-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "missing.h"
#include "netlink-internal.h"
#include "netlink-types.h"
diff --git a/src/libsystemd/sd-netlink/netlink-socket.c b/src/libsystemd/sd-netlink/netlink-socket.c
index c165fa3359..129bfd2d80 100644
--- a/src/libsystemd/sd-netlink/netlink-socket.c
+++ b/src/libsystemd/sd-netlink/netlink-socket.c
@@ -24,7 +24,7 @@
#include "sd-netlink.h"
#include "alloc-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "missing.h"
#include "netlink-internal.h"
#include "netlink-types.h"
@@ -281,7 +281,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool
else if (errno == EAGAIN)
log_debug("rtnl: no data in socket");
- return (errno == EAGAIN || errno == EINTR) ? 0 : -errno;
+ return IN_SET(errno, EAGAIN, EINTR) ? 0 : -errno;
}
if (sender.nl.nl_pid != 0) {
@@ -292,7 +292,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool
/* drop the message */
r = recvmsg(fd, &msg, 0);
if (r < 0)
- return (errno == EAGAIN || errno == EINTR) ? 0 : -errno;
+ return IN_SET(errno, EAGAIN, EINTR) ? 0 : -errno;
}
return 0;
diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c
index 1c10dd55a7..ff0e99558e 100644
--- a/src/libsystemd/sd-netlink/netlink-types.c
+++ b/src/libsystemd/sd-netlink/netlink-types.c
@@ -149,7 +149,7 @@ static const NLType rtnl_link_info_data_vxlan_types[] = {
[IFLA_VXLAN_ID] = { .type = NETLINK_TYPE_U32 },
[IFLA_VXLAN_GROUP] = { .type = NETLINK_TYPE_IN_ADDR },
[IFLA_VXLAN_LINK] = { .type = NETLINK_TYPE_U32 },
- [IFLA_VXLAN_LOCAL] = { .type = NETLINK_TYPE_U32},
+ [IFLA_VXLAN_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR },
[IFLA_VXLAN_TTL] = { .type = NETLINK_TYPE_U8 },
[IFLA_VXLAN_TOS] = { .type = NETLINK_TYPE_U8 },
[IFLA_VXLAN_LEARNING] = { .type = NETLINK_TYPE_U8 },
@@ -500,6 +500,28 @@ static const NLTypeSystem rtnl_address_type_system = {
.types = rtnl_address_types,
};
+/* RTM_METRICS --- array of struct rtattr with types of RTAX_* */
+
+static const NLType rtnl_route_metrics_types[] = {
+ [RTAX_MTU] = { .type = NETLINK_TYPE_U32 },
+ [RTAX_WINDOW] = { .type = NETLINK_TYPE_U32 },
+ [RTAX_RTT] = { .type = NETLINK_TYPE_U32 },
+ [RTAX_RTTVAR] = { .type = NETLINK_TYPE_U32 },
+ [RTAX_SSTHRESH] = { .type = NETLINK_TYPE_U32 },
+ [RTAX_CWND] = { .type = NETLINK_TYPE_U32 },
+ [RTAX_ADVMSS] = { .type = NETLINK_TYPE_U32 },
+ [RTAX_REORDERING] = { .type = NETLINK_TYPE_U32 },
+ [RTAX_HOPLIMIT] = { .type = NETLINK_TYPE_U32 },
+ [RTAX_INITCWND] = { .type = NETLINK_TYPE_U32 },
+ [RTAX_FEATURES] = { .type = NETLINK_TYPE_U32 },
+ [RTAX_RTO_MIN] = { .type = NETLINK_TYPE_U32 },
+};
+
+static const NLTypeSystem rtnl_route_metrics_type_system = {
+ .count = ELEMENTSOF(rtnl_route_metrics_types),
+ .types = rtnl_route_metrics_types,
+};
+
static const NLType rtnl_route_types[] = {
[RTA_DST] = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */
[RTA_SRC] = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */
@@ -508,9 +530,8 @@ static const NLType rtnl_route_types[] = {
[RTA_GATEWAY] = { .type = NETLINK_TYPE_IN_ADDR },
[RTA_PRIORITY] = { .type = NETLINK_TYPE_U32 },
[RTA_PREFSRC] = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */
-/*
- [RTA_METRICS] = { .type = NETLINK_TYPE_NESTED },
- [RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) },
+ [RTA_METRICS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_metrics_type_system},
+/* [RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) },
*/
[RTA_FLOW] = { .type = NETLINK_TYPE_U32 }, /* 6? */
/*
diff --git a/src/libsystemd/sd-netlink/rtnl-message.c b/src/libsystemd/sd-netlink/rtnl-message.c
index 09240c7b2a..b543b5f20c 100644
--- a/src/libsystemd/sd-netlink/rtnl-message.c
+++ b/src/libsystemd/sd-netlink/rtnl-message.c
@@ -23,7 +23,7 @@
#include "sd-netlink.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "missing.h"
#include "netlink-internal.h"
#include "netlink-types.h"
diff --git a/src/libsystemd/sd-netlink/sd-netlink.c b/src/libsystemd/sd-netlink/sd-netlink.c
index 43114eb825..68435564de 100644
--- a/src/libsystemd/sd-netlink/sd-netlink.c
+++ b/src/libsystemd/sd-netlink/sd-netlink.c
@@ -276,6 +276,10 @@ static int dispatch_rqueue(sd_netlink *rtnl, sd_netlink_message **message) {
if (rtnl->rqueue_size <= 0) {
/* Try to read a new message */
r = socket_read_message(rtnl);
+ if (r == -ENOBUFS) { /* FIXME: ignore buffer overruns for now */
+ log_debug_errno(r, "Got ENOBUFS from netlink socket, ignoring.");
+ return 1;
+ }
if (r <= 0)
return r;
}
diff --git a/src/libsystemd/sd-network/sd-network.c b/src/libsystemd/sd-network/sd-network.c
index f8e18f23fd..8b4af5a2c3 100644
--- a/src/libsystemd/sd-network/sd-network.c
+++ b/src/libsystemd/sd-network/sd-network.c
@@ -224,13 +224,8 @@ static int network_link_get_ifindexes(int ifindex, const char *key, int **ret) {
return -ENODATA;
if (r < 0)
return r;
- if (isempty(s)) {
- *ret = NULL;
- return 0;
- }
- x = s;
- for (;;) {
+ for (x = s;;) {
_cleanup_free_ char *word = NULL;
r = extract_first_word(&x, &word, NULL, 0);
@@ -243,15 +238,14 @@ static int network_link_get_ifindexes(int ifindex, const char *key, int **ret) {
if (r < 0)
return r;
- if (!GREEDY_REALLOC(ifis, allocated, c + 1))
+ if (!GREEDY_REALLOC(ifis, allocated, c + 2))
return -ENOMEM;
ifis[c++] = ifindex;
}
- if (!GREEDY_REALLOC(ifis, allocated, c + 1))
- return -ENOMEM;
- ifis[c] = 0; /* Let's add a 0 ifindex to the end, to be nice*/
+ if (ifis)
+ ifis[c] = 0; /* Let's add a 0 ifindex to the end, to be nice */
*ret = ifis;
ifis = NULL;
diff --git a/src/libsystemd/sd-path/sd-path.c b/src/libsystemd/sd-path/sd-path.c
index b7aec1f20a..752c1ba56b 100644
--- a/src/libsystemd/sd-path/sd-path.c
+++ b/src/libsystemd/sd-path/sd-path.c
@@ -77,7 +77,7 @@ static int from_home_dir(const char *envname, const char *suffix, char **buffer,
if (endswith(h, "/"))
cc = strappend(h, suffix);
else
- cc = strjoin(h, "/", suffix, NULL);
+ cc = strjoin(h, "/", suffix);
if (!cc)
return -ENOMEM;
@@ -387,7 +387,7 @@ _public_ int sd_path_home(uint64_t type, const char *suffix, char **path) {
if (endswith(ret, "/"))
cc = strappend(ret, suffix);
else
- cc = strjoin(ret, "/", suffix, NULL);
+ cc = strjoin(ret, "/", suffix);
free(buffer);
@@ -455,7 +455,7 @@ static int search_from_environment(
if (endswith(e, "/"))
h = strappend(e, home_suffix);
else
- h = strjoin(e, "/", home_suffix, NULL);
+ h = strjoin(e, "/", home_suffix);
if (!h) {
strv_free(l);
@@ -621,7 +621,7 @@ _public_ int sd_path_search(uint64_t type, const char *suffix, char ***paths) {
if (endswith(*i, "/"))
*j = strappend(*i, suffix);
else
- *j = strjoin(*i, "/", suffix, NULL);
+ *j = strjoin(*i, "/", suffix);
if (!*j) {
strv_free(l);
diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c
index a1f2b33ad5..a40329d732 100644
--- a/src/libudev/libudev-monitor.c
+++ b/src/libudev/libudev-monitor.c
@@ -33,7 +33,7 @@
#include "alloc-util.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "libudev-private.h"
#include "missing.h"
#include "mount-util.h"
diff --git a/src/libudev/libudev-util.c b/src/libudev/libudev-util.c
index 574cfeac85..1d73d8f090 100644
--- a/src/libudev/libudev-util.c
+++ b/src/libudev/libudev-util.c
@@ -161,6 +161,20 @@ void util_remove_trailing_chars(char *path, char c)
path[--len] = '\0';
}
+/*
+ * Copy from 'str' to 'to', while removing all leading and trailing whitespace,
+ * and replacing each run of consecutive whitespace with a single underscore.
+ * The chars from 'str' are copied up to the \0 at the end of the string, or
+ * at most 'len' chars. This appends \0 to 'to', at the end of the copied
+ * characters.
+ *
+ * If 'len' chars are copied into 'to', the final \0 is placed at len+1
+ * (i.e. 'to[len] = \0'), so the 'to' buffer must have at least len+1
+ * chars available.
+ *
+ * Note this may be called with 'str' == 'to', i.e. to replace whitespace
+ * in-place in a buffer. This function can handle that situation.
+ */
int util_replace_whitespace(const char *str, char *to, size_t len)
{
size_t i, j;
@@ -186,7 +200,7 @@ int util_replace_whitespace(const char *str, char *to, size_t len)
to[j++] = str[i++];
}
to[j] = '\0';
- return 0;
+ return j;
}
/* allow chars in whitelist, plain ascii, hex-escaping and valid utf8 */
diff --git a/src/libudev/libudev.c b/src/libudev/libudev.c
index 63fb05547d..d8e13288b0 100644
--- a/src/libudev/libudev.c
+++ b/src/libudev/libudev.c
@@ -97,8 +97,10 @@ _public_ struct udev *udev_new(void) {
_cleanup_fclose_ FILE *f = NULL;
udev = new0(struct udev, 1);
- if (udev == NULL)
+ if (!udev) {
+ errno = -ENOMEM;
return NULL;
+ }
udev->refcount = 1;
f = fopen("/etc/udev/udev.conf", "re");
@@ -156,7 +158,7 @@ _public_ struct udev *udev_new(void) {
/* unquote */
if (val[0] == '"' || val[0] == '\'') {
- if (val[len-1] != val[0]) {
+ if (len == 1 || val[len-1] != val[0]) {
log_debug("/etc/udev/udev.conf:%u: inconsistent quoting, skipping line.", line_nr);
continue;
}
diff --git a/src/libudev/libudev.pc.in b/src/libudev/libudev.pc.in
index a0f3f524e0..770c92209e 100644
--- a/src/libudev/libudev.pc.in
+++ b/src/libudev/libudev.pc.in
@@ -7,7 +7,7 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
-libdir=@libdir@
+libdir=@rootlibdir@
includedir=@includedir@
Name: libudev
diff --git a/src/locale/keymap-util.c b/src/locale/keymap-util.c
index a6bcd1ad54..da72bee4a9 100644
--- a/src/locale/keymap-util.c
+++ b/src/locale/keymap-util.c
@@ -519,7 +519,7 @@ int find_converted_keymap(const char *x11_layout, const char *x11_variant, char
_cleanup_free_ char *n;
if (x11_variant)
- n = strjoin(x11_layout, "-", x11_variant, NULL);
+ n = strjoin(x11_layout, "-", x11_variant);
else
n = strdup(x11_layout);
if (!n)
@@ -529,8 +529,8 @@ int find_converted_keymap(const char *x11_layout, const char *x11_variant, char
_cleanup_free_ char *p = NULL, *pz = NULL;
bool uncompressed;
- p = strjoin(dir, "xkb/", n, ".map", NULL);
- pz = strjoin(dir, "xkb/", n, ".map.gz", NULL);
+ p = strjoin(dir, "xkb/", n, ".map");
+ pz = strjoin(dir, "xkb/", n, ".map.gz");
if (!p || !pz)
return -ENOMEM;
diff --git a/src/locale/localectl.c b/src/locale/localectl.c
index 81afb4909f..0bd18a5c0b 100644
--- a/src/locale/localectl.c
+++ b/src/locale/localectl.c
@@ -166,6 +166,8 @@ static int show_status(sd_bus *bus, char **args, unsigned n) {
{ "Locale", "as", NULL, offsetof(StatusInfo, locale) },
{}
};
+
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
int r;
assert(bus);
@@ -174,9 +176,10 @@ static int show_status(sd_bus *bus, char **args, unsigned n) {
"org.freedesktop.locale1",
"/org/freedesktop/locale1",
map,
+ &error,
&info);
if (r < 0)
- return log_error_errno(r, "Could not get properties: %m");
+ return log_error_errno(r, "Could not get properties: %s", bus_error_message(&error, r));
print_overridden_variables();
print_status_info(&info);
diff --git a/src/login/inhibit.c b/src/login/inhibit.c
index f2c37a8623..7e5a093698 100644
--- a/src/login/inhibit.c
+++ b/src/login/inhibit.c
@@ -29,7 +29,7 @@
#include "bus-error.h"
#include "bus-util.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "process-util.h"
#include "signal-util.h"
#include "strv.h"
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index 4c618ed19e..68cac4cb08 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -240,7 +240,6 @@ static int list_seats(int argc, char *argv[], void *userdata) {
sd_bus *bus = userdata;
unsigned k = 0;
int r;
-
assert(bus);
assert(argv);
@@ -280,35 +279,17 @@ static int list_seats(int argc, char *argv[], void *userdata) {
}
static int show_unit_cgroup(sd_bus *bus, const char *interface, const char *unit, pid_t leader) {
+ _cleanup_free_ char *cgroup = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- _cleanup_free_ char *path = NULL;
- const char *cgroup;
unsigned c;
int r;
assert(bus);
assert(unit);
- path = unit_dbus_path_from_name(unit);
- if (!path)
- return log_oom();
-
- r = sd_bus_get_property(
- bus,
- "org.freedesktop.systemd1",
- path,
- interface,
- "ControlGroup",
- &error,
- &reply,
- "s");
- if (r < 0)
- return log_error_errno(r, "Failed to query ControlGroup: %s", bus_error_message(&error, r));
-
- r = sd_bus_message_read(reply, "s", &cgroup);
+ r = show_cgroup_get_unit_path_and_warn(bus, unit, &cgroup);
if (r < 0)
- return bus_log_parse_error(r);
+ return r;
if (isempty(cgroup))
return 0;
@@ -501,14 +482,15 @@ static int print_session_status_info(sd_bus *bus, const char *path, bool *new_li
{}
};
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
char since2[FORMAT_TIMESTAMP_MAX], *s2;
_cleanup_(session_status_info_clear) SessionStatusInfo i = {};
int r;
- r = bus_map_all_properties(bus, "org.freedesktop.login1", path, map, &i);
+ r = bus_map_all_properties(bus, "org.freedesktop.login1", path, map, &error, &i);
if (r < 0)
- return log_error_errno(r, "Could not get properties: %m");
+ return log_error_errno(r, "Could not get properties: %s", bus_error_message(&error, r));
if (*new_line)
printf("\n");
@@ -630,14 +612,15 @@ static int print_user_status_info(sd_bus *bus, const char *path, bool *new_line)
{}
};
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
char since2[FORMAT_TIMESTAMP_MAX], *s2;
_cleanup_(user_status_info_clear) UserStatusInfo i = {};
int r;
- r = bus_map_all_properties(bus, "org.freedesktop.login1", path, map, &i);
+ r = bus_map_all_properties(bus, "org.freedesktop.login1", path, map, &error, &i);
if (r < 0)
- return log_error_errno(r, "Could not get properties: %m");
+ return log_error_errno(r, "Could not get properties: %s", bus_error_message(&error, r));
if (*new_line)
printf("\n");
@@ -704,12 +687,13 @@ static int print_seat_status_info(sd_bus *bus, const char *path, bool *new_line)
{}
};
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(seat_status_info_clear) SeatStatusInfo i = {};
int r;
- r = bus_map_all_properties(bus, "org.freedesktop.login1", path, map, &i);
+ r = bus_map_all_properties(bus, "org.freedesktop.login1", path, map, &error, &i);
if (r < 0)
- return log_error_errno(r, "Could not get properties: %m");
+ return log_error_errno(r, "Could not get properties: %s", bus_error_message(&error, r));
if (*new_line)
printf("\n");
@@ -945,7 +929,7 @@ static int show_session(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_free_ char *path = NULL;
- r = get_session_path(bus, argv[1], &error, &path);
+ r = get_session_path(bus, argv[i], &error, &path);
if (r < 0) {
log_error("Failed to get session path: %s", bus_error_message(&error, r));
return r;
diff --git a/src/login/logind-acl.c b/src/login/logind-acl.c
index 0cef88a82d..1b69f4b9ca 100644
--- a/src/login/logind-acl.c
+++ b/src/login/logind-acl.c
@@ -25,7 +25,7 @@
#include "dirent-util.h"
#include "escape.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "logind-acl.h"
#include "set.h"
#include "string-util.h"
diff --git a/src/login/logind-action.c b/src/login/logind-action.c
index a950409254..91225a5363 100644
--- a/src/login/logind-action.c
+++ b/src/login/logind-action.c
@@ -23,7 +23,7 @@
#include "bus-error.h"
#include "bus-util.h"
#include "conf-parser.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "logind-action.h"
#include "process-util.h"
#include "sleep-config.h"
diff --git a/src/login/logind-button.c b/src/login/logind-button.c
index 90fb93bbaf..d739af8ea2 100644
--- a/src/login/logind-button.c
+++ b/src/login/logind-button.c
@@ -155,7 +155,7 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u
case KEY_POWER2:
log_struct(LOG_INFO,
LOG_MESSAGE("Power key pressed."),
- LOG_MESSAGE_ID(SD_MESSAGE_POWER_KEY),
+ "MESSAGE_ID=" SD_MESSAGE_POWER_KEY_STR,
NULL);
manager_handle_action(b->manager, INHIBIT_HANDLE_POWER_KEY, b->manager->handle_power_key, b->manager->power_key_ignore_inhibited, true);
@@ -170,7 +170,7 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u
case KEY_SLEEP:
log_struct(LOG_INFO,
LOG_MESSAGE("Suspend key pressed."),
- LOG_MESSAGE_ID(SD_MESSAGE_SUSPEND_KEY),
+ "MESSAGE_ID=" SD_MESSAGE_SUSPEND_KEY_STR,
NULL);
manager_handle_action(b->manager, INHIBIT_HANDLE_SUSPEND_KEY, b->manager->handle_suspend_key, b->manager->suspend_key_ignore_inhibited, true);
@@ -179,7 +179,7 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u
case KEY_SUSPEND:
log_struct(LOG_INFO,
LOG_MESSAGE("Hibernate key pressed."),
- LOG_MESSAGE_ID(SD_MESSAGE_HIBERNATE_KEY),
+ "MESSAGE_ID=" SD_MESSAGE_HIBERNATE_KEY_STR,
NULL);
manager_handle_action(b->manager, INHIBIT_HANDLE_HIBERNATE_KEY, b->manager->handle_hibernate_key, b->manager->hibernate_key_ignore_inhibited, true);
@@ -191,7 +191,7 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u
if (ev.code == SW_LID) {
log_struct(LOG_INFO,
LOG_MESSAGE("Lid closed."),
- LOG_MESSAGE_ID(SD_MESSAGE_LID_CLOSED),
+ "MESSAGE_ID=" SD_MESSAGE_LID_CLOSED_STR,
NULL);
b->lid_closed = true;
@@ -201,7 +201,7 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u
} else if (ev.code == SW_DOCK) {
log_struct(LOG_INFO,
LOG_MESSAGE("System docked."),
- LOG_MESSAGE_ID(SD_MESSAGE_SYSTEM_DOCKED),
+ "MESSAGE_ID=" SD_MESSAGE_SYSTEM_DOCKED_STR,
NULL);
b->docked = true;
@@ -212,7 +212,7 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u
if (ev.code == SW_LID) {
log_struct(LOG_INFO,
LOG_MESSAGE("Lid opened."),
- LOG_MESSAGE_ID(SD_MESSAGE_LID_OPENED),
+ "MESSAGE_ID=" SD_MESSAGE_LID_OPENED_STR,
NULL);
b->lid_closed = false;
@@ -221,7 +221,7 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u
} else if (ev.code == SW_DOCK) {
log_struct(LOG_INFO,
LOG_MESSAGE("System undocked."),
- LOG_MESSAGE_ID(SD_MESSAGE_SYSTEM_UNDOCKED),
+ "MESSAGE_ID=" SD_MESSAGE_SYSTEM_UNDOCKED_STR,
NULL);
b->docked = false;
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 0a84d75e24..c6be596af3 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -34,7 +34,7 @@
#include "escape.h"
#include "fd-util.h"
#include "fileio-label.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "fs-util.h"
#include "logind.h"
#include "mkdir.h"
@@ -1286,8 +1286,7 @@ static int flush_devices(Manager *m) {
} else {
struct dirent *de;
- while ((de = readdir(d))) {
-
+ FOREACH_DIRENT_ALL(de, d, break) {
if (!dirent_is_file(de))
continue;
@@ -1431,7 +1430,7 @@ static int bus_manager_log_shutdown(
p = strjoina(p, " (", m->wall_message, ").");
return log_struct(LOG_NOTICE,
- LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
+ "MESSAGE_ID=" SD_MESSAGE_SHUTDOWN_STR,
p,
q,
NULL);
@@ -2397,13 +2396,9 @@ static int method_set_wall_message(
if (r == 0)
return 1; /* Will call us back */
- if (isempty(wall_message))
- m->wall_message = mfree(m->wall_message);
- else {
- r = free_and_strdup(&m->wall_message, wall_message);
- if (r < 0)
- return log_oom();
- }
+ r = free_and_strdup(&m->wall_message, empty_to_null(wall_message));
+ if (r < 0)
+ return log_oom();
m->enable_wall_messages = enable_wall_messages;
diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c
index c93b24009b..1e6f383738 100644
--- a/src/login/logind-inhibit.c
+++ b/src/login/logind-inhibit.c
@@ -26,7 +26,7 @@
#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "logind-inhibit.h"
#include "mkdir.h"
#include "parse-util.h"
@@ -294,7 +294,7 @@ int inhibitor_create_fifo(Inhibitor *i) {
if (r < 0)
return r;
- i->fifo_path = strjoin("/run/systemd/inhibit/", i->id, ".ref", NULL);
+ i->fifo_path = strjoin("/run/systemd/inhibit/", i->id, ".ref");
if (!i->fifo_path)
return -ENOMEM;
@@ -347,7 +347,7 @@ InhibitWhat manager_inhibit_what(Manager *m, InhibitMode mm) {
assert(m);
HASHMAP_FOREACH(i, m->inhibitors, j)
- if (i->mode == mm)
+ if (i->mode == mm && i->started)
what |= i->what;
return what;
@@ -388,6 +388,9 @@ bool manager_is_inhibited(
assert(w > 0 && w < _INHIBIT_WHAT_MAX);
HASHMAP_FOREACH(i, m->inhibitors, j) {
+ if (!i->started)
+ continue;
+
if (!(i->what & w))
continue;
diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c
index ecc7bd2e5b..30dac7997b 100644
--- a/src/login/logind-seat.c
+++ b/src/login/logind-seat.c
@@ -27,7 +27,7 @@
#include "alloc-util.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "logind-acl.h"
#include "logind-seat.h"
#include "mkdir.h"
@@ -379,7 +379,8 @@ int seat_read_active_vt(Seat *s) {
if (!seat_has_vts(s))
return 0;
- lseek(s->manager->console_active_fd, SEEK_SET, 0);
+ if (lseek(s->manager->console_active_fd, SEEK_SET, 0) < 0)
+ return log_error_errno(errno, "lseek on console_active_fd failed: %m");
k = read(s->manager->console_active_fd, t, sizeof(t)-1);
if (k <= 0) {
@@ -396,10 +397,8 @@ int seat_read_active_vt(Seat *s) {
}
r = safe_atou(t+3, &vtnr);
- if (r < 0) {
- log_error("Failed to parse VT number %s", t+3);
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse VT number \"%s\": %m", t+3);
if (!vtnr) {
log_error("VT number invalid: %s", t+3);
@@ -416,7 +415,7 @@ int seat_start(Seat *s) {
return 0;
log_struct(LOG_INFO,
- LOG_MESSAGE_ID(SD_MESSAGE_SEAT_START),
+ "MESSAGE_ID=" SD_MESSAGE_SEAT_START_STR,
"SEAT_ID=%s", s->id,
LOG_MESSAGE("New seat %s.", s->id),
NULL);
@@ -444,7 +443,7 @@ int seat_stop(Seat *s, bool force) {
if (s->started)
log_struct(LOG_INFO,
- LOG_MESSAGE_ID(SD_MESSAGE_SEAT_STOP),
+ "MESSAGE_ID=" SD_MESSAGE_SEAT_STOP_STR,
"SEAT_ID=%s", s->id,
LOG_MESSAGE("Removed seat %s.", s->id),
NULL);
@@ -541,8 +540,6 @@ int seat_attach_session(Seat *s, Session *session) {
LIST_PREPEND(sessions_by_seat, s->sessions, session);
seat_assign_position(s, session);
- seat_send_changed(s, "Sessions", NULL);
-
/* On seats with VTs, the VT logic defines which session is active. On
* seats without VTs, we automatically activate new sessions. */
if (!seat_has_vts(s))
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index cbf035f706..4a168906d6 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -35,7 +35,7 @@
#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "io-util.h"
#include "logind-session.h"
#include "mkdir.h"
@@ -505,7 +505,7 @@ static int session_start_scope(Session *s) {
char *scope, *job = NULL;
const char *description;
- scope = strjoin("session-", s->id, ".scope", NULL);
+ scope = strjoin("session-", s->id, ".scope");
if (!scope)
return log_oom();
@@ -561,7 +561,7 @@ int session_start(Session *s) {
return r;
log_struct(s->class == SESSION_BACKGROUND ? LOG_DEBUG : LOG_INFO,
- LOG_MESSAGE_ID(SD_MESSAGE_SESSION_START),
+ "MESSAGE_ID=" SD_MESSAGE_SESSION_START_STR,
"SESSION_ID=%s", s->id,
"USER_ID=%s", s->user->name,
"LEADER="PID_FMT, s->leader,
@@ -586,12 +586,10 @@ int session_start(Session *s) {
/* Send signals */
session_send_signal(s, true);
- user_send_changed(s->user, "Sessions", "Display", NULL);
+ user_send_changed(s->user, "Display", NULL);
if (s->seat) {
if (s->seat->active == s)
- seat_send_changed(s->seat, "Sessions", "ActiveSession", NULL);
- else
- seat_send_changed(s->seat, "Sessions", NULL);
+ seat_send_changed(s->seat, "ActiveSession", NULL);
}
return 0;
@@ -668,7 +666,7 @@ int session_finalize(Session *s) {
if (s->started)
log_struct(s->class == SESSION_BACKGROUND ? LOG_DEBUG : LOG_INFO,
- LOG_MESSAGE_ID(SD_MESSAGE_SESSION_STOP),
+ "MESSAGE_ID=" SD_MESSAGE_SESSION_STOP_STR,
"SESSION_ID=%s", s->id,
"USER_ID=%s", s->user->name,
"LEADER="PID_FMT, s->leader,
@@ -698,11 +696,10 @@ int session_finalize(Session *s) {
seat_set_active(s->seat, NULL);
seat_save(s->seat);
- seat_send_changed(s->seat, "Sessions", NULL);
}
user_save(s->user);
- user_send_changed(s->user, "Sessions", "Display", NULL);
+ user_send_changed(s->user, "Display", NULL);
return 0;
}
diff --git a/src/login/logind-user-dbus.c b/src/login/logind-user-dbus.c
index af6392e025..987c63014f 100644
--- a/src/login/logind-user-dbus.c
+++ b/src/login/logind-user-dbus.c
@@ -22,7 +22,7 @@
#include "alloc-util.h"
#include "bus-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "logind-user.h"
#include "logind.h"
#include "signal-util.h"
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index 2dc5fa7665..888a97c2fc 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -32,7 +32,7 @@
#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "fs-util.h"
#include "hashmap.h"
#include "label.h"
@@ -338,7 +338,7 @@ static int user_mkdir_runtime_path(User *u) {
if (r < 0)
return log_error_errno(r, "Failed to create /run/user: %m");
- if (path_is_mount_point(u->runtime_path, 0) <= 0) {
+ if (path_is_mount_point(u->runtime_path, NULL, 0) <= 0) {
_cleanup_free_ char *t = NULL;
(void) mkdir_label(u->runtime_path, 0700);
diff --git a/src/login/logind-utmp.c b/src/login/logind-utmp.c
index 29ab00eb1f..311751c2db 100644
--- a/src/login/logind-utmp.c
+++ b/src/login/logind-utmp.c
@@ -29,7 +29,7 @@
#include "bus-common-errors.h"
#include "bus-error.h"
#include "bus-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "logind.h"
#include "special.h"
#include "strv.h"
diff --git a/src/login/logind.c b/src/login/logind.c
index a9841a3832..19bae294a4 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -32,7 +32,7 @@
#include "def.h"
#include "dirent-util.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "logind.h"
#include "selinux-util.h"
#include "signal-util.h"
diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c
index 4f023640f6..dab082a26e 100644
--- a/src/login/pam_systemd.c
+++ b/src/login/pam_systemd.c
@@ -36,7 +36,7 @@
#include "def.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "hostname-util.h"
#include "login-util.h"
#include "macro.h"
@@ -186,7 +186,7 @@ static int export_legacy_dbus_address(
* daemons that spawn dbus-daemon, instead of forcing
* DBUS_SESSION_BUS_ADDRESS= here. */
- s = strjoin(runtime, "/bus", NULL);
+ s = strjoin(runtime, "/bus");
if (!s)
goto error;
diff --git a/src/login/systemd-user.m4 b/src/login/systemd-user.m4
index e33963b125..4f85b4b7fe 100644
--- a/src/login/systemd-user.m4
+++ b/src/login/systemd-user.m4
@@ -3,10 +3,10 @@
# Used by systemd --user instances.
account required pam_unix.so
-
m4_ifdef(`HAVE_SELINUX',
-session required pam_selinux.so close
-session required pam_selinux.so nottys open
+session required pam_selinux.so close
+session required pam_selinux.so nottys open
)m4_dnl
-session required pam_loginuid.so
+session required pam_loginuid.so
+session optional pam_keyinit.so force revoke
session optional pam_systemd.so
diff --git a/src/machine-id-setup/machine-id-setup-main.c b/src/machine-id-setup/machine-id-setup-main.c
index cc9b1b38fe..2244b1cc76 100644
--- a/src/machine-id-setup/machine-id-setup-main.c
+++ b/src/machine-id-setup/machine-id-setup-main.c
@@ -22,6 +22,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include "id128-util.h"
#include "log.h"
#include "machine-id-setup.h"
#include "path-util.h"
@@ -118,11 +119,14 @@ int main(int argc, char *argv[]) {
goto finish;
if (arg_commit) {
+ const char *etc_machine_id;
+
r = machine_id_commit(arg_root);
if (r < 0)
goto finish;
- r = sd_id128_get_machine(&id);
+ etc_machine_id = prefix_roota(arg_root, "/etc/machine-id");
+ r = id128_read(etc_machine_id, ID128_PLAIN, &id);
if (r < 0) {
log_error_errno(r, "Failed to read machine ID back: %m");
goto finish;
diff --git a/src/machine/image-dbus.c b/src/machine/image-dbus.c
index 867bbc467b..2f69e2c7b7 100644
--- a/src/machine/image-dbus.c
+++ b/src/machine/image-dbus.c
@@ -17,14 +17,23 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <sys/mount.h>
+
#include "alloc-util.h"
#include "bus-label.h"
#include "bus-util.h"
+#include "copy.h"
+#include "dissect-image.h"
#include "fd-util.h"
+#include "fileio.h"
+#include "fs-util.h"
#include "image-dbus.h"
#include "io-util.h"
+#include "loop-util.h"
#include "machine-image.h"
+#include "mount-util.h"
#include "process-util.h"
+#include "raw-clone.h"
#include "strv.h"
#include "user-util.h"
@@ -279,6 +288,160 @@ int bus_image_method_set_limit(
return sd_bus_reply_method_return(message, NULL);
}
+#define EXIT_NOT_FOUND 2
+
+static int directory_image_get_os_release(Image *image, char ***ret, sd_bus_error *error) {
+
+ _cleanup_free_ char *path = NULL;
+ int r;
+
+ assert(image);
+ assert(ret);
+
+ r = chase_symlinks("/etc/os-release", image->path, CHASE_PREFIX_ROOT, &path);
+ if (r == -ENOENT)
+ r = chase_symlinks("/usr/lib/os-release", image->path, CHASE_PREFIX_ROOT, &path);
+ if (r == -ENOENT)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Image does not contain OS release information");
+ if (r < 0)
+ return sd_bus_error_set_errnof(error, r, "Failed to resolve %s: %m", image->path);
+
+ r = load_env_file_pairs(NULL, path, NULL, ret);
+ if (r < 0)
+ return sd_bus_error_set_errnof(error, r, "Failed to open %s: %m", path);
+
+ return 0;
+}
+
+static int raw_image_get_os_release(Image *image, char ***ret, sd_bus_error *error) {
+ _cleanup_(rmdir_and_freep) char *t = NULL;
+ _cleanup_(loop_device_unrefp) LoopDevice *d = NULL;
+ _cleanup_(dissected_image_unrefp) DissectedImage *m = NULL;
+ _cleanup_(sigkill_waitp) pid_t child = 0;
+ _cleanup_close_pair_ int pair[2] = { -1, -1 };
+ _cleanup_fclose_ FILE *f = NULL;
+ _cleanup_strv_free_ char **v = NULL;
+ siginfo_t si;
+ int r;
+
+ assert(image);
+ assert(ret);
+
+ r = mkdtemp_malloc("/tmp/machined-root-XXXXXX", &t);
+ if (r < 0)
+ return sd_bus_error_set_errnof(error, r, "Failed to create temporary directory: %m");
+
+ r = loop_device_make_by_path(image->path, O_RDONLY, &d);
+ if (r < 0)
+ return sd_bus_error_set_errnof(error, r, "Failed to set up loop block device for %s: %m", image->path);
+
+ r = dissect_image(d->fd, NULL, 0, DISSECT_IMAGE_REQUIRE_ROOT, &m);
+ if (r == -ENOPKG)
+ return sd_bus_error_set_errnof(error, r, "Disk image %s not understood: %m", image->path);
+ if (r < 0)
+ return sd_bus_error_set_errnof(error, r, "Failed to dissect image %s: %m", image->path);
+
+ if (pipe2(pair, O_CLOEXEC) < 0)
+ return sd_bus_error_set_errnof(error, errno, "Failed to create communication pipe: %m");
+
+ child = raw_clone(SIGCHLD|CLONE_NEWNS);
+ if (child < 0)
+ return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
+
+ if (child == 0) {
+ int fd;
+
+ pair[0] = safe_close(pair[0]);
+
+ /* Make sure we never propagate to the host */
+ if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0)
+ _exit(EXIT_FAILURE);
+
+ r = dissected_image_mount(m, t, DISSECT_IMAGE_READ_ONLY);
+ if (r < 0)
+ _exit(EXIT_FAILURE);
+
+ r = mount_move_root(t);
+ if (r < 0)
+ _exit(EXIT_FAILURE);
+
+ fd = open("/etc/os-release", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+ if (fd < 0 && errno == ENOENT) {
+ fd = open("/usr/lib/os-release", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+ if (fd < 0 && errno == ENOENT)
+ _exit(EXIT_NOT_FOUND);
+ }
+ if (fd < 0)
+ _exit(EXIT_FAILURE);
+
+ r = copy_bytes(fd, pair[1], (uint64_t) -1, 0);
+ if (r < 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ pair[1] = safe_close(pair[1]);
+
+ f = fdopen(pair[0], "re");
+ if (!f)
+ return -errno;
+
+ pair[0] = -1;
+
+ r = load_env_file_pairs(f, "os-release", NULL, &v);
+ if (r < 0)
+ return r;
+
+ r = wait_for_terminate(child, &si);
+ if (r < 0)
+ return sd_bus_error_set_errnof(error, r, "Failed to wait for child: %m");
+ child = 0;
+ if (si.si_code == CLD_EXITED && si.si_status == EXIT_NOT_FOUND)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Image does not contain OS release information");
+ if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Child died abnormally.");
+
+ *ret = v;
+ v = NULL;
+
+ return 0;
+}
+
+int bus_image_method_get_os_release(
+ sd_bus_message *message,
+ void *userdata,
+ sd_bus_error *error) {
+
+ _cleanup_release_lock_file_ LockFile tree_global_lock = LOCK_FILE_INIT, tree_local_lock = LOCK_FILE_INIT;
+ _cleanup_strv_free_ char **v = NULL;
+ Image *image = userdata;
+ int r;
+
+ r = image_path_lock(image->path, LOCK_SH|LOCK_NB, &tree_global_lock, &tree_local_lock);
+ if (r < 0)
+ return sd_bus_error_set_errnof(error, r, "Failed to lock image: %m");
+
+ switch (image->type) {
+
+ case IMAGE_DIRECTORY:
+ case IMAGE_SUBVOLUME:
+ r = directory_image_get_os_release(image, &v, error);
+ break;
+
+ case IMAGE_RAW:
+ r = raw_image_get_os_release(image, &v, error);
+ break;
+
+ default:
+ assert_not_reached("Unknown image type");
+ }
+ if (r < 0)
+ return r;
+
+ return bus_reply_pair_array(message, v);
+}
+
const sd_bus_vtable image_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Image, name), 0),
@@ -296,6 +459,7 @@ const sd_bus_vtable image_vtable[] = {
SD_BUS_METHOD("Clone", "sb", NULL, bus_image_method_clone, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("MarkReadOnly", "b", NULL, bus_image_method_mark_read_only, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SetLimit", "t", NULL, bus_image_method_set_limit, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetOSRelease", NULL, "a{ss}", bus_image_method_get_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END
};
diff --git a/src/machine/image-dbus.h b/src/machine/image-dbus.h
index b62da996c6..bc8a6c3400 100644
--- a/src/machine/image-dbus.h
+++ b/src/machine/image-dbus.h
@@ -33,3 +33,4 @@ int bus_image_method_rename(sd_bus_message *message, void *userdata, sd_bus_erro
int bus_image_method_clone(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_image_method_mark_read_only(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_image_method_set_limit(sd_bus_message *message, void *userdata, sd_bus_error *error);
+int bus_image_method_get_os_release(sd_bus_message *message, void *userdata, sd_bus_error *error);
diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c
index 5ca18ff87e..36568b65ef 100644
--- a/src/machine/machine-dbus.c
+++ b/src/machine/machine-dbus.c
@@ -37,7 +37,7 @@
#include "env-util.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "fs-util.h"
#include "in-addr-util.h"
#include "local-addresses.h"
@@ -356,11 +356,11 @@ int bus_machine_method_get_addresses(sd_bus_message *message, void *userdata, sd
return sd_bus_send(NULL, reply, NULL);
}
+#define EXIT_NOT_FOUND 2
+
int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_strv_free_ char **l = NULL;
Machine *m = userdata;
- char **k, **v;
int r;
assert(message);
@@ -394,7 +394,7 @@ int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, s
return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
if (child == 0) {
- _cleanup_close_ int fd = -1;
+ int fd = -1;
pair[0] = safe_close(pair[0]);
@@ -402,14 +402,16 @@ int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, s
if (r < 0)
_exit(EXIT_FAILURE);
- fd = open("/etc/os-release", O_RDONLY|O_CLOEXEC);
- if (fd < 0) {
- fd = open("/usr/lib/os-release", O_RDONLY|O_CLOEXEC);
- if (fd < 0)
- _exit(EXIT_FAILURE);
+ fd = open("/etc/os-release", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+ if (fd < 0 && errno == ENOENT) {
+ fd = open("/usr/lib/os-release", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+ if (fd < 0 && errno == ENOENT)
+ _exit(EXIT_NOT_FOUND);
}
+ if (fd < 0)
+ _exit(EXIT_FAILURE);
- r = copy_bytes(fd, pair[1], (uint64_t) -1, false);
+ r = copy_bytes(fd, pair[1], (uint64_t) -1, 0);
if (r < 0)
_exit(EXIT_FAILURE);
@@ -431,6 +433,8 @@ int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, s
r = wait_for_terminate(child, &si);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to wait for child: %m");
+ if (si.si_code == CLD_EXITED && si.si_status == EXIT_NOT_FOUND)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Machine does not contain OS release information");
if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Child died abnormally.");
@@ -441,25 +445,7 @@ int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, s
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Requesting OS release data is only supported on container machines.");
}
- r = sd_bus_message_new_method_return(message, &reply);
- if (r < 0)
- return r;
-
- r = sd_bus_message_open_container(reply, 'a', "{ss}");
- if (r < 0)
- return r;
-
- STRV_FOREACH_PAIR(k, v, l) {
- r = sd_bus_message_append(reply, "{ss}", *k, *v);
- if (r < 0)
- return r;
- }
-
- r = sd_bus_message_close_container(reply);
- if (r < 0)
- return r;
-
- return sd_bus_send(NULL, reply, NULL);
+ return bus_reply_pair_array(message, l);
}
int bus_machine_method_open_pty(sd_bus_message *message, void *userdata, sd_bus_error *error) {
@@ -855,6 +841,7 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu
int read_only, make_directory;
pid_t child;
siginfo_t si;
+ uid_t uid;
int r;
assert(message);
@@ -889,6 +876,12 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu
if (r == 0)
return 1; /* Will call us back */
+ r = machine_get_uid_shift(m, &uid);
+ if (r < 0)
+ return r;
+ if (uid != 0)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Can't bind mount on container with user namespacing applied.");
+
/* One day, when bind mounting /proc/self/fd/n works across
* namespace boundaries we should rework this logic to make
* use of it... */
@@ -1069,10 +1062,12 @@ finish:
int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *src, *dest, *host_path, *container_path, *host_basename, *host_dirname, *container_basename, *container_dirname;
_cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
+ CopyFlags copy_flags = COPY_REFLINK|COPY_MERGE;
_cleanup_close_ int hostfd = -1;
Machine *m = userdata;
bool copy_from;
pid_t child;
+ uid_t uid_shift;
char *t;
int r;
@@ -1111,6 +1106,10 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro
if (r == 0)
return 1; /* Will call us back */
+ r = machine_get_uid_shift(m, &uid_shift);
+ if (r < 0)
+ return r;
+
copy_from = strstr(sd_bus_message_get_member(message), "CopyFrom");
if (copy_from) {
@@ -1165,10 +1164,13 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro
goto child_fail;
}
+ /* Run the actual copy operation. Note that when an UID shift is set we'll either clamp the UID/GID to
+ * 0 or to the actual UID shift depending on the direction we copy. If no UID shift is set we'll copy
+ * the UID/GIDs as they are. */
if (copy_from)
- r = copy_tree_at(containerfd, container_basename, hostfd, host_basename, true);
+ r = copy_tree_at(containerfd, container_basename, hostfd, host_basename, uid_shift == 0 ? UID_INVALID : 0, uid_shift == 0 ? GID_INVALID : 0, copy_flags);
else
- r = copy_tree_at(hostfd, host_basename, containerfd, container_basename, true);
+ r = copy_tree_at(hostfd, host_basename, containerfd, container_basename, uid_shift == 0 ? UID_INVALID : uid_shift, uid_shift == 0 ? GID_INVALID : uid_shift, copy_flags);
hostfd = safe_close(hostfd);
containerfd = safe_close(containerfd);
@@ -1290,6 +1292,32 @@ int bus_machine_method_open_root_directory(sd_bus_message *message, void *userda
return sd_bus_reply_method_return(message, "h", fd);
}
+int bus_machine_method_get_uid_shift(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ Machine *m = userdata;
+ uid_t shift = 0;
+ int r;
+
+ assert(message);
+ assert(m);
+
+ /* You wonder why this is a method and not a property? Well, properties are not supposed to return errors, but
+ * we kinda have to for this. */
+
+ if (m->class == MACHINE_HOST)
+ return sd_bus_reply_method_return(message, "u", UINT32_C(0));
+
+ if (m->class != MACHINE_CONTAINER)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "UID/GID shift may only be determined for container machines.");
+
+ r = machine_get_uid_shift(m, &shift);
+ if (r == -ENXIO)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Machine %s uses a complex UID/GID mapping, cannot determine shift", m->name);
+ if (r < 0)
+ return r;
+
+ return sd_bus_reply_method_return(message, "u", (uint32_t) shift);
+}
+
const sd_bus_vtable machine_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Machine, name), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -1307,6 +1335,7 @@ const sd_bus_vtable machine_vtable[] = {
SD_BUS_METHOD("Kill", "si", NULL, bus_machine_method_kill, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetAddresses", NULL, "a(iay)", bus_machine_method_get_addresses, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetOSRelease", NULL, "a{ss}", bus_machine_method_get_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetUIDShift", NULL, "u", bus_machine_method_get_uid_shift, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("OpenPTY", NULL, "hs", bus_machine_method_open_pty, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("OpenLogin", NULL, "hs", bus_machine_method_open_login, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("OpenShell", "ssasas", "hs", bus_machine_method_open_shell, SD_BUS_VTABLE_UNPRIVILEGED),
diff --git a/src/machine/machine-dbus.h b/src/machine/machine-dbus.h
index 241b23c7ec..2aa7b4ce06 100644
--- a/src/machine/machine-dbus.h
+++ b/src/machine/machine-dbus.h
@@ -39,6 +39,9 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu
int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_machine_method_open_root_directory(sd_bus_message *message, void *userdata, sd_bus_error *error);
+int bus_machine_method_get_uid_shift(sd_bus_message *message, void *userdata, sd_bus_error *error);
int machine_send_signal(Machine *m, bool new_machine);
int machine_send_create_reply(Machine *m, sd_bus_error *error);
+
+int bus_reply_pair_array(sd_bus_message *m, char **l);
diff --git a/src/machine/machine.c b/src/machine/machine.c
index a02b9d7575..d3433d9b96 100644
--- a/src/machine/machine.c
+++ b/src/machine/machine.c
@@ -30,7 +30,7 @@
#include "extract-word.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "hashmap.h"
#include "machine-dbus.h"
#include "machine.h"
@@ -38,6 +38,7 @@
#include "parse-util.h"
#include "process-util.h"
#include "special.h"
+#include "stdio-util.h"
#include "string-table.h"
#include "terminal-util.h"
#include "unit-name.h"
@@ -355,7 +356,7 @@ static int machine_start_scope(Machine *m, sd_bus_message *properties, sd_bus_er
if (!escaped)
return log_oom();
- scope = strjoin("machine-", escaped, ".scope", NULL);
+ scope = strjoin("machine-", escaped, ".scope");
if (!scope)
return log_oom();
@@ -401,7 +402,7 @@ int machine_start(Machine *m, sd_bus_message *properties, sd_bus_error *error) {
return r;
log_struct(LOG_INFO,
- LOG_MESSAGE_ID(SD_MESSAGE_MACHINE_START),
+ "MESSAGE_ID=" SD_MESSAGE_MACHINE_START_STR,
"NAME=%s", m->name,
"LEADER="PID_FMT, m->leader,
LOG_MESSAGE("New machine %s.", m->name),
@@ -464,7 +465,7 @@ int machine_finalize(Machine *m) {
if (m->started)
log_struct(LOG_INFO,
- LOG_MESSAGE_ID(SD_MESSAGE_MACHINE_STOP),
+ "MESSAGE_ID=" SD_MESSAGE_MACHINE_STOP_STR,
"NAME=%s", m->name,
"LEADER="PID_FMT, m->leader,
LOG_MESSAGE("Machine %s terminated.", m->name),
@@ -604,6 +605,96 @@ void machine_release_unit(Machine *m) {
m->unit = mfree(m->unit);
}
+int machine_get_uid_shift(Machine *m, uid_t *ret) {
+ char p[strlen("/proc//uid_map") + DECIMAL_STR_MAX(pid_t) + 1];
+ uid_t uid_base, uid_shift, uid_range;
+ gid_t gid_base, gid_shift, gid_range;
+ _cleanup_fclose_ FILE *f = NULL;
+ int k;
+
+ assert(m);
+ assert(ret);
+
+ /* Return the base UID/GID of the specified machine. Note that this only works for containers with simple
+ * mappings. In most cases setups should be simple like this, and administrators should only care about the
+ * basic offset a container has relative to the host. This is what this function exposes.
+ *
+ * If we encounter any more complex mappings we politely refuse this with ENXIO. */
+
+ if (m->class == MACHINE_HOST) {
+ *ret = 0;
+ return 0;
+ }
+
+ if (m->class != MACHINE_CONTAINER)
+ return -EOPNOTSUPP;
+
+ xsprintf(p, "/proc/" PID_FMT "/uid_map", m->leader);
+ f = fopen(p, "re");
+ if (!f) {
+ if (errno == ENOENT) {
+ /* If the file doesn't exist, user namespacing is off in the kernel, return a zero mapping hence. */
+ *ret = 0;
+ return 0;
+ }
+
+ return -errno;
+ }
+
+ /* Read the first line. There's at least one. */
+ errno = 0;
+ k = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT "\n", &uid_base, &uid_shift, &uid_range);
+ if (k != 3) {
+ if (ferror(f))
+ return -errno;
+
+ return -EBADMSG;
+ }
+
+ /* Not a mapping starting at 0? Then it's a complex mapping we can't expose here. */
+ if (uid_base != 0)
+ return -ENXIO;
+ /* Insist that at least the nobody user is mapped, everything else is weird, and hence complex, and we don't support it */
+ if (uid_range < (uid_t) 65534U)
+ return -ENXIO;
+
+ /* If there's more than one line, then we don't support this mapping. */
+ if (fgetc(f) != EOF)
+ return -ENXIO;
+
+ fclose(f);
+
+ xsprintf(p, "/proc/" PID_FMT "/gid_map", m->leader);
+ f = fopen(p, "re");
+ if (!f)
+ return -errno;
+
+ /* Read the first line. There's at least one. */
+ errno = 0;
+ k = fscanf(f, GID_FMT " " GID_FMT " " GID_FMT "\n", &gid_base, &gid_shift, &gid_range);
+ if (k != 3) {
+ if (ferror(f))
+ return -errno;
+
+ return -EBADMSG;
+ }
+
+ /* If there's more than one line, then we don't support this file. */
+ if (fgetc(f) != EOF)
+ return -ENXIO;
+
+ /* If the UID and GID mapping doesn't match, we don't support this mapping. */
+ if (uid_base != (uid_t) gid_base)
+ return -ENXIO;
+ if (uid_shift != (uid_t) gid_shift)
+ return -ENXIO;
+ if (uid_range != (uid_t) gid_range)
+ return -ENXIO;
+
+ *ret = uid_shift;
+ return 0;
+}
+
static const char* const machine_class_table[_MACHINE_CLASS_MAX] = {
[MACHINE_CONTAINER] = "container",
[MACHINE_VM] = "vm",
diff --git a/src/machine/machine.h b/src/machine/machine.h
index e5d75361a9..6bdb204ed6 100644
--- a/src/machine/machine.h
+++ b/src/machine/machine.h
@@ -108,3 +108,5 @@ KillWho kill_who_from_string(const char *s) _pure_;
int machine_openpt(Machine *m, int flags);
int machine_open_terminal(Machine *m, const char *path, int mode);
+
+int machine_get_uid_shift(Machine *m, uid_t *ret);
diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c
index 7b9be3b425..3031ed5def 100644
--- a/src/machine/machinectl.c
+++ b/src/machine/machinectl.c
@@ -138,7 +138,7 @@ static void clean_machine_info(MachineInfo *machines, size_t n_machines) {
free(machines);
}
-static int get_os_release_property(sd_bus *bus, const char *name, const char *query, ...) {
+static int call_get_os_release(sd_bus *bus, const char *method, const char *name, const char *query, ...) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
const char *k, *v, *iter, **query_res = NULL;
size_t count = 0, awaited_args = 0;
@@ -153,12 +153,13 @@ static int get_os_release_property(sd_bus *bus, const char *name, const char *qu
awaited_args++;
query_res = newa0(const char *, awaited_args);
- r = sd_bus_call_method(bus,
- "org.freedesktop.machine1",
- "/org/freedesktop/machine1",
- "org.freedesktop.machine1.Manager",
- "GetMachineOSRelease",
- NULL, &reply, "s", name);
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ method,
+ NULL, &reply, "s", name);
if (r < 0)
return r;
@@ -193,7 +194,7 @@ static int get_os_release_property(sd_bus *bus, const char *name, const char *qu
val = strdup(query_res[count]);
if (!val) {
va_end(ap);
- return log_oom();
+ return -ENOMEM;
}
*out = val;
}
@@ -242,24 +243,24 @@ static int list_machines(int argc, char *argv[], void *userdata) {
if (name[0] == '.' && !arg_all)
continue;
- if (!GREEDY_REALLOC(machines, n_allocated, n_machines + 1)) {
+ if (!GREEDY_REALLOC0(machines, n_allocated, n_machines + 1)) {
r = log_oom();
goto out;
}
- machines[n_machines].os = NULL;
- machines[n_machines].version_id = NULL;
- r = get_os_release_property(bus, name,
- "ID\0" "VERSION_ID\0",
- &machines[n_machines].os,
- &machines[n_machines].version_id);
- if (r < 0)
- goto out;
-
machines[n_machines].name = name;
machines[n_machines].class = class;
machines[n_machines].service = service;
+ (void) call_get_os_release(
+ bus,
+ "GetMachineOSRelease",
+ name,
+ "ID\0"
+ "VERSION_ID\0",
+ &machines[n_machines].os,
+ &machines[n_machines].version_id);
+
l = strlen(name);
if (l > max_name)
max_name = l;
@@ -326,15 +327,20 @@ static int list_machines(int argc, char *argv[], void *userdata) {
(int) max_version_id, strdash_if_empty(machines[j].version_id));
r = print_addresses(bus, machines[j].name, 0, "", prefix, arg_addrs);
- if (r == -ENOSYS)
- printf("-\n");
+ if (r <= 0) /* error or no addresses defined? */
+ fputs("-\n", stdout);
+ else
+ fputc('\n', stdout);
}
- if (arg_legend && n_machines > 0)
- printf("\n%zu machines listed.\n", n_machines);
- else
- printf("No machines.\n");
+ if (arg_legend) {
+ if (n_machines > 0)
+ printf("\n%zu machines listed.\n", n_machines);
+ else
+ printf("No machines.\n");
+ }
+ r = 0;
out:
clean_machine_info(machines, n_machines);
return r;
@@ -463,44 +469,28 @@ static int list_images(int argc, char *argv[], void *userdata) {
(int) max_mtime, strna(format_timestamp(mtime_buf, sizeof(mtime_buf), images[j].mtime)));
}
- if (arg_legend && n_images > 0)
- printf("\n%zu images listed.\n", n_images);
- else
- printf("No images.\n");
+ if (arg_legend) {
+ if (n_images > 0)
+ printf("\n%zu images listed.\n", n_images);
+ else
+ printf("No images.\n");
+ }
return 0;
}
static int show_unit_cgroup(sd_bus *bus, const char *unit, pid_t leader) {
+ _cleanup_free_ char *cgroup = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- _cleanup_free_ char *path = NULL;
- const char *cgroup;
int r;
unsigned c;
assert(bus);
assert(unit);
- path = unit_dbus_path_from_name(unit);
- if (!path)
- return log_oom();
-
- r = sd_bus_get_property(
- bus,
- "org.freedesktop.systemd1",
- path,
- unit_dbus_interface_from_name(unit),
- "ControlGroup",
- &error,
- &reply,
- "s");
+ r = show_cgroup_get_unit_path_and_warn(bus, unit, &cgroup);
if (r < 0)
- return log_error_errno(r, "Failed to query ControlGroup: %s", bus_error_message(&error, r));
-
- r = sd_bus_message_read(reply, "s", &cgroup);
- if (r < 0)
- return bus_log_parse_error(r);
+ return r;
if (isempty(cgroup))
return 0;
@@ -533,6 +523,7 @@ static int print_addresses(sd_bus *bus, const char *name, int ifi, const char *p
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_free_ char *addresses = NULL;
bool truncate = false;
+ unsigned n = 0;
int r;
assert(bus);
@@ -580,7 +571,7 @@ static int print_addresses(sd_bus *bus, const char *name, int ifi, const char *p
else
strcpy(buf_ifi, "");
- if(!strextend(&addresses, prefix, inet_ntop(family, a, buffer, sizeof(buffer)), buf_ifi, NULL))
+ if (!strextend(&addresses, prefix, inet_ntop(family, a, buffer, sizeof(buffer)), buf_ifi, NULL))
return log_oom();
} else
truncate = true;
@@ -594,6 +585,8 @@ static int print_addresses(sd_bus *bus, const char *name, int ifi, const char *p
if (n_addr > 0)
n_addr -= 1;
+
+ n++;
}
if (r < 0)
return bus_log_parse_error(r);
@@ -602,11 +595,13 @@ static int print_addresses(sd_bus *bus, const char *name, int ifi, const char *p
if (r < 0)
return bus_log_parse_error(r);
- fprintf(stdout, "%s%s\n", addresses, truncate ? "..." : "");
- return 0;
+ if (n > 0)
+ fprintf(stdout, "%s%s", addresses, truncate ? "..." : "");
+
+ return (int) n;
}
-static int print_os_release(sd_bus *bus, const char *name, const char *prefix) {
+static int print_os_release(sd_bus *bus, const char *method, const char *name, const char *prefix) {
_cleanup_free_ char *pretty = NULL;
int r;
@@ -614,7 +609,7 @@ static int print_os_release(sd_bus *bus, const char *name, const char *prefix) {
assert(name);
assert(prefix);
- r = get_os_release_property(bus, name, "PRETTY_NAME\0", &pretty, NULL);
+ r = call_get_os_release(bus, method, name, "PRETTY_NAME\0", &pretty, NULL);
if (r < 0)
return r;
@@ -624,6 +619,37 @@ static int print_os_release(sd_bus *bus, const char *name, const char *prefix) {
return 0;
}
+static int print_uid_shift(sd_bus *bus, const char *name) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ uint32_t shift;
+ int r;
+
+ assert(bus);
+ assert(name);
+
+ r = sd_bus_call_method(bus,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "GetMachineUIDShift",
+ &error,
+ &reply,
+ "s", name);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to query UID/GID shift: %s", bus_error_message(&error, r));
+
+ r = sd_bus_message_read(reply, "u", &shift);
+ if (r < 0)
+ return r;
+
+ if (shift == 0) /* Don't show trivial mappings */
+ return 0;
+
+ printf(" UID Shift: %" PRIu32 "\n", shift);
+ return 0;
+}
+
typedef struct MachineStatusInfo {
char *name;
sd_id128_t id;
@@ -720,12 +746,15 @@ static void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
fputc('\n', stdout);
}
- print_addresses(bus, i->name, ifi,
- "\t Address: ",
- "\n\t ",
- ALL_IP_ADDRESSES);
+ if (print_addresses(bus, i->name, ifi,
+ "\t Address: ",
+ "\n\t ",
+ ALL_IP_ADDRESSES) > 0)
+ fputc('\n', stdout);
+
+ print_os_release(bus, "GetMachineOSRelease", i->name, "\t OS: ");
- print_os_release(bus, i->name, "\t OS: ");
+ print_uid_shift(bus, i->name);
if (i->unit) {
printf("\t Unit: %s\n", i->unit);
@@ -785,6 +814,7 @@ static int show_machine_info(const char *verb, sd_bus *bus, const char *path, bo
{}
};
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(machine_status_info_clear) MachineStatusInfo info = {};
int r;
@@ -797,9 +827,10 @@ static int show_machine_info(const char *verb, sd_bus *bus, const char *path, bo
"org.freedesktop.machine1",
path,
map,
+ &error,
&info);
if (r < 0)
- return log_error_errno(r, "Could not get properties: %m");
+ return log_error_errno(r, "Could not get properties: %s", bus_error_message(&error, r));
if (*new_line)
printf("\n");
@@ -923,6 +954,8 @@ static void print_image_status_info(sd_bus *bus, ImageStatusInfo *i) {
if (i->path)
printf("\t Path: %s\n", i->path);
+ print_os_release(bus, "GetImageOSRelease", i->name, "\t OS: ");
+
printf("\t RO: %s%s%s\n",
i->read_only ? ansi_highlight_red() : "",
i->read_only ? "read-only" : "writable",
@@ -973,6 +1006,7 @@ static int show_image_info(sd_bus *bus, const char *path, bool *new_line) {
{}
};
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(image_status_info_clear) ImageStatusInfo info = {};
int r;
@@ -984,9 +1018,10 @@ static int show_image_info(sd_bus *bus, const char *path, bool *new_line) {
"org.freedesktop.machine1",
path,
map,
+ &error,
&info);
if (r < 0)
- return log_error_errno(r, "Could not get properties: %m");
+ return log_error_errno(r, "Could not get properties: %s", bus_error_message(&error, r));
if (*new_line)
printf("\n");
@@ -1040,6 +1075,8 @@ static int show_pool_info(sd_bus *bus) {
.usage = (uint64_t) -1,
.limit = (uint64_t) -1,
};
+
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
int r;
assert(bus);
@@ -1048,9 +1085,10 @@ static int show_pool_info(sd_bus *bus) {
"org.freedesktop.machine1",
"/org/freedesktop/machine1",
map,
+ &error,
&info);
if (r < 0)
- return log_error_errno(r, "Could not get properties: %m");
+ return log_error_errno(r, "Could not get properties: %s", bus_error_message(&error, r));
print_pool_status_info(bus, &info);
@@ -2489,10 +2527,12 @@ static int list_transfers(int argc, char *argv[], void *userdata) {
(int) max_local, transfers[j].local,
(int) max_remote, transfers[j].remote);
- if (arg_legend && n_transfers > 0)
- printf("\n%zu transfers listed.\n", n_transfers);
- else
- printf("No transfers.\n");
+ if (arg_legend) {
+ if (n_transfers > 0)
+ printf("\n%zu transfers listed.\n", n_transfers);
+ else
+ printf("No transfers.\n");
+ }
return 0;
}
@@ -2657,9 +2697,9 @@ static int help(int argc, char *argv[], void *userdata) {
" -o --output=STRING Change journal output mode (short,\n"
" short-monotonic, verbose, export, json,\n"
" json-pretty, json-sse, cat)\n"
- " --verify=MODE Verification mode for downloaded images (no,\n"
+ " --verify=MODE Verification mode for downloaded images (no,\n"
" checksum, signature)\n"
- " --force Download image even if already exists\n\n"
+ " --force Download image even if already exists\n\n"
"Machine Commands:\n"
" list List running VMs and containers\n"
" status NAME... Show VM/container details\n"
@@ -2756,7 +2796,7 @@ static int parse_argv(int argc, char *argv[]) {
assert(argv);
for (;;) {
- static const char option_string[] = "-hp:als:H:M:qn:o:";
+ static const char option_string[] = "-hp:als:H:M:qn:o:E:";
c = getopt_long(argc, argv, option_string + reorder, options, NULL);
if (c < 0)
diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c
index e40f40a263..c9b92d2765 100644
--- a/src/machine/machined-dbus.c
+++ b/src/machine/machined-dbus.c
@@ -30,7 +30,7 @@
#include "cgroup-util.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "hostname-util.h"
#include "image-dbus.h"
#include "io-util.h"
@@ -729,6 +729,26 @@ static int method_open_machine_root_directory(sd_bus_message *message, void *use
return bus_machine_method_open_root_directory(message, machine, error);
}
+static int method_get_machine_uid_shift(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ Manager *m = userdata;
+ Machine *machine;
+ const char *name;
+ int r;
+
+ assert(message);
+ assert(m);
+
+ r = sd_bus_message_read(message, "s", &name);
+ if (r < 0)
+ return r;
+
+ machine = hashmap_get(m->machines, name);
+ if (!machine)
+ return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
+
+ return bus_machine_method_get_uid_shift(message, machine, error);
+}
+
static int method_remove_image(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_(image_unrefp) Image* i = NULL;
const char *name;
@@ -825,6 +845,30 @@ static int method_mark_image_read_only(sd_bus_message *message, void *userdata,
return bus_image_method_mark_read_only(message, i, error);
}
+static int method_get_image_os_release(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ _cleanup_(image_unrefp) Image *i = NULL;
+ const char *name;
+ int r;
+
+ assert(message);
+
+ r = sd_bus_message_read(message, "s", &name);
+ if (r < 0)
+ return r;
+
+ if (!image_name_is_valid(name))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
+
+ r = image_find(name, &i);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
+
+ i->userdata = userdata;
+ return bus_image_method_get_os_release(message, i, error);
+}
+
static int clean_pool_done(Operation *operation, int ret, sd_bus_error *error) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_fclose_ FILE *f = NULL;
@@ -1392,10 +1436,12 @@ const sd_bus_vtable manager_vtable[] = {
SD_BUS_METHOD("CopyFromMachine", "sss", NULL, method_copy_machine, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("CopyToMachine", "sss", NULL, method_copy_machine, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("OpenMachineRootDirectory", "s", "h", method_open_machine_root_directory, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetMachineUIDShift", "s", "u", method_get_machine_uid_shift, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("RemoveImage", "s", NULL, method_remove_image, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("RenameImage", "ss", NULL, method_rename_image, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("CloneImage", "ssb", NULL, method_clone_image, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("MarkImageReadOnly", "sb", NULL, method_mark_image_read_only, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetImageOSRelease", "s", "a{ss}", method_get_image_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SetPoolLimit", "t", NULL, method_set_pool_limit, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SetImageLimit", "st", NULL, method_set_image_limit, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("CleanPool", "s", "a(st)", method_clean_pool, SD_BUS_VTABLE_UNPRIVILEGED),
@@ -1804,3 +1850,30 @@ int manager_add_machine(Manager *m, const char *name, Machine **_machine) {
return 0;
}
+
+int bus_reply_pair_array(sd_bus_message *m, char **l) {
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ char **k, **v;
+ int r;
+
+ r = sd_bus_message_new_method_return(m, &reply);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_open_container(reply, 'a', "{ss}");
+ if (r < 0)
+ return r;
+
+ STRV_FOREACH_PAIR(k, v, l) {
+ r = sd_bus_message_append(reply, "{ss}", *k, *v);
+ if (r < 0)
+ return r;
+ }
+
+ r = sd_bus_message_close_container(reply);
+ if (r < 0)
+ return r;
+
+ return sd_bus_send(NULL, reply, NULL);
+
+}
diff --git a/src/machine/machined.c b/src/machine/machined.c
index 57121945f3..8719e01de9 100644
--- a/src/machine/machined.c
+++ b/src/machine/machined.c
@@ -29,7 +29,7 @@
#include "cgroup-util.h"
#include "dirent-util.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "hostname-util.h"
#include "label.h"
#include "machine-image.h"
diff --git a/src/machine/operation.c b/src/machine/operation.c
index c966d0d21c..f7d5310f44 100644
--- a/src/machine/operation.c
+++ b/src/machine/operation.c
@@ -61,8 +61,10 @@ static int operation_done(sd_event_source *s, const siginfo_t *si, void *userdat
} else {
/* The default operation when done is to simply return an error on failure or an empty success
* message on success. */
- if (r < 0)
+ if (r < 0) {
+ sd_bus_error_set_errno(&error, r);
goto fail;
+ }
r = sd_bus_reply_method_return(o->message, NULL);
if (r < 0)
diff --git a/src/machine/org.freedesktop.machine1.conf b/src/machine/org.freedesktop.machine1.conf
index 562b9d3cc0..daa365a9dd 100644
--- a/src/machine/org.freedesktop.machine1.conf
+++ b/src/machine/org.freedesktop.machine1.conf
@@ -66,6 +66,10 @@
<allow send_destination="org.freedesktop.machine1"
send_interface="org.freedesktop.machine1.Manager"
+ send_member="GetMachineUIDShift"/>
+
+ <allow send_destination="org.freedesktop.machine1"
+ send_interface="org.freedesktop.machine1.Manager"
send_member="OpenMachineLogin"/>
<allow send_destination="org.freedesktop.machine1"
@@ -118,6 +122,10 @@
<allow send_destination="org.freedesktop.machine1"
send_interface="org.freedesktop.machine1.Manager"
+ send_member="GetImageOSRelease"/>
+
+ <allow send_destination="org.freedesktop.machine1"
+ send_interface="org.freedesktop.machine1.Manager"
send_member="CleanPool"/>
<allow send_destination="org.freedesktop.machine1"
@@ -146,6 +154,10 @@
<allow send_destination="org.freedesktop.machine1"
send_interface="org.freedesktop.machine1.Machine"
+ send_member="GetUIDShift"/>
+
+ <allow send_destination="org.freedesktop.machine1"
+ send_interface="org.freedesktop.machine1.Machine"
send_member="OpenLogin"/>
<allow send_destination="org.freedesktop.machine1"
@@ -192,6 +204,10 @@
send_interface="org.freedesktop.machine1.Image"
send_member="MarkReadOnly"/>
+ <allow send_destination="org.freedesktop.machine1"
+ send_interface="org.freedesktop.machine1.Image"
+ send_member="GetOSRelease"/>
+
<allow receive_sender="org.freedesktop.machine1"/>
</policy>
diff --git a/src/modules-load/modules-load.c b/src/modules-load/modules-load.c
index 0901fea8dc..615998a6f6 100644
--- a/src/modules-load/modules-load.c
+++ b/src/modules-load/modules-load.c
@@ -62,7 +62,11 @@ static int add_modules(const char *p) {
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
int r;
- if (streq(key, "modules-load") && value) {
+ if (proc_cmdline_key_streq(key, "modules_load")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
r = add_modules(value);
if (r < 0)
return r;
@@ -226,7 +230,7 @@ int main(int argc, char *argv[]) {
umask(0022);
- r = parse_proc_cmdline(parse_proc_cmdline_item, NULL, true);
+ r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
if (r < 0)
log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c
index 80bba086e4..b709166aa9 100644
--- a/src/mount/mount-tool.c
+++ b/src/mount/mount-tool.c
@@ -40,6 +40,7 @@ enum {
ACTION_DEFAULT,
ACTION_MOUNT,
ACTION_AUTOMOUNT,
+ ACTION_UMOUNT,
ACTION_LIST,
} arg_action = ACTION_DEFAULT;
@@ -99,6 +100,7 @@ static void help(void) {
" Set automount unit property\n"
" --bind-device Bind automount unit to device\n"
" --list List mountable block devices\n"
+ " -u --umount Unmount mount points\n"
, program_invocation_short_name);
}
@@ -137,6 +139,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "discover", no_argument, NULL, ARG_DISCOVER },
{ "type", required_argument, NULL, 't' },
{ "options", required_argument, NULL, 'o' },
+ { "fsck", required_argument, NULL, ARG_FSCK },
{ "description", required_argument, NULL, ARG_DESCRIPTION },
{ "property", required_argument, NULL, 'p' },
{ "automount", required_argument, NULL, ARG_AUTOMOUNT },
@@ -144,6 +147,8 @@ static int parse_argv(int argc, char *argv[]) {
{ "automount-property", required_argument, NULL, ARG_AUTOMOUNT_PROPERTY },
{ "bind-device", no_argument, NULL, ARG_BIND_DEVICE },
{ "list", no_argument, NULL, ARG_LIST },
+ { "umount", no_argument, NULL, 'u' },
+ { "unmount", no_argument, NULL, 'u' },
{},
};
@@ -152,7 +157,10 @@ static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "hqH:M:t:o:p:A", options, NULL)) >= 0)
+ if (strstr(program_invocation_short_name, "systemd-umount"))
+ arg_action = ACTION_UMOUNT;
+
+ while ((c = getopt_long(argc, argv, "hqH:M:t:o:p:Au", options, NULL)) >= 0)
switch (c) {
@@ -263,6 +271,10 @@ static int parse_argv(int argc, char *argv[]) {
arg_action = ACTION_LIST;
break;
+ case 'u':
+ arg_action = ACTION_UMOUNT;
+ break;
+
case '?':
return -EINVAL;
@@ -607,6 +619,89 @@ static int start_transient_automount(
return 0;
}
+static int stop_mount(
+ sd_bus *bus,
+ char **argv,
+ const char *suffix) {
+
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
+ _cleanup_free_ char *mount_unit = NULL;
+ int r;
+
+ if (!arg_no_block) {
+ r = bus_wait_for_jobs_new(bus, &w);
+ if (r < 0)
+ return log_error_errno(r, "Could not watch jobs: %m");
+ }
+
+ r = unit_name_from_path(arg_mount_where, suffix, &mount_unit);
+ if (r < 0)
+ return log_error_errno(r, "Failed to make mount unit name: %m");
+
+ r = sd_bus_message_new_method_call(
+ bus,
+ &m,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "StopUnit");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ /* Name and mode */
+ r = sd_bus_message_append(m, "ss", mount_unit, "fail");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ polkit_agent_open_if_enabled();
+
+ r = sd_bus_call(bus, m, 0, &error, &reply);
+ if (r < 0)
+ return log_error_errno(r, "Failed to stop mount unit: %s", bus_error_message(&error, r));
+
+ if (w) {
+ const char *object;
+
+ r = sd_bus_message_read(reply, "o", &object);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ r = bus_wait_for_jobs_one(w, object, arg_quiet);
+ if (r < 0)
+ return r;
+ }
+
+ if (!arg_quiet)
+ log_info("Stopped unit %s%s%s for mount point: %s%s%s",
+ ansi_highlight(), mount_unit, ansi_normal(),
+ ansi_highlight(), arg_mount_where, ansi_normal());
+
+ return 0;
+}
+
+static int stop_mounts(
+ sd_bus *bus,
+ char **argv) {
+
+ int r;
+
+ r = stop_mount(bus, argv + optind, ".mount");
+ if (r < 0)
+ return r;
+
+ r = stop_mount(bus, argv + optind, ".automount");
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+
static int acquire_mount_type(struct udev_device *d) {
const char *v;
@@ -697,7 +792,7 @@ static int acquire_mount_where(struct udev_device *d) {
if (!filename_is_valid(escaped))
return 0;
- arg_mount_where = strjoin("/run/media/system/", escaped, NULL);
+ arg_mount_where = strjoin("/run/media/system/", escaped);
} else
arg_mount_where = strdup(v);
@@ -721,7 +816,7 @@ static int acquire_description(struct udev_device *d) {
label = udev_device_get_property_value(d, "ID_PART_ENTRY_NUMBER");
if (model && label)
- arg_description = strjoin(model, " ", label, NULL);
+ arg_description = strjoin(model, " ", label);
else if (label)
arg_description = strdup(label);
else if (model)
@@ -930,7 +1025,7 @@ static int list_devices(void) {
j = items + n++;
for (c = 0; c < _COLUMN_MAX; c++) {
- const char *x;
+ const char *x = NULL;
size_t k;
switch (c) {
@@ -1093,6 +1188,10 @@ int main(int argc, char* argv[]) {
r = start_transient_automount(bus, argv + optind);
break;
+ case ACTION_UMOUNT:
+ r = stop_mounts(bus, argv + optind);
+ break;
+
default:
assert_not_reached("Unexpected action.");
}
diff --git a/src/network/.gitignore b/src/network/.gitignore
index aca55206b7..230671763d 100644
--- a/src/network/.gitignore
+++ b/src/network/.gitignore
@@ -1,3 +1,2 @@
/networkd-network-gperf.c
-/networkd-netdev-gperf.c
/networkd-gperf.c
diff --git a/src/network/netdev/.gitignore b/src/network/netdev/.gitignore
new file mode 100644
index 0000000000..0f1a65d2e6
--- /dev/null
+++ b/src/network/netdev/.gitignore
@@ -0,0 +1 @@
+/netdev-gperf.c
diff --git a/src/network/netdev/Makefile b/src/network/netdev/Makefile
new file mode 120000
index 0000000000..94aaae2c4d
--- /dev/null
+++ b/src/network/netdev/Makefile
@@ -0,0 +1 @@
+../../Makefile \ No newline at end of file
diff --git a/src/network/networkd-netdev-bond.c b/src/network/netdev/bond.c
index 46d1669337..19b0e8da40 100644
--- a/src/network/networkd-netdev-bond.c
+++ b/src/network/netdev/bond.c
@@ -27,7 +27,7 @@
#include "conf-parser.h"
#include "extract-word.h"
#include "missing.h"
-#include "networkd-netdev-bond.h"
+#include "netdev/bond.h"
#include "string-table.h"
#include "string-util.h"
diff --git a/src/network/networkd-netdev-bond.h b/src/network/netdev/bond.h
index b941edb344..fb88b538ed 100644
--- a/src/network/networkd-netdev-bond.h
+++ b/src/network/netdev/bond.h
@@ -22,7 +22,7 @@
#include "in-addr-util.h"
#include "list.h"
-#include "networkd-netdev.h"
+#include "netdev/netdev.h"
/*
* Maximum number of targets supported by the kernel for a single
diff --git a/src/network/networkd-netdev-bridge.c b/src/network/netdev/bridge.c
index 002ad94210..9fdcb55376 100644
--- a/src/network/networkd-netdev-bridge.c
+++ b/src/network/netdev/bridge.c
@@ -22,8 +22,8 @@
#include "missing.h"
#include "netlink-util.h"
-#include "networkd.h"
-#include "networkd-netdev-bridge.h"
+#include "netdev/bridge.h"
+#include "networkd-manager.h"
/* callback for brige netdev's parameter set */
static int netdev_bridge_set_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
@@ -72,7 +72,7 @@ static int netdev_bridge_post_create(NetDev *netdev, Link *link, sd_netlink_mess
return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m");
/* convert to jiffes */
- if (b->forward_delay > 0) {
+ if (b->forward_delay != USEC_INFINITY) {
r = sd_netlink_message_append_u32(req, IFLA_BR_FORWARD_DELAY, usec_to_jiffies(b->forward_delay));
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_FORWARD_DELAY attribute: %m");
@@ -160,6 +160,7 @@ static void bridge_init(NetDev *n) {
b->mcast_snooping = -1;
b->vlan_filtering = -1;
b->stp = -1;
+ b->forward_delay = USEC_INFINITY;
}
const NetDevVTable bridge_vtable = {
diff --git a/src/network/networkd-netdev-bridge.h b/src/network/netdev/bridge.h
index 53f72f1ea5..093c60d5b5 100644
--- a/src/network/networkd-netdev-bridge.h
+++ b/src/network/netdev/bridge.h
@@ -19,7 +19,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "networkd-netdev.h"
+#include "netdev/netdev.h"
typedef struct Bridge {
NetDev meta;
diff --git a/src/network/networkd-netdev-dummy.c b/src/network/netdev/dummy.c
index 6617a86c20..5e6e162931 100644
--- a/src/network/networkd-netdev-dummy.c
+++ b/src/network/netdev/dummy.c
@@ -19,7 +19,7 @@
***/
-#include "networkd-netdev-dummy.h"
+#include "netdev/dummy.h"
const NetDevVTable dummy_vtable = {
.object_size = sizeof(Dummy),
diff --git a/src/network/networkd-netdev-dummy.h b/src/network/netdev/dummy.h
index efe302267e..a908400459 100644
--- a/src/network/networkd-netdev-dummy.h
+++ b/src/network/netdev/dummy.h
@@ -19,7 +19,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "networkd-netdev.h"
+#include "netdev/netdev.h"
typedef struct Dummy {
NetDev meta;
diff --git a/src/network/networkd-netdev-ipvlan.c b/src/network/netdev/ipvlan.c
index af4177e43a..3b5c30fed8 100644
--- a/src/network/networkd-netdev-ipvlan.c
+++ b/src/network/netdev/ipvlan.c
@@ -20,7 +20,7 @@
#include <net/if.h>
#include "conf-parser.h"
-#include "networkd-netdev-ipvlan.h"
+#include "netdev/ipvlan.h"
#include "string-table.h"
static const char* const ipvlan_mode_table[_NETDEV_IPVLAN_MODE_MAX] = {
diff --git a/src/network/networkd-netdev-ipvlan.h b/src/network/netdev/ipvlan.h
index 10d4079844..7d7d0184f1 100644
--- a/src/network/networkd-netdev-ipvlan.h
+++ b/src/network/netdev/ipvlan.h
@@ -20,7 +20,7 @@
***/
#include "missing.h"
-#include "networkd-netdev.h"
+#include "netdev/netdev.h"
typedef enum IPVlanMode {
NETDEV_IPVLAN_MODE_L2 = IPVLAN_MODE_L2,
diff --git a/src/network/networkd-netdev-macvlan.c b/src/network/netdev/macvlan.c
index 48e98aa51b..93f650def5 100644
--- a/src/network/networkd-netdev-macvlan.c
+++ b/src/network/netdev/macvlan.c
@@ -20,7 +20,7 @@
#include <net/if.h>
#include "conf-parser.h"
-#include "networkd-netdev-macvlan.h"
+#include "netdev/macvlan.h"
#include "string-table.h"
static const char* const macvlan_mode_table[_NETDEV_MACVLAN_MODE_MAX] = {
diff --git a/src/network/networkd-netdev-macvlan.h b/src/network/netdev/macvlan.h
index 3663f4f051..118d55658c 100644
--- a/src/network/networkd-netdev-macvlan.h
+++ b/src/network/netdev/macvlan.h
@@ -21,7 +21,7 @@
typedef struct MacVlan MacVlan;
-#include "networkd-netdev.h"
+#include "netdev/netdev.h"
typedef enum MacVlanMode {
NETDEV_MACVLAN_MODE_PRIVATE = MACVLAN_MODE_PRIVATE,
diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf
new file mode 100644
index 0000000000..e19fa9817e
--- /dev/null
+++ b/src/network/netdev/netdev-gperf.gperf
@@ -0,0 +1,121 @@
+%{
+#include <stddef.h>
+#include "conf-parser.h"
+#include "network-internal.h"
+#include "netdev/bond.h"
+#include "netdev/bridge.h"
+#include "netdev/ipvlan.h"
+#include "netdev/macvlan.h"
+#include "netdev/tunnel.h"
+#include "netdev/tuntap.h"
+#include "netdev/veth.h"
+#include "netdev/vlan.h"
+#include "netdev/vxlan.h"
+#include "netdev/vrf.h"
+#include "netdev/netdev.h"
+#include "vlan-util.h"
+%}
+struct ConfigPerfItem;
+%null_strings
+%language=ANSI-C
+%define slot-name section_and_lvalue
+%define hash-function-name network_netdev_gperf_hash
+%define lookup-function-name network_netdev_gperf_lookup
+%readonly-tables
+%omit-struct-type
+%struct-type
+%includes
+%%
+Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(NetDev, match_host)
+Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(NetDev, match_virt)
+Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(NetDev, match_kernel)
+Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(NetDev, match_arch)
+NetDev.Description, config_parse_string, 0, offsetof(NetDev, description)
+NetDev.Name, config_parse_ifname, 0, offsetof(NetDev, ifname)
+NetDev.Kind, config_parse_netdev_kind, 0, offsetof(NetDev, kind)
+NetDev.MTUBytes, config_parse_iec_size, 0, offsetof(NetDev, mtu)
+NetDev.MACAddress, config_parse_hwaddr, 0, offsetof(NetDev, mac)
+VLAN.Id, config_parse_vlanid, 0, offsetof(VLan, id)
+MACVLAN.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode)
+MACVTAP.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode)
+IPVLAN.Mode, config_parse_ipvlan_mode, 0, offsetof(IPVlan, mode)
+Tunnel.Local, config_parse_tunnel_address, 0, offsetof(Tunnel, local)
+Tunnel.Remote, config_parse_tunnel_address, 0, offsetof(Tunnel, remote)
+Tunnel.TOS, config_parse_unsigned, 0, offsetof(Tunnel, tos)
+Tunnel.TTL, config_parse_unsigned, 0, offsetof(Tunnel, ttl)
+Tunnel.Key, config_parse_tunnel_key, 0, offsetof(Tunnel, key)
+Tunnel.InputKey, config_parse_tunnel_key, 0, offsetof(Tunnel, ikey)
+Tunnel.OutputKey, config_parse_tunnel_key, 0, offsetof(Tunnel, okey)
+Tunnel.DiscoverPathMTU, config_parse_bool, 0, offsetof(Tunnel, pmtudisc)
+Tunnel.Mode, config_parse_ip6tnl_mode, 0, offsetof(Tunnel, ip6tnl_mode)
+Tunnel.IPv6FlowLabel, config_parse_ipv6_flowlabel, 0, offsetof(Tunnel, ipv6_flowlabel)
+Tunnel.CopyDSCP, config_parse_bool, 0, offsetof(Tunnel, copy_dscp)
+Tunnel.EncapsulationLimit, config_parse_encap_limit, 0, offsetof(Tunnel, encap_limit)
+Peer.Name, config_parse_ifname, 0, offsetof(Veth, ifname_peer)
+Peer.MACAddress, config_parse_hwaddr, 0, offsetof(Veth, mac_peer)
+VXLAN.Id, config_parse_uint64, 0, offsetof(VxLan, id)
+VXLAN.Group, config_parse_vxlan_address, 0, offsetof(VxLan, remote)
+VXLAN.Local, config_parse_vxlan_address, 0, offsetof(VxLan, local)
+VXLAN.Remote, config_parse_vxlan_address, 0, offsetof(VxLan, remote)
+VXLAN.TOS, config_parse_unsigned, 0, offsetof(VxLan, tos)
+VXLAN.TTL, config_parse_unsigned, 0, offsetof(VxLan, ttl)
+VXLAN.MacLearning, config_parse_bool, 0, offsetof(VxLan, learning)
+VXLAN.ARPProxy, config_parse_bool, 0, offsetof(VxLan, arp_proxy)
+VXLAN.ReduceARPProxy, config_parse_bool, 0, offsetof(VxLan, arp_proxy)
+VXLAN.L2MissNotification, config_parse_bool, 0, offsetof(VxLan, l2miss)
+VXLAN.L3MissNotification, config_parse_bool, 0, offsetof(VxLan, l3miss)
+VXLAN.RouteShortCircuit, config_parse_bool, 0, offsetof(VxLan, route_short_circuit)
+VXLAN.UDPCheckSum, config_parse_bool, 0, offsetof(VxLan, udpcsum)
+VXLAN.UDPChecksum, config_parse_bool, 0, offsetof(VxLan, udpcsum)
+VXLAN.UDP6ZeroCheckSumRx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumrx)
+VXLAN.UDP6ZeroChecksumRx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumrx)
+VXLAN.UDP6ZeroCheckSumTx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumtx)
+VXLAN.UDP6ZeroChecksumTx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumtx)
+VXLAN.RemoteChecksumTx, config_parse_bool, 0, offsetof(VxLan, remote_csum_tx)
+VXLAN.RemoteChecksumRx, config_parse_bool, 0, offsetof(VxLan, remote_csum_rx)
+VXLAN.FDBAgeingSec, config_parse_sec, 0, offsetof(VxLan, fdb_ageing)
+VXLAN.GroupPolicyExtension, config_parse_bool, 0, offsetof(VxLan, group_policy)
+VXLAN.MaximumFDBEntries, config_parse_unsigned, 0, offsetof(VxLan, max_fdb)
+VXLAN.PortRange, config_parse_port_range, 0, 0
+VXLAN.DestinationPort, config_parse_destination_port, 0, offsetof(VxLan, dest_port)
+Tun.OneQueue, config_parse_bool, 0, offsetof(TunTap, one_queue)
+Tun.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue)
+Tun.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info)
+Tun.User, config_parse_string, 0, offsetof(TunTap, user_name)
+Tun.Group, config_parse_string, 0, offsetof(TunTap, group_name)
+Tap.OneQueue, config_parse_bool, 0, offsetof(TunTap, one_queue)
+Tap.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue)
+Tap.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info)
+Tap.VNetHeader, config_parse_bool, 0, offsetof(TunTap, vnet_hdr)
+Tap.User, config_parse_string, 0, offsetof(TunTap, user_name)
+Tap.Group, config_parse_string, 0, offsetof(TunTap, group_name)
+Bond.Mode, config_parse_bond_mode, 0, offsetof(Bond, mode)
+Bond.TransmitHashPolicy, config_parse_bond_xmit_hash_policy, 0, offsetof(Bond, xmit_hash_policy)
+Bond.LACPTransmitRate, config_parse_bond_lacp_rate, 0, offsetof(Bond, lacp_rate)
+Bond.AdSelect, config_parse_bond_ad_select, 0, offsetof(Bond, ad_select)
+Bond.FailOverMACPolicy, config_parse_bond_fail_over_mac, 0, offsetof(Bond, fail_over_mac)
+Bond.ARPIPTargets, config_parse_arp_ip_target_address, 0, 0
+Bond.ARPValidate, config_parse_bond_arp_validate, 0, offsetof(Bond, arp_validate)
+Bond.ARPAllTargets, config_parse_bond_arp_all_targets, 0, offsetof(Bond, arp_all_targets)
+Bond.PrimaryReselectPolicy, config_parse_bond_primary_reselect, 0, offsetof(Bond, primary_reselect)
+Bond.ResendIGMP, config_parse_unsigned, 0, offsetof(Bond, resend_igmp)
+Bond.PacketsPerSlave, config_parse_unsigned, 0, offsetof(Bond, packets_per_slave)
+Bond.GratuitousARP, config_parse_unsigned, 0, offsetof(Bond, num_grat_arp)
+Bond.AllSlavesActive, config_parse_unsigned, 0, offsetof(Bond, all_slaves_active)
+Bond.MinLinks, config_parse_unsigned, 0, offsetof(Bond, min_links)
+Bond.MIIMonitorSec, config_parse_sec, 0, offsetof(Bond, miimon)
+Bond.UpDelaySec, config_parse_sec, 0, offsetof(Bond, updelay)
+Bond.DownDelaySec, config_parse_sec, 0, offsetof(Bond, downdelay)
+Bond.ARPIntervalSec, config_parse_sec, 0, offsetof(Bond, arp_interval)
+Bond.LearnPacketIntervalSec, config_parse_sec, 0, offsetof(Bond, lp_interval)
+Bridge.HelloTimeSec, config_parse_sec, 0, offsetof(Bridge, hello_time)
+Bridge.MaxAgeSec, config_parse_sec, 0, offsetof(Bridge, max_age)
+Bridge.AgeingTimeSec, config_parse_sec, 0, offsetof(Bridge, ageing_time)
+Bridge.ForwardDelaySec, config_parse_sec, 0, offsetof(Bridge, forward_delay)
+Bridge.Priority, config_parse_uint16, 0, offsetof(Bridge, priority)
+Bridge.DefaultPVID, config_parse_vlanid, 0, offsetof(Bridge, default_pvid)
+Bridge.MulticastQuerier, config_parse_tristate, 0, offsetof(Bridge, mcast_querier)
+Bridge.MulticastSnooping, config_parse_tristate, 0, offsetof(Bridge, mcast_snooping)
+Bridge.VLANFiltering, config_parse_tristate, 0, offsetof(Bridge, vlan_filtering)
+Bridge.STP, config_parse_tristate, 0, offsetof(Bridge, stp)
+VRF.TableId, config_parse_uint32, 0, offsetof(Vrf, table_id)
diff --git a/src/network/networkd-netdev.c b/src/network/netdev/netdev.c
index a210ba1242..f70117e6f9 100644
--- a/src/network/networkd-netdev.c
+++ b/src/network/netdev/netdev.c
@@ -26,13 +26,27 @@
#include "list.h"
#include "netlink-util.h"
#include "network-internal.h"
-#include "networkd-netdev.h"
-#include "networkd.h"
+#include "netdev/netdev.h"
+#include "networkd-manager.h"
+#include "networkd-link.h"
#include "siphash24.h"
#include "stat-util.h"
#include "string-table.h"
#include "string-util.h"
+#include "netdev/bridge.h"
+#include "netdev/bond.h"
+#include "netdev/vlan.h"
+#include "netdev/macvlan.h"
+#include "netdev/ipvlan.h"
+#include "netdev/vxlan.h"
+#include "netdev/tunnel.h"
+#include "netdev/tuntap.h"
+#include "netdev/veth.h"
+#include "netdev/dummy.h"
+#include "netdev/vrf.h"
+#include "netdev/vcan.h"
+
const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = {
[NETDEV_KIND_BRIDGE] = &bridge_vtable,
[NETDEV_KIND_BOND] = &bond_vtable,
@@ -205,6 +219,13 @@ static int netdev_enslave_ready(NetDev *netdev, Link* link, sd_netlink_message_h
assert(link);
assert(callback);
+ if (link->flags & IFF_UP) {
+ log_netdev_debug(netdev, "Link '%s' was up when attempting to enslave it. Bringing link down.", link->ifname);
+ r = link_down(link);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not bring link down: %m");
+ }
+
r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not allocate RTM_SETLINK message: %m");
diff --git a/src/network/networkd-netdev.h b/src/network/netdev/netdev.h
index 37c7431213..37c7431213 100644
--- a/src/network/networkd-netdev.h
+++ b/src/network/netdev/netdev.h
diff --git a/src/network/networkd-netdev-tunnel.c b/src/network/netdev/tunnel.c
index 9138ee4511..67f4fab400 100644
--- a/src/network/networkd-netdev-tunnel.c
+++ b/src/network/netdev/tunnel.c
@@ -28,7 +28,7 @@
#include "conf-parser.h"
#include "missing.h"
#include "networkd-link.h"
-#include "networkd-netdev-tunnel.h"
+#include "netdev/tunnel.h"
#include "parse-util.h"
#include "string-table.h"
#include "string-util.h"
@@ -397,16 +397,31 @@ static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
assert(t);
- if (t->family != AF_INET && t->family != AF_INET6 && t->family != 0) {
- log_warning("Tunnel with invalid address family configured in %s. Ignoring", filename);
+ if (!IN_SET(t->family, AF_INET, AF_INET6, AF_UNSPEC)) {
+ log_netdev_error(netdev,
+ "Tunnel with invalid address family configured in %s. Ignoring", filename);
return -EINVAL;
}
- if (netdev->kind == NETDEV_KIND_IP6TNL) {
- if (t->ip6tnl_mode == _NETDEV_IP6_TNL_MODE_INVALID) {
- log_warning("IP6 Tunnel without mode configured in %s. Ignoring", filename);
- return -EINVAL;
- }
+ if (netdev->kind == NETDEV_KIND_VTI &&
+ (t->family != AF_INET || in_addr_is_null(t->family, &t->local))) {
+ log_netdev_error(netdev,
+ "vti tunnel without a local IPv4 address configured in %s. Ignoring", filename);
+ return -EINVAL;
+ }
+
+ if (IN_SET(netdev->kind, NETDEV_KIND_VTI6, NETDEV_KIND_IP6TNL, NETDEV_KIND_IP6GRE) &&
+ (t->family != AF_INET6 || in_addr_is_null(t->family, &t->local))) {
+ log_netdev_error(netdev,
+ "vti6/ip6tnl/ip6gre tunnel without a local IPv6 address configured in %s. Ignoring", filename);
+ return -EINVAL;
+ }
+
+ if (netdev->kind == NETDEV_KIND_IP6TNL &&
+ t->ip6tnl_mode == _NETDEV_IP6_TNL_MODE_INVALID) {
+ log_netdev_error(netdev,
+ "ip6tnl without mode configured in %s. Ignoring", filename);
+ return -EINVAL;
}
return 0;
@@ -431,26 +446,40 @@ int config_parse_tunnel_address(const char *unit,
assert(rvalue);
assert(data);
+ /* This is used to parse addresses on both local and remote ends of the tunnel.
+ * Address families must match.
+ *
+ * "any" is a special value which means that the address is unspecified.
+ */
+
if (streq(rvalue, "any")) {
- t->family = 0;
+ *addr = IN_ADDR_NULL;
+
+ /* As a special case, if both the local and remote addresses are
+ * unspecified, also clear the address family.
+ */
+ if (t->family != AF_UNSPEC &&
+ in_addr_is_null(t->family, &t->local) &&
+ in_addr_is_null(t->family, &t->remote))
+ t->family = AF_UNSPEC;
return 0;
- } else {
+ }
- r = in_addr_from_string_auto(rvalue, &f, &buffer);
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Tunnel address is invalid, ignoring assignment: %s", rvalue);
- return 0;
- }
+ r = in_addr_from_string_auto(rvalue, &f, &buffer);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Tunnel address \"%s\" invalid, ignoring assignment: %m", rvalue);
+ return 0;
+ }
- if (t->family != AF_UNSPEC && t->family != f) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Tunnel addresses incompatible, ignoring assignment: %s", rvalue);
- return 0;
- }
+ if (t->family != AF_UNSPEC && t->family != f) {
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Tunnel addresses incompatible, ignoring assignment: %s", rvalue);
+ return 0;
}
t->family = f;
*addr = buffer;
-
return 0;
}
@@ -578,7 +607,6 @@ static void ipip_init(NetDev *n) {
assert(t);
t->pmtudisc = true;
- t->family = AF_UNSPEC;
}
static void sit_init(NetDev *n) {
@@ -588,7 +616,6 @@ static void sit_init(NetDev *n) {
assert(t);
t->pmtudisc = true;
- t->family = AF_UNSPEC;
}
static void vti_init(NetDev *n) {
@@ -619,7 +646,6 @@ static void gre_init(NetDev *n) {
assert(t);
t->pmtudisc = true;
- t->family = AF_UNSPEC;
}
static void ip6gre_init(NetDev *n) {
diff --git a/src/network/networkd-netdev-tunnel.h b/src/network/netdev/tunnel.h
index 32a46bd82f..d78c6135ee 100644
--- a/src/network/networkd-netdev-tunnel.h
+++ b/src/network/netdev/tunnel.h
@@ -21,7 +21,7 @@
#include "in-addr-util.h"
-#include "networkd-netdev.h"
+#include "netdev/netdev.h"
typedef enum Ip6TnlMode {
NETDEV_IP6_TNL_MODE_IP6IP6,
diff --git a/src/network/networkd-netdev-tuntap.c b/src/network/netdev/tuntap.c
index 088a4d8d32..3d62808842 100644
--- a/src/network/networkd-netdev-tuntap.c
+++ b/src/network/netdev/tuntap.c
@@ -27,7 +27,7 @@
#include "alloc-util.h"
#include "fd-util.h"
-#include "networkd-netdev-tuntap.h"
+#include "netdev/tuntap.h"
#include "user-util.h"
#define TUN_DEV "/dev/net/tun"
diff --git a/src/network/networkd-netdev-tuntap.h b/src/network/netdev/tuntap.h
index 120f00a353..95d3fcf1e9 100644
--- a/src/network/networkd-netdev-tuntap.h
+++ b/src/network/netdev/tuntap.h
@@ -21,7 +21,7 @@
typedef struct TunTap TunTap;
-#include "networkd-netdev.h"
+#include "netdev/netdev.h"
struct TunTap {
NetDev meta;
diff --git a/src/network/networkd-netdev-vcan.c b/src/network/netdev/vcan.c
index bfce6e1962..7f56702938 100644
--- a/src/network/networkd-netdev-vcan.c
+++ b/src/network/netdev/vcan.c
@@ -17,7 +17,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "networkd-netdev-vcan.h"
+#include "netdev/vcan.h"
const NetDevVTable vcan_vtable = {
.object_size = sizeof(VCan),
diff --git a/src/network/networkd-netdev-vcan.h b/src/network/netdev/vcan.h
index 6ba47fd70e..00838b7675 100644
--- a/src/network/networkd-netdev-vcan.h
+++ b/src/network/netdev/vcan.h
@@ -23,7 +23,7 @@ typedef struct VCan VCan;
#include <linux/can/netlink.h>
-#include "networkd-netdev.h"
+#include "netdev/netdev.h"
struct VCan {
NetDev meta;
diff --git a/src/network/networkd-netdev-veth.c b/src/network/netdev/veth.c
index b122a06c25..350b59bf03 100644
--- a/src/network/networkd-netdev-veth.c
+++ b/src/network/netdev/veth.c
@@ -22,7 +22,7 @@
#include "sd-netlink.h"
-#include "networkd-netdev-veth.h"
+#include "netdev/veth.h"
static int netdev_veth_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
Veth *v;
diff --git a/src/network/networkd-netdev-veth.h b/src/network/netdev/veth.h
index e69bfbc8f0..b00ce476e8 100644
--- a/src/network/networkd-netdev-veth.h
+++ b/src/network/netdev/veth.h
@@ -21,7 +21,7 @@
typedef struct Veth Veth;
-#include "networkd-netdev.h"
+#include "netdev/netdev.h"
struct Veth {
NetDev meta;
diff --git a/src/network/networkd-netdev-vlan.c b/src/network/netdev/vlan.c
index 3cc072388f..28c061fa4f 100644
--- a/src/network/networkd-netdev-vlan.c
+++ b/src/network/netdev/vlan.c
@@ -19,7 +19,7 @@
#include <net/if.h>
-#include "networkd-netdev-vlan.h"
+#include "netdev/vlan.h"
#include "vlan-util.h"
static int netdev_vlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *req) {
diff --git a/src/network/networkd-netdev-vlan.h b/src/network/netdev/vlan.h
index 2dfe314b6e..fade899997 100644
--- a/src/network/networkd-netdev-vlan.h
+++ b/src/network/netdev/vlan.h
@@ -21,7 +21,7 @@
typedef struct VLan VLan;
-#include "networkd-netdev.h"
+#include "netdev/netdev.h"
struct VLan {
NetDev meta;
diff --git a/src/network/networkd-netdev-vrf.c b/src/network/netdev/vrf.c
index 89bd142e8c..f48b413102 100644
--- a/src/network/networkd-netdev-vrf.c
+++ b/src/network/netdev/vrf.c
@@ -21,7 +21,7 @@
#include "sd-netlink.h"
#include "missing.h"
-#include "networkd-netdev-vrf.h"
+#include "netdev/vrf.h"
static int netdev_vrf_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
Vrf *v;
diff --git a/src/network/networkd-netdev-vrf.h b/src/network/netdev/vrf.h
index 3d92a26a4d..00f54ed96d 100644
--- a/src/network/networkd-netdev-vrf.h
+++ b/src/network/netdev/vrf.h
@@ -21,7 +21,7 @@
typedef struct Vrf Vrf;
-#include "networkd-netdev.h"
+#include "netdev/netdev.h"
struct Vrf {
NetDev meta;
diff --git a/src/network/networkd-netdev-vxlan.c b/src/network/netdev/vxlan.c
index 706e52b698..b677b000fd 100644
--- a/src/network/networkd-netdev-vxlan.c
+++ b/src/network/netdev/vxlan.c
@@ -24,11 +24,13 @@
#include "conf-parser.h"
#include "alloc-util.h"
#include "extract-word.h"
+#include "string-util.h"
+#include "strv.h"
#include "parse-util.h"
#include "missing.h"
#include "networkd-link.h"
-#include "networkd-netdev-vxlan.h"
+#include "netdev/vxlan.h"
static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
VxLan *v;
@@ -48,9 +50,29 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netli
return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_ID attribute: %m");
}
- r = sd_netlink_message_append_in_addr(m, IFLA_VXLAN_GROUP, &v->group.in);
- if (r < 0)
- return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_GROUP attribute: %m");
+ if (!in_addr_is_null(v->remote_family, &v->remote)) {
+
+ if (v->remote_family == AF_INET)
+ r = sd_netlink_message_append_in_addr(m, IFLA_VXLAN_GROUP, &v->remote.in);
+ else
+ r = sd_netlink_message_append_in6_addr(m, IFLA_VXLAN_GROUP6, &v->remote.in6);
+
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_GROUP attribute: %m");
+
+ }
+
+ if (!in_addr_is_null(v->local_family, &v->local)) {
+
+ if (v->local_family == AF_INET)
+ r = sd_netlink_message_append_in_addr(m, IFLA_VXLAN_LOCAL, &v->local.in);
+ else
+ r = sd_netlink_message_append_in6_addr(m, IFLA_VXLAN_LOCAL6, &v->local.in6);
+
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_LOCAL attribute: %m");
+
+ }
r = sd_netlink_message_append_u32(m, IFLA_VXLAN_LINK, link->ifindex);
if (r < 0)
@@ -144,16 +166,16 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netli
return r;
}
-int config_parse_vxlan_group_address(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
+int config_parse_vxlan_address(const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
VxLan *v = userdata;
union in_addr_union *addr = data, buffer;
int r, f;
@@ -165,16 +187,28 @@ int config_parse_vxlan_group_address(const char *unit,
r = in_addr_from_string_auto(rvalue, &f, &buffer);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "vxlan multicast group address is invalid, ignoring assignment: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "vxlan '%s' address is invalid, ignoring assignment: %s", lvalue, rvalue);
return 0;
}
- if (v->family != AF_UNSPEC && v->family != f) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "vxlan multicast group incompatible, ignoring assignment: %s", rvalue);
- return 0;
+ r = in_addr_is_multicast(f, &buffer);
+
+ if (STR_IN_SET(lvalue, "Group", "Remote")) {
+ if (r <= 0) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "vxlan invalid multicast '%s' address, ignoring assignment: %s", lvalue, rvalue);
+ return 0;
+ }
+
+ v->remote_family = f;
+ } else {
+ if (r > 0) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "vxlan %s can not be multicast address, ignoring assignment: %s", lvalue, rvalue);
+ return 0;
+ }
+
+ v->local_family = f;
}
- v->family = f;
*addr = buffer;
return 0;
@@ -252,8 +286,8 @@ int config_parse_destination_port(const char *unit,
assert(rvalue);
assert(data);
- r = safe_atou16(rvalue, &port);
- if (r < 0 || port <= 0) {
+ r = parse_ip_port(rvalue, &port);
+ if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse VXLAN destination port '%s'.", rvalue);
return 0;
}
diff --git a/src/network/networkd-netdev-vxlan.h b/src/network/netdev/vxlan.h
index 3906820afb..dca58e7fe6 100644
--- a/src/network/networkd-netdev-vxlan.h
+++ b/src/network/netdev/vxlan.h
@@ -22,7 +22,7 @@
typedef struct VxLan VxLan;
#include "in-addr-util.h"
-#include "networkd-netdev.h"
+#include "netdev/netdev.h"
#define VXLAN_VID_MAX (1u << 24) - 1
@@ -31,8 +31,11 @@ struct VxLan {
uint64_t id;
- int family;
- union in_addr_union group;
+ int remote_family;
+ int local_family;
+
+ union in_addr_union remote;
+ union in_addr_union local;
unsigned tos;
unsigned ttl;
@@ -60,16 +63,16 @@ struct VxLan {
DEFINE_NETDEV_CAST(VXLAN, VxLan);
extern const NetDevVTable vxlan_vtable;
-int config_parse_vxlan_group_address(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata);
+int config_parse_vxlan_address(const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata);
int config_parse_port_range(const char *unit,
const char *filename,
unsigned line,
diff --git a/src/network/networkd-address-pool.c b/src/network/networkd-address-pool.c
index ebc6c9eb9e..a63b925a4a 100644
--- a/src/network/networkd-address-pool.c
+++ b/src/network/networkd-address-pool.c
@@ -19,7 +19,7 @@
#include "alloc-util.h"
#include "networkd-address-pool.h"
-#include "networkd.h"
+#include "networkd-manager.h"
#include "set.h"
#include "string-util.h"
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c
index ed52d5e42d..2e6c763aba 100644
--- a/src/network/networkd-address.c
+++ b/src/network/networkd-address.c
@@ -24,7 +24,7 @@
#include "firewall-util.h"
#include "netlink-util.h"
#include "networkd-address.h"
-#include "networkd.h"
+#include "networkd-manager.h"
#include "parse-util.h"
#include "set.h"
#include "socket-util.h"
@@ -53,15 +53,21 @@ int address_new(Address **ret) {
return 0;
}
-int address_new_static(Network *network, unsigned section, Address **ret) {
+int address_new_static(Network *network, const char *filename, unsigned section_line, Address **ret) {
+ _cleanup_network_config_section_free_ NetworkConfigSection *n = NULL;
_cleanup_address_free_ Address *address = NULL;
int r;
assert(network);
assert(ret);
+ assert(!!filename == (section_line > 0));
- if (section) {
- address = hashmap_get(network->addresses_by_section, UINT_TO_PTR(section));
+ if (filename) {
+ r = network_config_section_new(filename, section_line, &n);
+ if (r < 0)
+ return r;
+
+ address = hashmap_get(network->addresses_by_section, n);
if (address) {
*ret = address;
address = NULL;
@@ -77,9 +83,13 @@ int address_new_static(Network *network, unsigned section, Address **ret) {
if (r < 0)
return r;
- if (section) {
- address->section = section;
- hashmap_put(network->addresses_by_section, UINT_TO_PTR(address->section), address);
+ if (filename) {
+ address->section = n;
+ n = NULL;
+
+ r = hashmap_put(network->addresses_by_section, address->section, address);
+ if (r < 0)
+ return r;
}
address->network = network;
@@ -101,8 +111,10 @@ void address_free(Address *address) {
assert(address->network->n_static_addresses > 0);
address->network->n_static_addresses--;
- if (address->section)
- hashmap_remove(address->network->addresses_by_section, UINT_TO_PTR(address->section));
+ if (address->section) {
+ hashmap_remove(address->network->addresses_by_section, address->section);
+ network_config_section_free(address->section);
+ }
}
if (address->link) {
@@ -676,7 +688,7 @@ int config_parse_broadcast(
assert(rvalue);
assert(data);
- r = address_new_static(network, section_line, &n);
+ r = address_new_static(network, filename, section_line, &n);
if (r < 0)
return r;
@@ -723,10 +735,10 @@ int config_parse_address(const char *unit,
if (streq(section, "Network")) {
/* we are not in an Address section, so treat
* this as the special '0' section */
- section_line = 0;
- }
+ r = address_new_static(network, NULL, 0, &n);
+ } else
+ r = address_new_static(network, filename, section_line, &n);
- r = address_new_static(network, section_line, &n);
if (r < 0)
return r;
@@ -805,12 +817,12 @@ int config_parse_label(
assert(rvalue);
assert(data);
- r = address_new_static(network, section_line, &n);
+ r = address_new_static(network, filename, section_line, &n);
if (r < 0)
return r;
- if (!ifname_valid(rvalue)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Interface label is not valid or too long, ignoring assignment: %s", rvalue);
+ if (!address_label_valid(rvalue)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Interface label is too long or invalid, ignoring assignment: %s", rvalue);
return 0;
}
@@ -844,7 +856,7 @@ int config_parse_lifetime(const char *unit,
assert(rvalue);
assert(data);
- r = address_new_static(network, section_line, &n);
+ r = address_new_static(network, filename, section_line, &n);
if (r < 0)
return r;
@@ -891,7 +903,7 @@ int config_parse_address_flags(const char *unit,
assert(rvalue);
assert(data);
- r = address_new_static(network, section_line, &n);
+ r = address_new_static(network, filename, section_line, &n);
if (r < 0)
return r;
diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h
index bc3b4fc7f3..71a07ea7a3 100644
--- a/src/network/networkd-address.h
+++ b/src/network/networkd-address.h
@@ -33,10 +33,11 @@ typedef struct Address Address;
typedef struct Network Network;
typedef struct Link Link;
+typedef struct NetworkConfigSection NetworkConfigSection;
struct Address {
Network *network;
- unsigned section;
+ NetworkConfigSection *section;
Link *link;
@@ -62,7 +63,7 @@ struct Address {
LIST_FIELDS(Address, addresses);
};
-int address_new_static(Network *network, unsigned section, Address **ret);
+int address_new_static(Network *network, const char *filename, unsigned section, Address **ret);
int address_new(Address **ret);
void address_free(Address *address);
int address_add_foreign(Link *link, int family, const union in_addr_union *in_addr, unsigned char prefixlen, Address **ret);
diff --git a/src/network/networkd-brvlan.c b/src/network/networkd-brvlan.c
index 18ecd86858..fa5d3ee7fa 100644
--- a/src/network/networkd-brvlan.c
+++ b/src/network/networkd-brvlan.c
@@ -25,7 +25,9 @@
#include "conf-parser.h"
#include "netlink-util.h"
#include "networkd-brvlan.h"
-#include "networkd.h"
+#include "networkd-link.h"
+#include "networkd-manager.h"
+#include "networkd-network.h"
#include "parse-util.h"
#include "vlan-util.h"
diff --git a/src/network/networkd-conf.c b/src/network/networkd-conf.c
index 49bb8c18f6..aaa27f311d 100644
--- a/src/network/networkd-conf.c
+++ b/src/network/networkd-conf.c
@@ -22,8 +22,10 @@
#include "conf-parser.h"
#include "def.h"
#include "dhcp-identifier.h"
+#include "extract-word.h"
#include "hexdecoct.h"
#include "networkd-conf.h"
+#include "networkd-network.h"
#include "string-table.h"
int manager_parse_config_file(Manager *m) {
diff --git a/src/network/networkd-conf.h b/src/network/networkd-conf.h
index 00ddb7672a..1136975a5e 100644
--- a/src/network/networkd-conf.h
+++ b/src/network/networkd-conf.h
@@ -19,7 +19,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "networkd.h"
+typedef struct Manager Manager;
int manager_parse_config_file(Manager *m);
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c
index 76d3d132ea..9229b5753c 100644
--- a/src/network/networkd-dhcp4.c
+++ b/src/network/networkd-dhcp4.c
@@ -24,7 +24,9 @@
#include "dhcp-lease-internal.h"
#include "hostname-util.h"
#include "network-internal.h"
-#include "networkd.h"
+#include "networkd-link.h"
+#include "networkd-manager.h"
+#include "networkd-network.h"
static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m,
void *userdata) {
@@ -50,8 +52,21 @@ static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m,
return 1;
}
+static int route_scope_from_address(const Route *route, const struct in_addr *self_addr) {
+ assert(route);
+ assert(self_addr);
+
+ if (in_addr_is_localhost(AF_INET, &route->dst) ||
+ (self_addr->s_addr && route->dst.in.s_addr == self_addr->s_addr))
+ return RT_SCOPE_HOST;
+ else if (in4_addr_is_null(&route->gw.in))
+ return RT_SCOPE_LINK;
+ else
+ return RT_SCOPE_UNIVERSE;
+}
+
static int link_set_dhcp_routes(Link *link) {
- struct in_addr gateway;
+ struct in_addr gateway, address;
_cleanup_free_ sd_dhcp_route **static_routes = NULL;
int r, n, i;
@@ -62,19 +77,18 @@ static int link_set_dhcp_routes(Link *link) {
if (!link->network->dhcp_use_routes)
return 0;
+ r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "DHCP error: could not get address: %m");
+
r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
if (r < 0 && r != -ENODATA)
return log_link_warning_errno(link, r, "DHCP error: could not get gateway: %m");
if (r >= 0) {
- struct in_addr address;
_cleanup_route_free_ Route *route = NULL;
_cleanup_route_free_ Route *route_gw = NULL;
- r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
- if (r < 0)
- return log_link_warning_errno(link, r, "DHCP error: could not get address: %m");
-
r = route_new(&route);
if (r < 0)
return log_link_error_errno(link, r, "Could not allocate route: %m");
@@ -139,6 +153,7 @@ static int link_set_dhcp_routes(Link *link) {
assert_se(sd_dhcp_route_get_destination_prefix_length(static_routes[i], &route->dst_prefixlen) >= 0);
route->priority = link->network->dhcp_route_metric;
route->table = link->network->dhcp_route_table;
+ route->scope = route_scope_from_address(route, &address);
r = route_configure(route, link, dhcp4_route_handler);
if (r < 0)
@@ -253,7 +268,7 @@ static int dhcp_lease_lost(Link *link) {
if (hostname) {
/* If a hostname was set due to the lease, then unset it now. */
- r = link_set_hostname(link, NULL);
+ r = manager_set_hostname(link->manager, NULL);
if (r < 0)
log_link_warning_errno(link, r, "Failed to reset transient hostname: %m");
}
@@ -437,7 +452,7 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
(void) sd_dhcp_lease_get_hostname(lease, &hostname);
if (hostname) {
- r = link_set_hostname(link, hostname);
+ r = manager_set_hostname(link->manager, hostname);
if (r < 0)
log_link_error_errno(link, r, "Failed to set transient hostname to '%s': %m", hostname);
}
@@ -449,7 +464,7 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
(void) sd_dhcp_lease_get_timezone(link->dhcp_lease, &tz);
if (tz) {
- r = link_set_timezone(link, tz);
+ r = manager_set_timezone(link->manager, tz);
if (r < 0)
log_link_error_errno(link, r, "Failed to set timezone to '%s': %m", tz);
}
@@ -534,6 +549,28 @@ static void dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
return;
}
+static int dhcp4_set_hostname(Link *link) {
+ _cleanup_free_ char *hostname = NULL;
+ const char *hn;
+ int r;
+
+ assert(link);
+
+ if (!link->network->dhcp_send_hostname)
+ hn = NULL;
+ else if (link->network->dhcp_hostname)
+ hn = link->network->dhcp_hostname;
+ else {
+ r = gethostname_strict(&hostname);
+ if (r < 0 && r != -ENXIO) /* ENXIO: no hostname set or hostname is "localhost" */
+ return r;
+
+ hn = hostname;
+ }
+
+ return sd_dhcp_client_set_hostname(link->dhcp_client, hn);
+}
+
int dhcp4_configure(Link *link) {
int r;
@@ -603,25 +640,9 @@ int dhcp4_configure(Link *link) {
if (r < 0)
return r;
- if (link->network->dhcp_send_hostname) {
- _cleanup_free_ char *hostname = NULL;
- const char *hn = NULL;
-
- if (!link->network->dhcp_hostname) {
- hostname = gethostname_malloc();
- if (!hostname)
- return -ENOMEM;
-
- hn = hostname;
- } else
- hn = link->network->dhcp_hostname;
-
- if (!is_localhost(hn)) {
- r = sd_dhcp_client_set_hostname(link->dhcp_client, hn);
- if (r < 0)
- return r;
- }
- }
+ r = dhcp4_set_hostname(link);
+ if (r < 0)
+ return r;
if (link->network->dhcp_vendor_class_identifier) {
r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client,
@@ -630,6 +651,12 @@ int dhcp4_configure(Link *link) {
return r;
}
+ if (link->network->dhcp_client_port) {
+ r = sd_dhcp_client_set_client_port(link->dhcp_client, link->network->dhcp_client_port);
+ if (r < 0)
+ return r;
+ }
+
switch (link->network->dhcp_client_identifier) {
case DHCP_CLIENT_ID_DUID: {
/* If configured, apply user specified DUID and/or IAID */
diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c
index 15acf56a5f..6ba2d170e7 100644
--- a/src/network/networkd-dhcp6.c
+++ b/src/network/networkd-dhcp6.c
@@ -23,7 +23,8 @@
#include "sd-dhcp6-client.h"
#include "network-internal.h"
-#include "networkd.h"
+#include "networkd-link.h"
+#include "networkd-manager.h"
static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link);
@@ -125,7 +126,6 @@ static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
assert(link);
assert(link->network);
- assert(link->manager);
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return;
diff --git a/src/network/networkd-fdb.c b/src/network/networkd-fdb.c
index ed5a47589e..3d7f4d2b2d 100644
--- a/src/network/networkd-fdb.c
+++ b/src/network/networkd-fdb.c
@@ -22,9 +22,10 @@
#include "alloc-util.h"
#include "conf-parser.h"
+#include "netdev/bridge.h"
#include "netlink-util.h"
#include "networkd-fdb.h"
-#include "networkd.h"
+#include "networkd-manager.h"
#include "util.h"
#include "vlan-util.h"
diff --git a/src/network/networkd-gperf.gperf b/src/network/networkd-gperf.gperf
index 3fdfe74955..eca436d9fd 100644
--- a/src/network/networkd-gperf.gperf
+++ b/src/network/networkd-gperf.gperf
@@ -2,6 +2,7 @@
#include <stddef.h>
#include "conf-parser.h"
#include "networkd-conf.h"
+#include "networkd-manager.h"
%}
struct ConfigPerfItem;
%null_strings
diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c
index 2d81311e81..7ba05dbec3 100644
--- a/src/network/networkd-ipv4ll.c
+++ b/src/network/networkd-ipv4ll.c
@@ -21,7 +21,9 @@
#include <linux/if.h>
#include "network-internal.h"
-#include "networkd.h"
+#include "networkd-address.h"
+#include "networkd-manager.h"
+#include "networkd-link.h"
static int ipv4ll_address_lost(Link *link) {
_cleanup_address_free_ Address *address = NULL;
@@ -171,7 +173,6 @@ static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata) {
assert(link);
assert(link->network);
- assert(link->manager);
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return;
diff --git a/src/network/networkd-ipv6-proxy-ndp.c b/src/network/networkd-ipv6-proxy-ndp.c
new file mode 100644
index 0000000000..11c1cd9268
--- /dev/null
+++ b/src/network/networkd-ipv6-proxy-ndp.c
@@ -0,0 +1,209 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2017 Florian Klink <flokli@flokli.de>
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/ether.h>
+#include <linux/if.h>
+#include <unistd.h>
+
+#include "fileio.h"
+#include "netlink-util.h"
+#include "networkd-ipv6-proxy-ndp.h"
+#include "networkd-link.h"
+#include "networkd-manager.h"
+#include "networkd-network.h"
+#include "string-util.h"
+
+static bool ipv6_proxy_ndp_is_needed(Link *link) {
+ assert(link);
+
+ if (link->flags & IFF_LOOPBACK)
+ return false;
+
+ if (!link->network)
+ return false;
+
+ if (link->network->n_ipv6_proxy_ndp_addresses == 0)
+ return false;
+
+ return true;
+}
+
+static int ipv6_proxy_ndp_set(Link *link) {
+ const char *p = NULL;
+ int r, v;
+
+ assert(link);
+
+ v = ipv6_proxy_ndp_is_needed(link);
+ p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/proxy_ndp");
+
+ r = write_string_file(p, one_zero(v), WRITE_STRING_FILE_VERIFY_ON_FAILURE);
+ if (r < 0)
+ log_link_warning_errno(link, r, "Cannot configure proxy NDP for interface: %m");
+
+ return 0;
+}
+
+int ipv6_proxy_ndp_address_new_static(Network *network, IPv6ProxyNDPAddress **ret) {
+ _cleanup_(ipv6_proxy_ndp_address_freep) IPv6ProxyNDPAddress *ipv6_proxy_ndp_address = NULL;
+
+ assert(network);
+ assert(ret);
+
+ /* allocate space for IPv6ProxyNDPAddress entry */
+ ipv6_proxy_ndp_address = new0(IPv6ProxyNDPAddress, 1);
+ if (!ipv6_proxy_ndp_address)
+ return -ENOMEM;
+
+ ipv6_proxy_ndp_address->network = network;
+
+ LIST_PREPEND(ipv6_proxy_ndp_addresses, network->ipv6_proxy_ndp_addresses, ipv6_proxy_ndp_address);
+ network->n_ipv6_proxy_ndp_addresses++;
+
+ *ret = ipv6_proxy_ndp_address;
+ ipv6_proxy_ndp_address = NULL;
+
+ return 0;
+}
+
+void ipv6_proxy_ndp_address_free(IPv6ProxyNDPAddress *ipv6_proxy_ndp_address) {
+ if (!ipv6_proxy_ndp_address)
+ return;
+
+ if (ipv6_proxy_ndp_address->network) {
+ LIST_REMOVE(ipv6_proxy_ndp_addresses, ipv6_proxy_ndp_address->network->ipv6_proxy_ndp_addresses,
+ ipv6_proxy_ndp_address);
+
+ assert(ipv6_proxy_ndp_address->network->n_ipv6_proxy_ndp_addresses > 0);
+ ipv6_proxy_ndp_address->network->n_ipv6_proxy_ndp_addresses--;
+ }
+
+ free(ipv6_proxy_ndp_address);
+}
+
+int config_parse_ipv6_proxy_ndp_address(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ Network *network = userdata;
+ _cleanup_(ipv6_proxy_ndp_address_freep) IPv6ProxyNDPAddress *ipv6_proxy_ndp_address = NULL;
+ int r;
+ union in_addr_union buffer;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = ipv6_proxy_ndp_address_new_static(network, &ipv6_proxy_ndp_address);
+ if (r < 0)
+ return r;
+
+ r = in_addr_from_string(AF_INET6, rvalue, &buffer);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse IPv6 proxy NDP address, ignoring: %s",
+ rvalue);
+ return 0;
+ }
+
+ r = in_addr_is_null(AF_INET6, &buffer);
+ if (r != 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "IPv6 proxy NDP address can not be the ANY address, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ ipv6_proxy_ndp_address->in_addr = buffer.in6;
+ ipv6_proxy_ndp_address = NULL;
+
+ return 0;
+}
+
+static int set_ipv6_proxy_ndp_address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
+ Link *link = userdata;
+ int r;
+
+ assert(link);
+
+ r = sd_netlink_message_get_errno(m);
+ if (r < 0 && r != -EEXIST)
+ log_link_error_errno(link, r, "Could not add IPv6 proxy ndp address entry: %m");
+
+ return 1;
+}
+
+/* send a request to the kernel to add a IPv6 Proxy entry to the neighbour table */
+int ipv6_proxy_ndp_address_configure(Link *link, IPv6ProxyNDPAddress *ipv6_proxy_ndp_address) {
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
+ sd_netlink *rtnl;
+ int r;
+
+ assert(link);
+ assert(link->network);
+ assert(link->manager);
+ assert(ipv6_proxy_ndp_address);
+
+ rtnl = link->manager->rtnl;
+
+ /* create new netlink message */
+ r = sd_rtnl_message_new_neigh(rtnl, &req, RTM_NEWNEIGH, link->ifindex, AF_INET6);
+ if (r < 0)
+ return rtnl_log_create_error(r);
+
+ r = sd_rtnl_message_neigh_set_flags(req, NLM_F_REQUEST | NTF_PROXY);
+ if (r < 0)
+ return rtnl_log_create_error(r);
+
+ r = sd_netlink_message_append_in6_addr(req, NDA_DST, &ipv6_proxy_ndp_address->in_addr);
+ if (r < 0)
+ return rtnl_log_create_error(r);
+
+ r = sd_netlink_call_async(rtnl, req, set_ipv6_proxy_ndp_address_handler, link, 0, NULL);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
+
+ return 0;
+}
+
+/* configure all ipv6 proxy ndp addresses */
+int ipv6_proxy_ndp_addresses_configure(Link *link) {
+ IPv6ProxyNDPAddress *ipv6_proxy_ndp_address;
+ int r;
+
+ /* enable or disable proxy_ndp itself depending on whether ipv6_proxy_ndp_addresses are set or not */
+ r = ipv6_proxy_ndp_set(link);
+ if (r != 0)
+ return r;
+
+ LIST_FOREACH(ipv6_proxy_ndp_addresses, ipv6_proxy_ndp_address, link->network->ipv6_proxy_ndp_addresses) {
+ r = ipv6_proxy_ndp_address_configure(link, ipv6_proxy_ndp_address);
+ if (r != 0)
+ return r;
+ }
+ return 0;
+}
diff --git a/src/network/networkd-ipv6-proxy-ndp.h b/src/network/networkd-ipv6-proxy-ndp.h
new file mode 100644
index 0000000000..f09169f40f
--- /dev/null
+++ b/src/network/networkd-ipv6-proxy-ndp.h
@@ -0,0 +1,44 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2017 Florian Klink <flokli@flokli.de>
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "list.h"
+#include "macro.h"
+
+typedef struct Network Network;
+typedef struct IPv6ProxyNDPAddress IPv6ProxyNDPAddress;
+typedef struct Link Link;
+
+struct IPv6ProxyNDPAddress {
+ Network *network;
+ struct in6_addr in_addr;
+
+ LIST_FIELDS(IPv6ProxyNDPAddress, ipv6_proxy_ndp_addresses);
+};
+
+
+int ipv6_proxy_ndp_address_new_static(Network *network, IPv6ProxyNDPAddress ** ipv6_proxy_ndp_address);
+void ipv6_proxy_ndp_address_free(IPv6ProxyNDPAddress *ipv6_proxy_ndp_address);
+int ipv6_proxy_ndp_address_configure(Link *link, IPv6ProxyNDPAddress *ipv6_proxy_ndp_address);
+int ipv6_proxy_ndp_addresses_configure(Link *link);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(IPv6ProxyNDPAddress*, ipv6_proxy_ndp_address_free);
+
+int config_parse_ipv6_proxy_ndp_address(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
diff --git a/src/network/networkd-link-bus.c b/src/network/networkd-link-bus.c
index 532557ed6c..c39c648334 100644
--- a/src/network/networkd-link-bus.c
+++ b/src/network/networkd-link-bus.c
@@ -20,7 +20,7 @@
#include "alloc-util.h"
#include "bus-util.h"
#include "networkd-link.h"
-#include "networkd.h"
+#include "networkd-manager.h"
#include "parse-util.h"
#include "strv.h"
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index aefe7335b9..b1282931f3 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -28,9 +28,10 @@
#include "fileio.h"
#include "netlink-util.h"
#include "network-internal.h"
+#include "networkd-ipv6-proxy-ndp.h"
#include "networkd-lldp-tx.h"
+#include "networkd-manager.h"
#include "networkd-ndisc.h"
-#include "networkd.h"
#include "set.h"
#include "socket-util.h"
#include "stdio-util.h"
@@ -130,7 +131,10 @@ static bool link_lldp_rx_enabled(Link *link) {
if (!link->network)
return false;
- if (link->network->bridge)
+ /* LLDP should be handled on bridge slaves as those have a direct
+ * connection to their peers not on the bridge master. Linux doesn't
+ * even (by default) forward lldp packets to the bridge master.*/
+ if (streq_ptr("bridge", link->kind))
return false;
return link->network->lldp_mode != LLDP_MODE_NO;
@@ -255,9 +259,10 @@ static int link_enable_ipv6(Link *link) {
r = write_string_file(p, one_zero(disabled), WRITE_STRING_FILE_VERIFY_ON_FAILURE);
if (r < 0)
- log_link_warning_errno(link, r, "Cannot %s IPv6 for interface %s: %m", disabled ? "disable" : "enable", link->ifname);
+ log_link_warning_errno(link, r, "Cannot %s IPv6 for interface %s: %m",
+ enable_disable(!disabled), link->ifname);
else
- log_link_info(link, "IPv6 %sd for interface: %m", enable_disable(!disabled));
+ log_link_info(link, "IPv6 successfully %sd", enable_disable(!disabled));
return 0;
}
@@ -686,18 +691,18 @@ static Address* link_find_dhcp_server_address(Link *link) {
return NULL;
}
-static int link_enter_configured(Link *link) {
+static void link_enter_configured(Link *link) {
assert(link);
assert(link->network);
- assert(link->state == LINK_STATE_SETTING_ROUTES);
+
+ if (link->state != LINK_STATE_SETTING_ROUTES)
+ return;
log_link_info(link, "Configured");
link_set_state(link, LINK_STATE_CONFIGURED);
link_dirty(link);
-
- return 0;
}
void link_check_ready(Link *link) {
@@ -851,21 +856,27 @@ static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userda
return 1;
}
-static int link_push_dns_to_dhcp_server(Link *link, sd_dhcp_server *s) {
+static int link_push_uplink_dns_to_dhcp_server(Link *link, sd_dhcp_server *s) {
_cleanup_free_ struct in_addr *addresses = NULL;
size_t n_addresses = 0, n_allocated = 0;
- char **a;
+ unsigned i;
log_debug("Copying DNS server information from %s", link->ifname);
if (!link->network)
return 0;
- STRV_FOREACH(a, link->network->dns) {
+ for (i = 0; i < link->network->n_dns; i++) {
struct in_addr ia;
/* Only look for IPv4 addresses */
- if (inet_pton(AF_INET, *a, &ia) <= 0)
+ if (link->network->dns[i].family != AF_INET)
+ continue;
+
+ ia = link->network->dns[i].address.in;
+
+ /* Never propagate obviously borked data */
+ if (in4_addr_is_null(&ia) || in4_addr_is_localhost(&ia))
continue;
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
@@ -874,8 +885,7 @@ static int link_push_dns_to_dhcp_server(Link *link, sd_dhcp_server *s) {
addresses[n_addresses++] = ia;
}
- if (link->network->dhcp_use_dns &&
- link->dhcp_lease) {
+ if (link->network->dhcp_use_dns && link->dhcp_lease) {
const struct in_addr *da = NULL;
int n;
@@ -896,7 +906,7 @@ static int link_push_dns_to_dhcp_server(Link *link, sd_dhcp_server *s) {
return sd_dhcp_server_set_dns(s, addresses, n_addresses);
}
-static int link_push_ntp_to_dhcp_server(Link *link, sd_dhcp_server *s) {
+static int link_push_uplink_ntp_to_dhcp_server(Link *link, sd_dhcp_server *s) {
_cleanup_free_ struct in_addr *addresses = NULL;
size_t n_addresses = 0, n_allocated = 0;
char **a;
@@ -913,14 +923,17 @@ static int link_push_ntp_to_dhcp_server(Link *link, sd_dhcp_server *s) {
if (inet_pton(AF_INET, *a, &ia) <= 0)
continue;
+ /* Never propagate obviously borked data */
+ if (in4_addr_is_null(&ia) || in4_addr_is_localhost(&ia))
+ continue;
+
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
return log_oom();
addresses[n_addresses++] = ia;
}
- if (link->network->dhcp_use_ntp &&
- link->dhcp_lease) {
+ if (link->network->dhcp_use_ntp && link->dhcp_lease) {
const struct in_addr *da = NULL;
int n;
@@ -1034,7 +1047,7 @@ static int link_enter_set_addresses(Link *link) {
log_link_debug(link, "Not emitting DNS server information on link, couldn't find suitable uplink.");
r = 0;
} else
- r = link_push_dns_to_dhcp_server(uplink, link->dhcp_server);
+ r = link_push_uplink_dns_to_dhcp_server(uplink, link->dhcp_server);
}
if (r < 0)
log_link_warning_errno(link, r, "Failed to set DNS server for DHCP server, ignoring: %m");
@@ -1053,7 +1066,7 @@ static int link_enter_set_addresses(Link *link) {
log_link_debug(link, "Not emitting NTP server information on link, couldn't find suitable uplink.");
r = 0;
} else
- r = link_push_ntp_to_dhcp_server(uplink, link->dhcp_server);
+ r = link_push_uplink_ntp_to_dhcp_server(uplink, link->dhcp_server);
}
if (r < 0)
@@ -1167,109 +1180,6 @@ static int link_set_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userd
return 0;
}
-static int set_hostname_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
- _cleanup_link_unref_ Link *link = userdata;
- const sd_bus_error *e;
-
- assert(m);
- assert(link);
-
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- e = sd_bus_message_get_error(m);
- if (e)
- log_link_warning_errno(link, sd_bus_error_get_errno(e), "Could not set hostname: %s", e->message);
-
- return 1;
-}
-
-int link_set_hostname(Link *link, const char *hostname) {
- int r;
-
- assert(link);
- assert(link->manager);
-
- log_link_debug(link, "Setting transient hostname: '%s'", strna(hostname));
-
- if (!link->manager->bus) {
- /* TODO: replace by assert when we can rely on kdbus */
- log_link_info(link, "Not connected to system bus, ignoring transient hostname.");
- return 0;
- }
-
- r = sd_bus_call_method_async(
- link->manager->bus,
- NULL,
- "org.freedesktop.hostname1",
- "/org/freedesktop/hostname1",
- "org.freedesktop.hostname1",
- "SetHostname",
- set_hostname_handler,
- link,
- "sb",
- hostname,
- false);
-
- if (r < 0)
- return log_link_error_errno(link, r, "Could not set transient hostname: %m");
-
- link_ref(link);
-
- return 0;
-}
-
-static int set_timezone_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
- _cleanup_link_unref_ Link *link = userdata;
- const sd_bus_error *e;
-
- assert(m);
- assert(link);
-
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- e = sd_bus_message_get_error(m);
- if (e)
- log_link_warning_errno(link, sd_bus_error_get_errno(e), "Could not set timezone: %s", e->message);
-
- return 1;
-}
-
-int link_set_timezone(Link *link, const char *tz) {
- int r;
-
- assert(link);
- assert(link->manager);
- assert(tz);
-
- log_link_debug(link, "Setting system timezone: '%s'", tz);
-
- if (!link->manager->bus) {
- log_link_info(link, "Not connected to system bus, ignoring timezone.");
- return 0;
- }
-
- r = sd_bus_call_method_async(
- link->manager->bus,
- NULL,
- "org.freedesktop.timedate1",
- "/org/freedesktop/timedate1",
- "org.freedesktop.timedate1",
- "SetTimezone",
- set_timezone_handler,
- link,
- "sb",
- tz,
- false);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not set timezone: %m");
-
- link_ref(link);
-
- return 0;
-}
-
static int set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
_cleanup_link_unref_ Link *link = userdata;
int r;
@@ -1432,6 +1342,58 @@ static int link_set_bridge(Link *link) {
return r;
}
+static int link_bond_set(Link *link) {
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
+ int r;
+
+ assert(link);
+ assert(link->network);
+
+ r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_NEWLINK, link->network->bond->ifindex);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
+
+ r = sd_netlink_message_set_flags(req, NLM_F_REQUEST | NLM_F_ACK);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not set netlink flags: %m");
+
+ r = sd_netlink_message_open_container(req, IFLA_LINKINFO);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_PROTINFO attribute: %m");
+
+ r = sd_netlink_message_open_container_union(req, IFLA_INFO_DATA, "bond");
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m");
+
+ if (link->network->active_slave) {
+ r = sd_netlink_message_append_u32(req, IFLA_BOND_ACTIVE_SLAVE, link->ifindex);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_BOND_ACTIVE_SLAVE attribute: %m");
+ }
+
+ if (link->network->primary_slave) {
+ r = sd_netlink_message_append_u32(req, IFLA_BOND_PRIMARY, link->ifindex);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_BOND_PRIMARY attribute: %m");
+ }
+
+ r = sd_netlink_message_close_container(req);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m");
+
+ r = sd_netlink_message_close_container(req);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m");
+
+ r = sd_netlink_call_async(link->manager->rtnl, req, set_flags_handler, link, 0, NULL);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
+
+ link_ref(link);
+
+ return r;
+}
+
static int link_lldp_save(Link *link) {
_cleanup_free_ char *temp_path = NULL;
_cleanup_fclose_ FILE *f = NULL;
@@ -1639,7 +1601,7 @@ static int link_up_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userda
return 1;
}
-static int link_up(Link *link) {
+int link_up(Link *link) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
uint8_t ipv6ll_mode;
int r;
@@ -1760,7 +1722,7 @@ static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, void *user
return 1;
}
-static int link_down(Link *link) {
+int link_down(Link *link) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
int r;
@@ -2086,6 +2048,12 @@ static int link_joined(Link *link) {
log_link_error_errno(link, r, "Could not set bridge message: %m");
}
+ if (link->network->bond) {
+ r = link_bond_set(link);
+ if (r < 0)
+ log_link_error_errno(link, r, "Could not set bond message: %m");
+ }
+
if (link->network->use_br_vlan &&
(link->network->bridge || streq_ptr("bridge", link->kind))) {
r = link_set_bridge_vlan(link);
@@ -2484,6 +2452,10 @@ static int link_configure(Link *link) {
if (r < 0)
return r;
+ r = ipv6_proxy_ndp_addresses_configure(link);
+ if (r < 0)
+ return r;
+
r = link_set_ipv4_forward(link);
if (r < 0)
return r;
@@ -2618,6 +2590,9 @@ static int link_initialized_and_synced(sd_netlink *rtnl, sd_netlink_message *m,
if (r == -ENOENT) {
link_enter_unmanaged(link);
return 1;
+ } else if (r == 0 && network->unmanaged) {
+ link_enter_unmanaged(link);
+ return 0;
} else if (r < 0)
return r;
@@ -2632,7 +2607,7 @@ static int link_initialized_and_synced(sd_netlink *rtnl, sd_netlink_message *m,
log_link_debug(link, "Ignoring DHCP server for loopback link");
}
- r = network_apply(link->manager, network, link);
+ r = network_apply(network, link);
if (r < 0)
return r;
}
@@ -2728,7 +2703,7 @@ static int link_load(Link *link) {
goto network_file_fail;
}
- r = network_apply(link->manager, network, link);
+ r = network_apply(network, link);
if (r < 0)
return log_link_error_errno(link, r, "Failed to apply network %s: %m", basename(network_file));
}
@@ -3235,7 +3210,7 @@ int link_save(Link *link) {
if (r < 0)
goto fail;
- fchmod(fileno(f), 0644);
+ (void) fchmod(fileno(f), 0644);
fprintf(f,
"# This is private data. Do not parse.\n"
@@ -3248,6 +3223,7 @@ int link_save(Link *link) {
sd_dhcp6_lease *dhcp6_lease = NULL;
const char *dhcp_domainname = NULL;
char **dhcp6_domains = NULL;
+ unsigned j;
if (link->dhcp6_client) {
r = sd_dhcp6_client_get_lease(link->dhcp6_client, &dhcp6_lease);
@@ -3259,7 +3235,22 @@ int link_save(Link *link) {
fputs("DNS=", f);
space = false;
- fputstrv(f, link->network->dns, NULL, &space);
+
+ for (j = 0; j < link->network->n_dns; j++) {
+ _cleanup_free_ char *b = NULL;
+
+ r = in_addr_to_string(link->network->dns[j].family,
+ &link->network->dns[j].address, &b);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to format address, ignoring: %m");
+ continue;
+ }
+
+ if (space)
+ fputc(' ', f);
+ fputs(b, f);
+ space = true;
+ }
if (link->network->dhcp_use_dns &&
link->dhcp_lease) {
diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h
index 77f72d070e..be5c4f3284 100644
--- a/src/network/networkd-link.h
+++ b/src/network/networkd-link.h
@@ -138,6 +138,9 @@ int link_get(Manager *m, int ifindex, Link **ret);
int link_add(Manager *manager, sd_netlink_message *message, Link **ret);
void link_drop(Link *link);
+int link_up(Link *link);
+int link_down(Link *link);
+
int link_address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata);
int link_route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata);
@@ -159,8 +162,6 @@ bool link_has_carrier(Link *link);
int link_ipv6ll_gained(Link *link, const struct in6_addr *address);
int link_set_mtu(Link *link, uint32_t mtu);
-int link_set_hostname(Link *link, const char *hostname);
-int link_set_timezone(Link *link, const char *timezone);
int ipv4ll_configure(Link *link);
int dhcp4_configure(Link *link);
diff --git a/src/network/networkd-lldp-tx.c b/src/network/networkd-lldp-tx.c
index 3aa768388b..2de63ce746 100644
--- a/src/network/networkd-lldp-tx.c
+++ b/src/network/networkd-lldp-tx.c
@@ -26,7 +26,7 @@
#include "fileio.h"
#include "hostname-util.h"
#include "networkd-lldp-tx.h"
-#include "networkd.h"
+#include "networkd-manager.h"
#include "parse-util.h"
#include "random-util.h"
#include "socket-util.h"
diff --git a/src/network/networkd-manager-bus.c b/src/network/networkd-manager-bus.c
index 0c429b9471..cbb1b93031 100644
--- a/src/network/networkd-manager-bus.c
+++ b/src/network/networkd-manager-bus.c
@@ -19,7 +19,7 @@
#include "alloc-util.h"
#include "bus-util.h"
-#include "networkd.h"
+#include "networkd-manager.h"
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_operational_state, link_operstate, LinkOperationalState);
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index 9174dcc7f4..ea1c320809 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -33,7 +33,7 @@
#include "libudev-private.h"
#include "local-addresses.h"
#include "netlink-util.h"
-#include "networkd.h"
+#include "networkd-manager.h"
#include "ordered-set.h"
#include "path-util.h"
#include "set.h"
@@ -192,6 +192,18 @@ int manager_connect_bus(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to attach bus to event loop: %m");
+ /* Did we get a timezone or transient hostname from DHCP while D-Bus wasn't up yet? */
+ if (m->dynamic_hostname) {
+ r = manager_set_hostname(m, m->dynamic_hostname);
+ if (r < 0)
+ return r;
+ }
+ if (m->dynamic_timezone) {
+ r = manager_set_timezone(m, m->dynamic_timezone);
+ if (r < 0)
+ return r;
+ }
+
return 0;
}
@@ -774,11 +786,48 @@ static int manager_connect_rtnl(Manager *m) {
return 0;
}
-static int ordered_set_put_in_addr(OrderedSet *s, const struct in_addr *address) {
+static int ordered_set_put_in_addr_data(OrderedSet *s, const struct in_addr_data *address) {
char *p;
int r;
assert(s);
+ assert(address);
+
+ r = in_addr_to_string(address->family, &address->address, &p);
+ if (r < 0)
+ return r;
+
+ r = ordered_set_consume(s, p);
+ if (r == -EEXIST)
+ return 0;
+
+ return r;
+}
+
+static int ordered_set_put_in_addr_datav(OrderedSet *s, const struct in_addr_data *addresses, unsigned n) {
+ int r, c = 0;
+ unsigned i;
+
+ assert(s);
+ assert(addresses || n == 0);
+
+ for (i = 0; i < n; i++) {
+ r = ordered_set_put_in_addr_data(s, addresses+i);
+ if (r < 0)
+ return r;
+
+ c += r;
+ }
+
+ return c;
+}
+
+static int ordered_set_put_in4_addr(OrderedSet *s, const struct in_addr *address) {
+ char *p;
+ int r;
+
+ assert(s);
+ assert(address);
r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p);
if (r < 0)
@@ -791,14 +840,15 @@ static int ordered_set_put_in_addr(OrderedSet *s, const struct in_addr *address)
return r;
}
-static int ordered_set_put_in_addrv(OrderedSet *s, const struct in_addr *addresses, int n) {
- int r, i, c = 0;
+static int ordered_set_put_in4_addrv(OrderedSet *s, const struct in_addr *addresses, unsigned n) {
+ int r, c = 0;
+ unsigned i;
assert(s);
- assert(n <= 0 || addresses);
+ assert(n == 0 || addresses);
for (i = 0; i < n; i++) {
- r = ordered_set_put_in_addr(s, addresses+i);
+ r = ordered_set_put_in4_addr(s, addresses+i);
if (r < 0)
return r;
@@ -865,7 +915,7 @@ static int manager_save(Manager *m) {
continue;
/* First add the static configured entries */
- r = ordered_set_put_strdupv(dns, link->network->dns);
+ r = ordered_set_put_in_addr_datav(dns, link->network->dns, link->network->n_dns);
if (r < 0)
return r;
@@ -890,7 +940,7 @@ static int manager_save(Manager *m) {
r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
if (r > 0) {
- r = ordered_set_put_in_addrv(dns, addresses, r);
+ r = ordered_set_put_in4_addrv(dns, addresses, r);
if (r < 0)
return r;
} else if (r < 0 && r != -ENODATA)
@@ -902,7 +952,7 @@ static int manager_save(Manager *m) {
r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
if (r > 0) {
- r = ordered_set_put_in_addrv(ntp, addresses, r);
+ r = ordered_set_put_in4_addrv(ntp, addresses, r);
if (r < 0)
return r;
} else if (r < 0 && r != -ENODATA)
@@ -934,7 +984,7 @@ static int manager_save(Manager *m) {
if (r < 0)
return r;
- fchmod(fileno(f), 0644);
+ (void) fchmod(fileno(f), 0644);
fprintf(f,
"# This is private data. Do not parse.\n"
@@ -992,7 +1042,7 @@ static int manager_dirty_handler(sd_event_source *s, void *userdata) {
return 1;
}
-int manager_new(Manager **ret) {
+int manager_new(Manager **ret, sd_event *event) {
_cleanup_manager_free_ Manager *m = NULL;
int r;
@@ -1004,14 +1054,7 @@ int manager_new(Manager **ret) {
if (!m->state_file)
return -ENOMEM;
- r = sd_event_default(&m->event);
- if (r < 0)
- return r;
-
- sd_event_set_watchdog(m->event, true);
-
- sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
- sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
+ m->event = sd_event_ref(event);
r = sd_event_add_post(m->event, NULL, manager_dirty_handler, m);
if (r < 0)
@@ -1081,36 +1124,13 @@ void manager_free(Manager *m) {
sd_bus_slot_unref(m->prepare_for_sleep_slot);
sd_event_source_unref(m->bus_retry_event_source);
- free(m);
-}
-
-static bool manager_check_idle(void *userdata) {
- Manager *m = userdata;
- Link *link;
- Iterator i;
-
- assert(m);
-
- /* Check whether we are idle now. The only case when we decide to be idle is when there's only a loopback
- * device around, for which we have no configuration, and which already left the PENDING state. In all other
- * cases we are not idle. */
+ free(m->dynamic_timezone);
+ free(m->dynamic_hostname);
- HASHMAP_FOREACH(link, m->links, i) {
- /* We are not woken on udev activity, so let's just wait for the pending udev event */
- if (link->state == LINK_STATE_PENDING)
- return false;
-
- if ((link->flags & IFF_LOOPBACK) == 0)
- return false;
-
- if (link->network)
- return false;
- }
-
- return true;
+ free(m);
}
-int manager_run(Manager *m) {
+int manager_start(Manager *m) {
Link *link;
Iterator i;
@@ -1124,18 +1144,7 @@ int manager_run(Manager *m) {
HASHMAP_FOREACH(link, m->links, i)
link_save(link);
- if (m->bus)
- return bus_event_loop_with_idle(
- m->event,
- m->bus,
- "org.freedesktop.network1",
- DEFAULT_EXIT_USEC,
- manager_check_idle,
- m);
- else
- /* failed to connect to the bus, so we lose exit-on-idle logic,
- this should not happen except if dbus is not around at all */
- return sd_event_loop(m->event);
+ return 0;
}
int manager_load_config(Manager *m) {
@@ -1327,3 +1336,96 @@ void manager_dirty(Manager *manager) {
/* the serialized state in /run is no longer up-to-date */
manager->dirty = true;
}
+
+static int set_hostname_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
+ Manager *manager = userdata;
+ const sd_bus_error *e;
+
+ assert(m);
+ assert(manager);
+
+ e = sd_bus_message_get_error(m);
+ if (e)
+ log_warning_errno(sd_bus_error_get_errno(e), "Could not set hostname: %s", e->message);
+
+ return 1;
+}
+
+int manager_set_hostname(Manager *m, const char *hostname) {
+ int r;
+
+ log_debug("Setting transient hostname: '%s'", strna(hostname));
+ if (free_and_strdup(&m->dynamic_hostname, hostname) < 0)
+ return log_oom();
+
+ if (!m->bus) {
+ /* TODO: replace by assert when we can rely on kdbus */
+ log_info("Not connected to system bus, ignoring transient hostname.");
+ return 0;
+ }
+
+ r = sd_bus_call_method_async(
+ m->bus,
+ NULL,
+ "org.freedesktop.hostname1",
+ "/org/freedesktop/hostname1",
+ "org.freedesktop.hostname1",
+ "SetHostname",
+ set_hostname_handler,
+ m,
+ "sb",
+ hostname,
+ false);
+
+ if (r < 0)
+ return log_error_errno(r, "Could not set transient hostname: %m");
+
+ return 0;
+}
+
+static int set_timezone_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
+ Manager *manager = userdata;
+ const sd_bus_error *e;
+
+ assert(m);
+ assert(manager);
+
+ e = sd_bus_message_get_error(m);
+ if (e)
+ log_warning_errno(sd_bus_error_get_errno(e), "Could not set timezone: %s", e->message);
+
+ return 1;
+}
+
+int manager_set_timezone(Manager *m, const char *tz) {
+ int r;
+
+ assert(m);
+ assert(tz);
+
+ log_debug("Setting system timezone: '%s'", tz);
+ if (free_and_strdup(&m->dynamic_timezone, tz) < 0)
+ return log_oom();
+
+ if (!m->bus) {
+ log_info("Not connected to system bus, ignoring timezone.");
+ return 0;
+ }
+
+ r = sd_bus_call_method_async(
+ m->bus,
+ NULL,
+ "org.freedesktop.timedate1",
+ "/org/freedesktop/timedate1",
+ "org.freedesktop.timedate1",
+ "SetTimezone",
+ set_timezone_handler,
+ m,
+ "sb",
+ tz,
+ false);
+ if (r < 0)
+ return log_error_errno(r, "Could not set timezone: %m");
+
+ return 0;
+}
diff --git a/src/network/networkd.h b/src/network/networkd-manager.h
index cb1b73145e..e2447c2230 100644
--- a/src/network/networkd.h
+++ b/src/network/networkd-manager.h
@@ -32,20 +32,7 @@
#include "networkd-address-pool.h"
#include "networkd-link.h"
-#include "networkd-netdev-bond.h"
-#include "networkd-netdev-bridge.h"
-#include "networkd-netdev-dummy.h"
-#include "networkd-netdev-ipvlan.h"
-#include "networkd-netdev-macvlan.h"
-#include "networkd-netdev-tunnel.h"
-#include "networkd-netdev-tuntap.h"
-#include "networkd-netdev-veth.h"
-#include "networkd-netdev-vlan.h"
-#include "networkd-netdev-vrf.h"
-#include "networkd-netdev-vxlan.h"
-#include "networkd-netdev-vcan.h"
#include "networkd-network.h"
-#include "networkd-util.h"
extern const char* const network_dirs[];
@@ -76,6 +63,8 @@ struct Manager {
usec_t network_dirs_ts_usec;
DUID duid;
+ char* dynamic_hostname;
+ char* dynamic_timezone;
};
static inline const DUID* link_duid(const Link *link) {
@@ -87,11 +76,11 @@ static inline const DUID* link_duid(const Link *link) {
extern const sd_bus_vtable manager_vtable[];
-int manager_new(Manager **ret);
+int manager_new(Manager **ret, sd_event *event);
void manager_free(Manager *m);
int manager_connect_bus(Manager *m);
-int manager_run(Manager *m);
+int manager_start(Manager *m);
int manager_load_config(Manager *m);
bool manager_should_reload(Manager *m);
@@ -110,5 +99,8 @@ int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, uni
Link* manager_find_uplink(Manager *m, Link *exclude);
+int manager_set_hostname(Manager *m, const char *hostname);
+int manager_set_timezone(Manager *m, const char *timezone);
+
DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
#define _cleanup_manager_free_ _cleanup_(manager_freep)
diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c
index 4853791aa5..d52b511bb5 100644
--- a/src/network/networkd-ndisc.c
+++ b/src/network/networkd-ndisc.c
@@ -18,14 +18,16 @@
***/
#include <netinet/icmp6.h>
+#include <arpa/inet.h>
#include "sd-ndisc.h"
-#include "networkd.h"
#include "networkd-ndisc.h"
+#include "networkd-route.h"
#define NDISC_DNSSL_MAX 64U
#define NDISC_RDNSS_MAX 64U
+#define NDISC_PREFIX_LFT_MIN 7200U
static int ndisc_netlink_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
_cleanup_link_unref_ Link *link = userdata;
@@ -55,6 +57,7 @@ static void ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
struct in6_addr gateway;
uint16_t lifetime;
unsigned preference;
+ uint32_t mtu;
usec_t time_now;
int r;
Address *address;
@@ -115,6 +118,14 @@ static void ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
return;
}
+ r = sd_ndisc_router_get_mtu(rt, &mtu);
+ if (r == -ENODATA)
+ mtu = 0;
+ else if (r < 0) {
+ log_link_warning_errno(link, r, "Failed to get default router MTU from RA: %m");
+ return;
+ }
+
r = route_new(&route);
if (r < 0) {
log_link_error_errno(link, r, "Could not allocate route: %m");
@@ -123,10 +134,12 @@ static void ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
route->family = AF_INET6;
route->table = link->network->ipv6_accept_ra_route_table;
+ route->priority = link->network->dhcp_route_metric;
route->protocol = RTPROT_RA;
route->pref = preference;
route->gw.in6 = gateway;
route->lifetime = time_now + lifetime * USEC_PER_SEC;
+ route->mtu = mtu;
r = route_configure(route, link, ndisc_netlink_handler);
if (r < 0) {
@@ -140,13 +153,21 @@ static void ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
static void ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *rt) {
_cleanup_address_free_ Address *address = NULL;
- uint32_t lifetime_valid, lifetime_preferred;
+ Address *existing_address;
+ uint32_t lifetime_valid, lifetime_preferred, lifetime_remaining;
+ usec_t time_now;
unsigned prefixlen;
int r;
assert(link);
assert(rt);
+ r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
+ if (r < 0) {
+ log_link_warning_errno(link, r, "Failed to get RA timestamp: %m");
+ return;
+ }
+
r = sd_ndisc_router_prefix_get_prefixlen(rt, &prefixlen);
if (r < 0) {
log_link_error_errno(link, r, "Failed to get prefix length: %m");
@@ -195,7 +216,24 @@ static void ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *
address->prefixlen = prefixlen;
address->flags = IFA_F_NOPREFIXROUTE|IFA_F_MANAGETEMPADDR;
address->cinfo.ifa_prefered = lifetime_preferred;
- address->cinfo.ifa_valid = lifetime_valid;
+
+ /* see RFC4862 section 5.5.3.e */
+ r = address_get(link, address->family, &address->in_addr, address->prefixlen, &existing_address);
+ if (r > 0) {
+ lifetime_remaining = existing_address->cinfo.tstamp / 100 + existing_address->cinfo.ifa_valid - time_now / USEC_PER_SEC;
+ if (lifetime_valid > NDISC_PREFIX_LFT_MIN || lifetime_valid > lifetime_remaining)
+ address->cinfo.ifa_valid = lifetime_valid;
+ else if (lifetime_remaining <= NDISC_PREFIX_LFT_MIN)
+ address->cinfo.ifa_valid = lifetime_remaining;
+ else
+ address->cinfo.ifa_valid = NDISC_PREFIX_LFT_MIN;
+ } else if (lifetime_valid > 0)
+ address->cinfo.ifa_valid = lifetime_valid;
+ else
+ return; /* see RFC4862 section 5.5.3.d */
+
+ if (address->cinfo.ifa_valid == 0)
+ return;
r = address_configure(address, link, ndisc_netlink_handler, true);
if (r < 0) {
@@ -243,6 +281,7 @@ static void ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt)
route->family = AF_INET6;
route->table = link->network->ipv6_accept_ra_route_table;
+ route->priority = link->network->dhcp_route_metric;
route->protocol = RTPROT_RA;
route->flags = RTM_F_PREFIX;
route->dst_prefixlen = prefixlen;
@@ -574,11 +613,13 @@ static void ndisc_router_process_options(Link *link, sd_ndisc_router *rt) {
break;
case SD_NDISC_OPTION_RDNSS:
- ndisc_router_process_rdnss(link, rt);
+ if (link->network->ipv6_accept_ra_use_dns)
+ ndisc_router_process_rdnss(link, rt);
break;
case SD_NDISC_OPTION_DNSSL:
- ndisc_router_process_dnssl(link, rt);
+ if (link->network->ipv6_accept_ra_use_dns)
+ ndisc_router_process_dnssl(link, rt);
break;
}
diff --git a/src/network/networkd-netdev-gperf.gperf b/src/network/networkd-netdev-gperf.gperf
deleted file mode 100644
index 323eaa8032..0000000000
--- a/src/network/networkd-netdev-gperf.gperf
+++ /dev/null
@@ -1,118 +0,0 @@
-%{
-#include <stddef.h>
-#include "conf-parser.h"
-#include "network-internal.h"
-#include "networkd-netdev-bond.h"
-#include "networkd-netdev-bridge.h"
-#include "networkd-netdev-ipvlan.h"
-#include "networkd-netdev-macvlan.h"
-#include "networkd-netdev-tunnel.h"
-#include "networkd-netdev-tuntap.h"
-#include "networkd-netdev-veth.h"
-#include "networkd-netdev-vlan.h"
-#include "networkd-netdev-vxlan.h"
-#include "networkd-netdev-vrf.h"
-#include "networkd-netdev.h"
-#include "vlan-util.h"
-%}
-struct ConfigPerfItem;
-%null_strings
-%language=ANSI-C
-%define slot-name section_and_lvalue
-%define hash-function-name network_netdev_gperf_hash
-%define lookup-function-name network_netdev_gperf_lookup
-%readonly-tables
-%omit-struct-type
-%struct-type
-%includes
-%%
-Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(NetDev, match_host)
-Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(NetDev, match_virt)
-Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(NetDev, match_kernel)
-Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(NetDev, match_arch)
-NetDev.Description, config_parse_string, 0, offsetof(NetDev, description)
-NetDev.Name, config_parse_ifname, 0, offsetof(NetDev, ifname)
-NetDev.Kind, config_parse_netdev_kind, 0, offsetof(NetDev, kind)
-NetDev.MTUBytes, config_parse_iec_size, 0, offsetof(NetDev, mtu)
-NetDev.MACAddress, config_parse_hwaddr, 0, offsetof(NetDev, mac)
-VLAN.Id, config_parse_vlanid, 0, offsetof(VLan, id)
-MACVLAN.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode)
-MACVTAP.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode)
-IPVLAN.Mode, config_parse_ipvlan_mode, 0, offsetof(IPVlan, mode)
-Tunnel.Local, config_parse_tunnel_address, 0, offsetof(Tunnel, local)
-Tunnel.Remote, config_parse_tunnel_address, 0, offsetof(Tunnel, remote)
-Tunnel.TOS, config_parse_unsigned, 0, offsetof(Tunnel, tos)
-Tunnel.TTL, config_parse_unsigned, 0, offsetof(Tunnel, ttl)
-Tunnel.Key, config_parse_tunnel_key, 0, offsetof(Tunnel, key)
-Tunnel.InputKey, config_parse_tunnel_key, 0, offsetof(Tunnel, ikey)
-Tunnel.OutputKey, config_parse_tunnel_key, 0, offsetof(Tunnel, okey)
-Tunnel.DiscoverPathMTU, config_parse_bool, 0, offsetof(Tunnel, pmtudisc)
-Tunnel.Mode, config_parse_ip6tnl_mode, 0, offsetof(Tunnel, ip6tnl_mode)
-Tunnel.IPv6FlowLabel, config_parse_ipv6_flowlabel, 0, offsetof(Tunnel, ipv6_flowlabel)
-Tunnel.CopyDSCP, config_parse_bool, 0, offsetof(Tunnel, copy_dscp)
-Tunnel.EncapsulationLimit, config_parse_encap_limit, 0, offsetof(Tunnel, encap_limit)
-Peer.Name, config_parse_ifname, 0, offsetof(Veth, ifname_peer)
-Peer.MACAddress, config_parse_hwaddr, 0, offsetof(Veth, mac_peer)
-VXLAN.Id, config_parse_uint64, 0, offsetof(VxLan, id)
-VXLAN.Group, config_parse_vxlan_group_address, 0, offsetof(VxLan, group)
-VXLAN.TOS, config_parse_unsigned, 0, offsetof(VxLan, tos)
-VXLAN.TTL, config_parse_unsigned, 0, offsetof(VxLan, ttl)
-VXLAN.MacLearning, config_parse_bool, 0, offsetof(VxLan, learning)
-VXLAN.ARPProxy, config_parse_bool, 0, offsetof(VxLan, arp_proxy)
-VXLAN.L2MissNotification, config_parse_bool, 0, offsetof(VxLan, l2miss)
-VXLAN.L3MissNotification, config_parse_bool, 0, offsetof(VxLan, l3miss)
-VXLAN.RouteShortCircuit, config_parse_bool, 0, offsetof(VxLan, route_short_circuit)
-VXLAN.UDPCheckSum, config_parse_bool, 0, offsetof(VxLan, udpcsum)
-VXLAN.UDPChecksum, config_parse_bool, 0, offsetof(VxLan, udpcsum)
-VXLAN.UDP6ZeroCheckSumRx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumrx)
-VXLAN.UDP6ZeroChecksumRx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumrx)
-VXLAN.UDP6ZeroCheckSumTx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumtx)
-VXLAN.UDP6ZeroChecksumTx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumtx)
-VXLAN.RemoteChecksumTx, config_parse_bool, 0, offsetof(VxLan, remote_csum_tx)
-VXLAN.RemoteChecksumRx, config_parse_bool, 0, offsetof(VxLan, remote_csum_rx)
-VXLAN.FDBAgeingSec, config_parse_sec, 0, offsetof(VxLan, fdb_ageing)
-VXLAN.GroupPolicyExtension, config_parse_bool, 0, offsetof(VxLan, group_policy)
-VXLAN.MaximumFDBEntries, config_parse_unsigned, 0, offsetof(VxLan, max_fdb)
-VXLAN.PortRange, config_parse_port_range, 0, 0
-VXLAN.DestinationPort, config_parse_destination_port, 0, offsetof(VxLan, dest_port)
-Tun.OneQueue, config_parse_bool, 0, offsetof(TunTap, one_queue)
-Tun.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue)
-Tun.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info)
-Tun.User, config_parse_string, 0, offsetof(TunTap, user_name)
-Tun.Group, config_parse_string, 0, offsetof(TunTap, group_name)
-Tap.OneQueue, config_parse_bool, 0, offsetof(TunTap, one_queue)
-Tap.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue)
-Tap.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info)
-Tap.VNetHeader, config_parse_bool, 0, offsetof(TunTap, vnet_hdr)
-Tap.User, config_parse_string, 0, offsetof(TunTap, user_name)
-Tap.Group, config_parse_string, 0, offsetof(TunTap, group_name)
-Bond.Mode, config_parse_bond_mode, 0, offsetof(Bond, mode)
-Bond.TransmitHashPolicy, config_parse_bond_xmit_hash_policy, 0, offsetof(Bond, xmit_hash_policy)
-Bond.LACPTransmitRate, config_parse_bond_lacp_rate, 0, offsetof(Bond, lacp_rate)
-Bond.AdSelect, config_parse_bond_ad_select, 0, offsetof(Bond, ad_select)
-Bond.FailOverMACPolicy, config_parse_bond_fail_over_mac, 0, offsetof(Bond, fail_over_mac)
-Bond.ARPIPTargets, config_parse_arp_ip_target_address, 0, 0
-Bond.ARPValidate, config_parse_bond_arp_validate, 0, offsetof(Bond, arp_validate)
-Bond.ARPAllTargets, config_parse_bond_arp_all_targets, 0, offsetof(Bond, arp_all_targets)
-Bond.PrimaryReselectPolicy, config_parse_bond_primary_reselect, 0, offsetof(Bond, primary_reselect)
-Bond.ResendIGMP, config_parse_unsigned, 0, offsetof(Bond, resend_igmp)
-Bond.PacketsPerSlave, config_parse_unsigned, 0, offsetof(Bond, packets_per_slave)
-Bond.GratuitousARP, config_parse_unsigned, 0, offsetof(Bond, num_grat_arp)
-Bond.AllSlavesActive, config_parse_unsigned, 0, offsetof(Bond, all_slaves_active)
-Bond.MinLinks, config_parse_unsigned, 0, offsetof(Bond, min_links)
-Bond.MIIMonitorSec, config_parse_sec, 0, offsetof(Bond, miimon)
-Bond.UpDelaySec, config_parse_sec, 0, offsetof(Bond, updelay)
-Bond.DownDelaySec, config_parse_sec, 0, offsetof(Bond, downdelay)
-Bond.ARPIntervalSec, config_parse_sec, 0, offsetof(Bond, arp_interval)
-Bond.LearnPacketIntervalSec, config_parse_sec, 0, offsetof(Bond, lp_interval)
-Bridge.HelloTimeSec, config_parse_sec, 0, offsetof(Bridge, hello_time)
-Bridge.MaxAgeSec, config_parse_sec, 0, offsetof(Bridge, max_age)
-Bridge.AgeingTimeSec, config_parse_sec, 0, offsetof(Bridge, ageing_time)
-Bridge.ForwardDelaySec, config_parse_sec, 0, offsetof(Bridge, forward_delay)
-Bridge.Priority, config_parse_uint16, 0, offsetof(Bridge, priority)
-Bridge.DefaultPVID, config_parse_vlanid, 0, offsetof(Bridge, default_pvid)
-Bridge.MulticastQuerier, config_parse_tristate, 0, offsetof(Bridge, mcast_querier)
-Bridge.MulticastSnooping, config_parse_tristate, 0, offsetof(Bridge, mcast_snooping)
-Bridge.VLANFiltering, config_parse_tristate, 0, offsetof(Bridge, vlan_filtering)
-Bridge.STP, config_parse_tristate, 0, offsetof(Bridge, stp)
-VRF.TableId, config_parse_uint32, 0, offsetof(Vrf, table_id)
diff --git a/src/network/networkd-network-bus.c b/src/network/networkd-network-bus.c
index 6e21676d23..3b835b52f9 100644
--- a/src/network/networkd-network-bus.c
+++ b/src/network/networkd-network-bus.c
@@ -18,7 +18,7 @@
***/
#include "alloc-util.h"
-#include "networkd.h"
+#include "networkd-manager.h"
#include "string-util.h"
#include "strv.h"
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index bcf8186c33..68052ba544 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -1,8 +1,8 @@
%{
#include <stddef.h>
#include "conf-parser.h"
-#include "networkd.h"
#include "networkd-conf.h"
+#include "networkd-network.h"
#include "network-internal.h"
#include "vlan-util.h"
%}
@@ -29,6 +29,7 @@ Match.Architecture, config_parse_net_condition,
Link.MACAddress, config_parse_hwaddr, 0, offsetof(Network, mac)
Link.MTUBytes, config_parse_iec_size, 0, offsetof(Network, mtu)
Link.ARP, config_parse_tristate, 0, offsetof(Network, arp)
+Link.Unmanaged, config_parse_bool, 0, offsetof(Network, unmanaged)
Network.Description, config_parse_string, 0, offsetof(Network, description)
Network.Bridge, config_parse_netdev, 0, offsetof(Network, bridge)
Network.Bond, config_parse_netdev, 0, offsetof(Network, bond)
@@ -54,16 +55,19 @@ Network.LLMNR, config_parse_resolve_support,
Network.MulticastDNS, config_parse_resolve_support, 0, offsetof(Network, mdns)
Network.DNSSEC, config_parse_dnssec_mode, 0, offsetof(Network, dnssec_mode)
Network.DNSSECNegativeTrustAnchors, config_parse_dnssec_negative_trust_anchors, 0, 0
-Network.NTP, config_parse_strv, 0, offsetof(Network, ntp)
+Network.NTP, config_parse_ntp, 0, offsetof(Network, ntp)
Network.IPForward, config_parse_address_family_boolean_with_kernel,0, offsetof(Network, ip_forward)
Network.IPMasquerade, config_parse_bool, 0, offsetof(Network, ip_masquerade)
Network.IPv6PrivacyExtensions, config_parse_ipv6_privacy_extensions, 0, offsetof(Network, ipv6_privacy_extensions)
Network.IPv6AcceptRA, config_parse_tristate, 0, offsetof(Network, ipv6_accept_ra)
-/* legacy alias for the above */
Network.IPv6AcceptRouterAdvertisements, config_parse_tristate, 0, offsetof(Network, ipv6_accept_ra)
Network.IPv6DuplicateAddressDetection, config_parse_int, 0, offsetof(Network, ipv6_dad_transmits)
Network.IPv6HopLimit, config_parse_int, 0, offsetof(Network, ipv6_hop_limit)
+Network.ActiveSlave, config_parse_bool, 0, offsetof(Network, active_slave)
+Network.PrimarySlave, config_parse_bool, 0, offsetof(Network, primary_slave)
+Network.IPv4ProxyARP, config_parse_tristate, 0, offsetof(Network, proxy_arp)
Network.ProxyARP, config_parse_tristate, 0, offsetof(Network, proxy_arp)
+Network.IPv6ProxyNDPAddress, config_parse_ipv6_proxy_ndp_address, 0, 0
Network.BindCarrier, config_parse_strv, 0, offsetof(Network, bind_carrier)
Address.Address, config_parse_address, 0, 0
Address.Peer, config_parse_address, 0, 0
@@ -100,6 +104,7 @@ DHCP.RouteMetric, config_parse_unsigned,
DHCP.RouteTable, config_parse_dhcp_route_table, 0, offsetof(Network, dhcp_route_table)
DHCP.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone)
DHCP.IAID, config_parse_iaid, 0, offsetof(Network, iaid)
+DHCP.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port)
IPv6AcceptRA.UseDNS, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_dns)
IPv6AcceptRA.UseDomains, config_parse_dhcp_use_domains, 0, offsetof(Network, ipv6_accept_ra_use_domains)
IPv6AcceptRA.RouteTable, config_parse_dhcp_route_table, 0, offsetof(Network, ipv6_accept_ra_route_table)
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 042232fcac..fac42d8478 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -27,8 +27,8 @@
#include "fd-util.h"
#include "hostname-util.h"
#include "network-internal.h"
+#include "networkd-manager.h"
#include "networkd-network.h"
-#include "networkd.h"
#include "parse-util.h"
#include "set.h"
#include "stat-util.h"
@@ -36,6 +36,49 @@
#include "string-util.h"
#include "util.h"
+static void network_config_hash_func(const void *p, struct siphash *state) {
+ const NetworkConfigSection *c = p;
+
+ siphash24_compress(c->filename, strlen(c->filename), state);
+ siphash24_compress(&c->line, sizeof(c->line), state);
+}
+
+static int network_config_compare_func(const void *a, const void *b) {
+ const NetworkConfigSection *x = a, *y = b;
+ int r;
+
+ r = strcmp(x->filename, y->filename);
+ if (r != 0)
+ return r;
+
+ return y->line - x->line;
+}
+
+const struct hash_ops network_config_hash_ops = {
+ .hash = network_config_hash_func,
+ .compare = network_config_compare_func,
+};
+
+int network_config_section_new(const char *filename, unsigned line, NetworkConfigSection **s) {
+ NetworkConfigSection *cs;
+
+ cs = malloc0(offsetof(NetworkConfigSection, filename) + strlen(filename) + 1);
+ if (!cs)
+ return -ENOMEM;
+
+ strcpy(cs->filename, filename);
+ cs->line = line;
+
+ *s = cs;
+ cs = NULL;
+
+ return 0;
+}
+
+void network_config_section_free(NetworkConfigSection *cs) {
+ free(cs);
+}
+
static int network_load_one(Manager *manager, const char *filename) {
_cleanup_network_free_ Network *network = NULL;
_cleanup_fclose_ FILE *file = NULL;
@@ -70,16 +113,17 @@ static int network_load_one(Manager *manager, const char *filename) {
LIST_HEAD_INIT(network->static_addresses);
LIST_HEAD_INIT(network->static_routes);
LIST_HEAD_INIT(network->static_fdb_entries);
+ LIST_HEAD_INIT(network->ipv6_proxy_ndp_addresses);
network->stacked_netdevs = hashmap_new(&string_hash_ops);
if (!network->stacked_netdevs)
return log_oom();
- network->addresses_by_section = hashmap_new(NULL);
+ network->addresses_by_section = hashmap_new(&network_config_hash_ops);
if (!network->addresses_by_section)
return log_oom();
- network->routes_by_section = hashmap_new(NULL);
+ network->routes_by_section = hashmap_new(&network_config_hash_ops);
if (!network->routes_by_section)
return log_oom();
@@ -152,6 +196,7 @@ static int network_load_one(Manager *manager, const char *filename) {
"DHCPv4\0" /* compat */
"DHCPServer\0"
"IPv6AcceptRA\0"
+ "IPv6NDPProxyAddress\0"
"Bridge\0"
"BridgeFDB\0"
"BridgeVLAN\0",
@@ -224,6 +269,7 @@ void network_free(Network *network) {
Route *route;
Address *address;
FdbEntry *fdb_entry;
+ IPv6ProxyNDPAddress *ipv6_proxy_ndp_address;
Iterator i;
if (!network)
@@ -244,7 +290,7 @@ void network_free(Network *network) {
free(network->mac);
strv_free(network->ntp);
- strv_free(network->dns);
+ free(network->dns);
strv_free(network->search_domains);
strv_free(network->route_domains);
strv_free(network->bind_carrier);
@@ -268,6 +314,9 @@ void network_free(Network *network) {
while ((fdb_entry = network->static_fdb_entries))
fdb_entry_free(fdb_entry);
+ while ((ipv6_proxy_ndp_address = network->ipv6_proxy_ndp_addresses))
+ ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address);
+
hashmap_free(network->addresses_by_section);
hashmap_free(network->routes_by_section);
hashmap_free(network->fdb_entries_by_section);
@@ -368,10 +417,9 @@ int network_get(Manager *manager, struct udev_device *device,
return -ENOENT;
}
-int network_apply(Manager *manager, Network *network, Link *link) {
+int network_apply(Network *network, Link *link) {
int r;
- assert(manager);
assert(network);
assert(link);
@@ -380,7 +428,7 @@ int network_apply(Manager *manager, Network *network, Link *link) {
if (network->ipv4ll_route) {
Route *route;
- r = route_new_static(network, 0, &route);
+ r = route_new_static(network, NULL, 0, &route);
if (r < 0)
return r;
@@ -397,7 +445,7 @@ int network_apply(Manager *manager, Network *network, Link *link) {
route->protocol = RTPROT_STATIC;
}
- if (!strv_isempty(network->dns) ||
+ if (network->n_dns > 0 ||
!strv_isempty(network->ntp) ||
!strv_isempty(network->search_domains) ||
!strv_isempty(network->route_domains))
@@ -910,13 +958,14 @@ int config_parse_dhcp_server_dns(
struct in_addr a, *m;
r = extract_first_word(&p, &w, NULL, 0);
+ if (r == -ENOMEM)
+ return log_oom();
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract word, ignoring: %s", rvalue);
return 0;
}
-
if (r == 0)
- return 0;
+ break;
if (inet_pton(AF_INET, w, &a) <= 0) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse DNS server address, ignoring: %s", w);
@@ -930,6 +979,8 @@ int config_parse_dhcp_server_dns(
m[n->n_dhcp_server_dns++] = a;
n->dhcp_server_dns = m;
}
+
+ return 0;
}
int config_parse_dhcp_server_ntp(
@@ -957,11 +1008,12 @@ int config_parse_dhcp_server_ntp(
struct in_addr a, *m;
r = extract_first_word(&p, &w, NULL, 0);
+ if (r == -ENOMEM)
+ return log_oom();
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract word, ignoring: %s", rvalue);
return 0;
}
-
if (r == 0)
return 0;
@@ -1001,29 +1053,35 @@ int config_parse_dns(
for (;;) {
_cleanup_free_ char *w = NULL;
union in_addr_union a;
+ struct in_addr_data *m;
int family;
- r = extract_first_word(&rvalue, &w, WHITESPACE, EXTRACT_QUOTES|EXTRACT_RETAIN_ESCAPE);
- if (r == 0)
- break;
+ r = extract_first_word(&rvalue, &w, NULL, 0);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
break;
}
+ if (r == 0)
+ break;
r = in_addr_from_string_auto(w, &family, &a);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse dns server address, ignoring: %s", w);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse dns server address, ignoring: %s", w);
continue;
}
- r = strv_consume(&n->dns, w);
- if (r < 0)
+ m = realloc(n->dns, (n->n_dns + 1) * sizeof(struct in_addr_data));
+ if (!m)
return log_oom();
- w = NULL;
+ m[n->n_dns++] = (struct in_addr_data) {
+ .family = family,
+ .address = a,
+ };
+
+ n->dns = m;
}
return 0;
@@ -1085,6 +1143,59 @@ int config_parse_dnssec_negative_trust_anchors(
return 0;
}
+int config_parse_ntp(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ char ***l = data;
+ int r;
+
+ assert(l);
+ assert(lvalue);
+ assert(rvalue);
+
+ if (isempty(rvalue)) {
+ *l = strv_free(*l);
+ return 0;
+ }
+
+ for (;;) {
+ _cleanup_free_ char *w = NULL;
+
+ r = extract_first_word(&rvalue, &w, NULL, 0);
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract NTP server name, ignoring: %s", rvalue);
+ break;
+ }
+ if (r == 0)
+ break;
+
+ r = dns_name_is_valid_or_address(w);
+ if (r <= 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "%s is not a valid domain name or IP address, ignoring.", w);
+ continue;
+ }
+
+ r = strv_push(l, w);
+ if (r < 0)
+ return log_oom();
+
+ w = NULL;
+ }
+
+ return 0;
+}
+
int config_parse_dhcp_route_table(const char *unit,
const char *filename,
unsigned line,
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index 09c3b3a3ae..4ce066a764 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -31,9 +31,10 @@
#include "networkd-brvlan.h"
#include "networkd-fdb.h"
#include "networkd-lldp-tx.h"
-#include "networkd-netdev.h"
+#include "networkd-ipv6-proxy-ndp.h"
#include "networkd-route.h"
#include "networkd-util.h"
+#include "netdev/netdev.h"
#define DHCP_ROUTE_METRIC 1024
#define IPV4LL_ROUTE_METRIC 2048
@@ -81,6 +82,17 @@ typedef struct DUID {
uint8_t raw_data[MAX_DUID_LEN];
} DUID;
+typedef struct NetworkConfigSection {
+ unsigned line;
+ char filename[];
+} NetworkConfigSection;
+
+int network_config_section_new(const char *filename, unsigned line, NetworkConfigSection **s);
+void network_config_section_free(NetworkConfigSection *network);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(NetworkConfigSection*, network_config_section_free);
+#define _cleanup_network_config_section_free_ _cleanup_(network_config_section_freep)
+
typedef struct Manager Manager;
struct Network {
@@ -112,18 +124,19 @@ struct Network {
DCHPClientIdentifier dhcp_client_identifier;
char *dhcp_vendor_class_identifier;
char *dhcp_hostname;
- bool dhcp_use_dns;
- bool dhcp_use_ntp;
- bool dhcp_use_mtu;
- bool dhcp_use_hostname;
- DHCPUseDomains dhcp_use_domains;
+ unsigned dhcp_route_metric;
+ uint32_t dhcp_route_table;
+ uint16_t dhcp_client_port;
bool dhcp_send_hostname;
bool dhcp_broadcast;
bool dhcp_critical;
+ bool dhcp_use_dns;
+ bool dhcp_use_ntp;
+ bool dhcp_use_mtu;
bool dhcp_use_routes;
bool dhcp_use_timezone;
- unsigned dhcp_route_metric;
- uint32_t dhcp_route_table;
+ bool dhcp_use_hostname;
+ DHCPUseDomains dhcp_use_domains;
/* DHCP Server Support */
bool dhcp_server;
@@ -166,6 +179,8 @@ struct Network {
int proxy_arp;
bool ipv6_accept_ra_use_dns;
+ bool active_slave;
+ bool primary_slave;
DHCPUseDomains ipv6_accept_ra_use_domains;
uint32_t ipv6_accept_ra_route_table;
@@ -173,8 +188,9 @@ struct Network {
IPv6PrivacyExtensions ipv6_privacy_extensions;
struct ether_addr *mac;
- unsigned mtu;
+ size_t mtu;
int arp;
+ bool unmanaged;
uint32_t iaid;
DUID duid;
@@ -184,16 +200,21 @@ struct Network {
LIST_HEAD(Address, static_addresses);
LIST_HEAD(Route, static_routes);
LIST_HEAD(FdbEntry, static_fdb_entries);
+ LIST_HEAD(IPv6ProxyNDPAddress, ipv6_proxy_ndp_addresses);
unsigned n_static_addresses;
unsigned n_static_routes;
unsigned n_static_fdb_entries;
+ unsigned n_ipv6_proxy_ndp_addresses;
Hashmap *addresses_by_section;
Hashmap *routes_by_section;
Hashmap *fdb_entries_by_section;
- char **search_domains, **route_domains, **dns, **ntp, **bind_carrier;
+ struct in_addr_data *dns;
+ unsigned n_dns;
+
+ char **search_domains, **route_domains, **ntp, **bind_carrier;
ResolveSupport llmnr;
ResolveSupport mdns;
@@ -212,7 +233,7 @@ int network_load(Manager *manager);
int network_get_by_name(Manager *manager, const char *name, Network **ret);
int network_get(Manager *manager, struct udev_device *device, const char *ifname, const struct ether_addr *mac, Network **ret);
-int network_apply(Manager *manager, Network *network, Link *link);
+int network_apply(Network *network, Link *link);
bool network_has_static_ipv6_addresses(Network *network);
@@ -232,6 +253,7 @@ int config_parse_dnssec_negative_trust_anchors(const char *unit, const char *fil
int config_parse_dhcp_use_domains(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_lldp_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_dhcp_route_table(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_ntp(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
/* Legacy IPv4LL support */
int config_parse_ipv4ll(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c
index 6f60ee5e31..570083f180 100644
--- a/src/network/networkd-route.c
+++ b/src/network/networkd-route.c
@@ -21,8 +21,8 @@
#include "conf-parser.h"
#include "in-addr-util.h"
#include "netlink-util.h"
+#include "networkd-manager.h"
#include "networkd-route.h"
-#include "networkd.h"
#include "parse-util.h"
#include "set.h"
#include "string-util.h"
@@ -77,15 +77,21 @@ int route_new(Route **ret) {
return 0;
}
-int route_new_static(Network *network, unsigned section, Route **ret) {
+int route_new_static(Network *network, const char *filename, unsigned section_line, Route **ret) {
+ _cleanup_network_config_section_free_ NetworkConfigSection *n = NULL;
_cleanup_route_free_ Route *route = NULL;
int r;
assert(network);
assert(ret);
+ assert(!!filename == (section_line > 0));
- if (section) {
- route = hashmap_get(network->routes_by_section, UINT_TO_PTR(section));
+ if (filename) {
+ r = network_config_section_new(filename, section_line, &n);
+ if (r < 0)
+ return r;
+
+ route = hashmap_get(network->routes_by_section, n);
if (route) {
*ret = route;
route = NULL;
@@ -103,10 +109,11 @@ int route_new_static(Network *network, unsigned section, Route **ret) {
route->protocol = RTPROT_STATIC;
- if (section) {
- route->section = section;
+ if (filename) {
+ route->section = n;
+ n = NULL;
- r = hashmap_put(network->routes_by_section, UINT_TO_PTR(route->section), route);
+ r = hashmap_put(network->routes_by_section, route->section, route);
if (r < 0)
return r;
}
@@ -132,9 +139,11 @@ void route_free(Route *route) {
route->network->n_static_routes--;
if (route->section)
- hashmap_remove(route->network->routes_by_section, UINT_TO_PTR(route->section));
+ hashmap_remove(route->network->routes_by_section, route->section);
}
+ network_config_section_free(route->section);
+
if (route->link) {
set_remove(route->link->routes, route);
set_remove(route->link->routes_foreign, route);
@@ -605,6 +614,20 @@ int route_configure(
if (r < 0)
return log_error_errno(r, "Could not append RTA_OIF attribute: %m");
+ r = sd_netlink_message_open_container(req, RTA_METRICS);
+ if (r < 0)
+ return log_error_errno(r, "Could not append RTA_METRICS attribute: %m");
+
+ if (route->mtu > 0) {
+ r = sd_netlink_message_append_u32(req, RTAX_MTU, route->mtu);
+ if (r < 0)
+ return log_error_errno(r, "Could not append RTAX_MTU attribute: %m");
+ }
+
+ r = sd_netlink_message_close_container(req);
+ if (r < 0)
+ return log_error_errno(r, "Could not append RTA_METRICS attribute: %m");
+
r = sd_netlink_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
if (r < 0)
return log_error_errno(r, "Could not send rtnetlink message: %m");
@@ -659,10 +682,10 @@ int config_parse_gateway(const char *unit,
if (streq(section, "Network")) {
/* we are not in an Route section, so treat
* this as the special '0' section */
- section_line = 0;
- }
+ r = route_new_static(network, NULL, 0, &n);
+ } else
+ r = route_new_static(network, filename, section_line, &n);
- r = route_new_static(network, section_line, &n);
if (r < 0)
return r;
@@ -701,7 +724,7 @@ int config_parse_preferred_src(const char *unit,
assert(rvalue);
assert(data);
- r = route_new_static(network, section_line, &n);
+ r = route_new_static(network, filename, section_line, &n);
if (r < 0)
return r;
@@ -743,7 +766,7 @@ int config_parse_destination(const char *unit,
assert(rvalue);
assert(data);
- r = route_new_static(network, section_line, &n);
+ r = route_new_static(network, filename, section_line, &n);
if (r < 0)
return r;
@@ -821,7 +844,7 @@ int config_parse_route_priority(const char *unit,
assert(rvalue);
assert(data);
- r = route_new_static(network, section_line, &n);
+ r = route_new_static(network, filename, section_line, &n);
if (r < 0)
return r;
@@ -858,7 +881,7 @@ int config_parse_route_scope(const char *unit,
assert(rvalue);
assert(data);
- r = route_new_static(network, section_line, &n);
+ r = route_new_static(network, filename, section_line, &n);
if (r < 0)
return r;
@@ -899,7 +922,7 @@ int config_parse_route_table(const char *unit,
assert(rvalue);
assert(data);
- r = route_new_static(network, section_line, &n);
+ r = route_new_static(network, filename, section_line, &n);
if (r < 0)
return r;
diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h
index d4e4dbac0b..4ebfa0f0bd 100644
--- a/src/network/networkd-route.h
+++ b/src/network/networkd-route.h
@@ -20,12 +20,13 @@
***/
typedef struct Route Route;
+typedef struct NetworkConfigSection NetworkConfigSection;
#include "networkd-network.h"
struct Route {
Network *network;
- unsigned section;
+ NetworkConfigSection *section;
Link *link;
@@ -37,6 +38,7 @@ struct Route {
unsigned char tos;
uint32_t priority; /* note that ip(8) calls this 'metric' */
uint32_t table;
+ uint32_t mtu;
unsigned char pref;
unsigned flags;
@@ -51,7 +53,7 @@ struct Route {
LIST_FIELDS(Route, routes);
};
-int route_new_static(Network *network, unsigned section, Route **ret);
+int route_new_static(Network *network, const char *filename, unsigned section_line, Route **ret);
int route_new(Route **ret);
void route_free(Route *route);
int route_configure(Route *route, Link *link, sd_netlink_message_handler_t callback);
diff --git a/src/network/networkd.c b/src/network/networkd.c
index c8f81a2ca6..fe60f1ed14 100644
--- a/src/network/networkd.c
+++ b/src/network/networkd.c
@@ -18,14 +18,16 @@
***/
#include "sd-daemon.h"
+#include "sd-event.h"
#include "capability-util.h"
-#include "networkd.h"
#include "networkd-conf.h"
+#include "networkd-manager.h"
#include "signal-util.h"
#include "user-util.h"
int main(int argc, char *argv[]) {
+ sd_event *event = NULL;
_cleanup_manager_free_ Manager *m = NULL;
const char *user = "systemd-network";
uid_t uid;
@@ -78,7 +80,15 @@ int main(int argc, char *argv[]) {
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
- r = manager_new(&m);
+ r = sd_event_default(&event);
+ if (r < 0)
+ goto out;
+
+ sd_event_set_watchdog(event, true);
+ sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
+ sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);
+
+ r = manager_new(&m, event);
if (r < 0) {
log_error_errno(r, "Could not create manager: %m");
goto out;
@@ -118,22 +128,29 @@ int main(int argc, char *argv[]) {
goto out;
}
+ r = manager_start(m);
+ if (r < 0) {
+ log_error_errno(r, "Could not start manager: %m");
+ goto out;
+ }
+
log_info("Enumeration completed");
sd_notify(false,
"READY=1\n"
"STATUS=Processing requests...");
- r = manager_run(m);
+ r = sd_event_loop(event);
if (r < 0) {
log_error_errno(r, "Event loop failed: %m");
goto out;
}
-
out:
sd_notify(false,
"STOPPING=1\n"
"STATUS=Shutting down...");
+ sd_event_unref(event);
+
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/src/network/systemd-networkd.pkla b/src/network/systemd-networkd.pkla
new file mode 100644
index 0000000000..fb257d933b
--- /dev/null
+++ b/src/network/systemd-networkd.pkla
@@ -0,0 +1,4 @@
+[Allow systemd-networkd to set timezone and transient hostname]
+Identity=unix-user:systemd-network
+Action=org.freedesktop.hostname1.set-hostname;org.freedesktop.timedate1.set-timezone;
+ResultAny=yes
diff --git a/src/network/systemd-networkd.rules b/src/network/systemd-networkd.rules
new file mode 100644
index 0000000000..2e4bc42bfb
--- /dev/null
+++ b/src/network/systemd-networkd.rules
@@ -0,0 +1,8 @@
+// Allow systemd-networkd to set timezone and transient hostname
+polkit.addRule(function(action, subject) {
+ if ((action.id == "org.freedesktop.hostname1.set-hostname" ||
+ action.id == "org.freedesktop.timedate1.set-timezone") &&
+ subject.user == "systemd-network") {
+ return polkit.Result.YES;
+ }
+});
diff --git a/src/network/test-network-tables.c b/src/network/test-network-tables.c
index adbe09a5e1..eee91d11d2 100644
--- a/src/network/test-network-tables.c
+++ b/src/network/test-network-tables.c
@@ -2,9 +2,11 @@
#include "dhcp6-protocol.h"
#include "ethtool-util.h"
#include "netlink-internal.h"
-#include "networkd-netdev-bond.h"
-#include "networkd-netdev-macvlan.h"
-#include "networkd.h"
+#include "netdev/bond.h"
+#include "netdev/ipvlan.h"
+#include "netdev/macvlan.h"
+#include "networkd-link.h"
+#include "networkd-util.h"
#include "test-tables.h"
int main(int argc, char **argv) {
diff --git a/src/network/test-network.c b/src/network/test-network.c
index 855646173f..64d2f23fc1 100644
--- a/src/network/test-network.c
+++ b/src/network/test-network.c
@@ -20,7 +20,7 @@
#include "alloc-util.h"
#include "dhcp-lease-internal.h"
#include "network-internal.h"
-#include "networkd.h"
+#include "networkd-manager.h"
static void test_deserialize_in_addr(void) {
_cleanup_free_ struct in_addr *addresses = NULL;
@@ -186,6 +186,7 @@ static void test_address_equality(void) {
int main(void) {
_cleanup_manager_free_ Manager *manager = NULL;
+ sd_event *event;
struct udev *udev;
struct udev_device *loopback;
int r;
@@ -194,11 +195,16 @@ int main(void) {
test_deserialize_dhcp_routes();
test_address_equality();
- assert_se(manager_new(&manager) >= 0);
+ r = sd_event_default(&event);
+ assert_se(r >= 0);
+
+ assert_se(manager_new(&manager, event) >= 0);
r = test_load_config(manager);
- if (r == -EPERM)
+ if (r == -EPERM) {
+ sd_event_unref(event);
return EXIT_TEST_SKIP;
+ }
udev = udev_new();
assert_se(udev);
@@ -213,4 +219,5 @@ int main(void) {
udev_device_unref(loopback);
udev_unref(udev);
+ sd_event_unref(event);
}
diff --git a/src/network/wait-online/Makefile b/src/network/wait-online/Makefile
new file mode 120000
index 0000000000..94aaae2c4d
--- /dev/null
+++ b/src/network/wait-online/Makefile
@@ -0,0 +1 @@
+../../Makefile \ No newline at end of file
diff --git a/src/network/networkd-wait-online-link.c b/src/network/wait-online/link.c
index e63ba07e90..bd8578cf93 100644
--- a/src/network/networkd-wait-online-link.c
+++ b/src/network/wait-online/link.c
@@ -21,7 +21,9 @@
#include "sd-network.h"
#include "alloc-util.h"
-#include "networkd-wait-online-link.h"
+#include "hashmap.h"
+#include "link.h"
+#include "manager.h"
#include "string-util.h"
int link_new(Manager *m, Link **ret, int ifindex, const char *ifname) {
diff --git a/src/network/networkd-wait-online-link.h b/src/network/wait-online/link.h
index dc35085c55..c846e60c45 100644
--- a/src/network/networkd-wait-online-link.h
+++ b/src/network/wait-online/link.h
@@ -20,9 +20,10 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-typedef struct Link Link;
+#include "sd-netlink.h"
-#include "networkd-wait-online.h"
+typedef struct Link Link;
+typedef struct Manager Manager;
struct Link {
Manager *manager;
diff --git a/src/network/networkd-wait-online-manager.c b/src/network/wait-online/manager.c
index 725b3310dd..d51b0a59d6 100644
--- a/src/network/networkd-wait-online-manager.c
+++ b/src/network/wait-online/manager.c
@@ -22,10 +22,10 @@
#include <fnmatch.h>
#include "alloc-util.h"
+#include "link.h"
+#include "manager.h"
#include "netlink-util.h"
#include "network-internal.h"
-#include "networkd-wait-online-link.h"
-#include "networkd-wait-online.h"
#include "time-util.h"
#include "util.h"
diff --git a/src/network/networkd-wait-online.h b/src/network/wait-online/manager.h
index f91995c306..052f6b9780 100644
--- a/src/network/networkd-wait-online.h
+++ b/src/network/wait-online/manager.h
@@ -26,8 +26,7 @@
#include "hashmap.h"
typedef struct Manager Manager;
-
-#include "networkd-wait-online-link.h"
+typedef struct Link Link;
struct Manager {
Hashmap *links;
diff --git a/src/network/networkd-wait-online.c b/src/network/wait-online/wait-online.c
index 3220c4b7ef..268cbdb629 100644
--- a/src/network/networkd-wait-online.c
+++ b/src/network/wait-online/wait-online.c
@@ -22,7 +22,7 @@
#include "sd-daemon.h"
-#include "networkd-wait-online.h"
+#include "manager.h"
#include "signal-util.h"
#include "strv.h"
diff --git a/src/notify/notify.c b/src/notify/notify.c
index 49f97c61d9..70b6f868b9 100644
--- a/src/notify/notify.c
+++ b/src/notify/notify.c
@@ -27,7 +27,7 @@
#include "alloc-util.h"
#include "env-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "log.h"
#include "parse-util.h"
#include "string-util.h"
diff --git a/src/nspawn/nspawn-cgroup.c b/src/nspawn/nspawn-cgroup.c
index a226866207..7c4fbc5055 100644
--- a/src/nspawn/nspawn-cgroup.c
+++ b/src/nspawn/nspawn-cgroup.c
@@ -148,7 +148,7 @@ static int sync_cgroup(pid_t pid, CGroupUnified outer_cgver, CGroupUnified inner
if (!mkdtemp(mountpoint))
return log_error_errno(errno, LOG_PFIX ": failed to create temporary mount point for container cgroup hierarchy: %m", pid);
- if (outer_cgver >= CGROUP_UNIFIED_SYSTEMD) {
+ if (outer_cgver >= CGROUP_UNIFIED_SYSTEMD232) {
/* host: v2 ; container: v1 */
inner_hier = "?:name=systemd";
r = mount_verbose(LOG_ERR, "cgroup", mountpoint, "cgroup",
@@ -277,7 +277,7 @@ int cgroup_setup(pid_t pid, CGroupUnified outer_cgver, CGroupUnified inner_cgver
if (outer_cgver == CGROUP_UNIFIED_UNKNOWN)
return 0;
- if ((outer_cgver >= CGROUP_UNIFIED_SYSTEMD) != (inner_cgver >= CGROUP_UNIFIED_SYSTEMD)) {
+ if ((outer_cgver >= CGROUP_UNIFIED_SYSTEMD232) != (inner_cgver >= CGROUP_UNIFIED_SYSTEMD232)) {
/* sync the name=systemd hierarchy with the unified hierarchy */
r = sync_cgroup(pid, outer_cgver, inner_cgver, uid_shift);
if (r < 0)
@@ -297,7 +297,7 @@ int cgroup_setup(pid_t pid, CGroupUnified outer_cgver, CGroupUnified inner_cgver
return log_error_errno(r, "Unable to count the processes in the container's cgroup: %m");
/* This applies only to the unified hierarchy */
- if (outer_cgver >= CGROUP_UNIFIED_SYSTEMD && inner_cgver >= CGROUP_UNIFIED_SYSTEMD) {
+ if (outer_cgver >= CGROUP_UNIFIED_SYSTEMD232 && inner_cgver >= CGROUP_UNIFIED_SYSTEMD232) {
if (set_size(peers) == 2 && set_contains(peers, PID_TO_PTR(getpid()))) {
char *tmp;
@@ -528,17 +528,23 @@ static int cgroup_decide_mounts_sd_y_cgns(
skip_controllers:
switch (inner_cgver) {
- case CGROUP_UNIFIED_NONE:
- if (!cgmount_add(&mounts, CGMOUNT_CGROUP1, "none,name=systmed,xattr", "systemd"))
+ default:
+ case CGROUP_UNIFIED_UNKNOWN:
+ assert_not_reached("unknown inner_cgver");
+ case CGROUP_UNIFIED_ALL:
+ assert_not_reached("cgroup v2 requested in cgroup v1 function");
+ case CGROUP_UNIFIED_SYSTEMD232:
+ if (!cgmount_add(&mounts, CGMOUNT_CGROUP2, "", "systemd"))
return log_oom();
break;
- case CGROUP_UNIFIED_SYSTEMD:
- if (!cgmount_add(&mounts, CGMOUNT_CGROUP2, "", "systemd"))
+ case CGROUP_UNIFIED_SYSTEMD233:
+ if (!cgmount_add(&mounts, CGMOUNT_CGROUP2, "", "unified"))
+ return log_oom();
+ /* fall through */
+ case CGROUP_UNIFIED_NONE:
+ if (!cgmount_add(&mounts, CGMOUNT_CGROUP1, "none,name=systemd,xattr", "systemd"))
return log_oom();
break;
- default:
- assert_not_reached("non-legacy cgroup version desired in legacy setup function");
- return -EINVAL;
}
*ret_mounts = mounts;
@@ -609,17 +615,23 @@ static int cgroup_decide_mounts_sd_n_cgns(
skip_controllers:
switch (inner_cgver) {
- case CGROUP_UNIFIED_NONE:
- if (!cgmount_add(&mounts, CGMOUNT_CGROUP1, "none,name=systmed,xattr", "systemd"))
+ default:
+ case CGROUP_UNIFIED_UNKNOWN:
+ assert_not_reached("unknown inner_cgver");
+ case CGROUP_UNIFIED_ALL:
+ assert_not_reached("cgroup v2 requested in cgroup v1 function");
+ case CGROUP_UNIFIED_SYSTEMD232:
+ if (!cgmount_add(&mounts, CGMOUNT_CGROUP2, "", "systemd"))
return log_oom();
break;
- case CGROUP_UNIFIED_SYSTEMD:
- if (!cgmount_add(&mounts, CGMOUNT_CGROUP2, "", "systemd"))
+ case CGROUP_UNIFIED_SYSTEMD233:
+ if (!cgmount_add(&mounts, CGMOUNT_CGROUP2, "", "unified"))
+ return log_oom();
+ /* fall through */
+ case CGROUP_UNIFIED_NONE:
+ if (!cgmount_add(&mounts, CGMOUNT_CGROUP1, "none,name=systemd,xattr", "systemd"))
return log_oom();
break;
- default:
- assert_not_reached("non-legacy cgroup version desired in legacy setup function");
- return -EINVAL;
}
*ret_mounts = mounts;
@@ -634,10 +646,14 @@ int cgroup_decide_mounts(
bool use_cgns) {
switch (inner_cgver) {
+ default:
+ case CGROUP_UNIFIED_UNKNOWN:
+ assert_not_reached("unknown inner_cgver");
case CGROUP_UNIFIED_INHERIT:
return cgroup_decide_mounts_inherit(ret_mounts);
case CGROUP_UNIFIED_NONE:
- case CGROUP_UNIFIED_SYSTEMD:
+ case CGROUP_UNIFIED_SYSTEMD232:
+ case CGROUP_UNIFIED_SYSTEMD233:
/* Historically, if use_cgns, then this ran inside the container; if !use_cgns, then it ran outside.
* The use_cgns one had to be added because running inside the container, it couldn't look at the host
* '/sys'. Now that they both run outside the container again, I'm afraid to unify them because I'm
@@ -650,9 +666,6 @@ int cgroup_decide_mounts(
if (!cgmount_add(ret_mounts, CGMOUNT_CGROUP2, "cgroup", ""))
return log_oom();
return 0;
- default:
- assert_not_reached("Invalid cgroup ver requested");
- return -EINVAL;
}
}
@@ -717,10 +730,15 @@ static int cgroup_mount_cg(
return 0;
}
-int cgroup_mount_mounts(CGMounts m, FILE *cgfile, uid_t uid_shift, const char *selinux_apifs_context) {
+int cgroup_mount_mounts(
+ CGMounts m,
+ FILE *cgfile,
+ uid_t uid_shift,
+ const char *selinux_apifs_context) {
const bool use_cgns = cgfile == NULL;
const bool use_userns = uid_shift != UID_INVALID;
+ const char *cgroup_root = "/sys/fs/cgroup";
bool used_tmpfs = false;
@@ -729,7 +747,7 @@ int cgroup_mount_mounts(CGMounts m, FILE *cgfile, uid_t uid_shift, const char *s
const char *dst;
int r;
- dst = prefix_roota("/sys/fs/cgroup", m.mounts[i].dst);
+ dst = prefix_roota(cgroup_root, m.mounts[i].dst);
/* The checks here to see if things are already mounted are kind of primative. Perhaps they should
* actually check the statfs() f_type to verify that the thing mounted is what we want to be mounted
@@ -745,7 +763,7 @@ int cgroup_mount_mounts(CGMounts m, FILE *cgfile, uid_t uid_shift, const char *s
break;
case CGMOUNT_TMPFS:
used_tmpfs = true;
- r = path_is_mount_point(dst, AT_SYMLINK_FOLLOW);
+ r = path_is_mount_point(dst, NULL, path_equal(cgroup_root, dst) ? AT_SYMLINK_FOLLOW : 0);
if (r < 0)
return log_error_errno(r, "Failed to determine if %s is mounted already: %m", dst);
if (r > 0)
@@ -760,7 +778,7 @@ int cgroup_mount_mounts(CGMounts m, FILE *cgfile, uid_t uid_shift, const char *s
break;
case CGMOUNT_CGROUP1:
case CGMOUNT_CGROUP2:
- r = path_is_mount_point(dst, 0);
+ r = path_is_mount_point(dst, NULL, path_equal(cgroup_root, dst) ? AT_SYMLINK_FOLLOW : 0);
if (r < 0 && r != -ENOENT)
return log_error_errno(r, "Failed to determine if %s is mounted already: %m", dst);
if (r > 0) {
diff --git a/src/nspawn/nspawn-expose-ports.c b/src/nspawn/nspawn-expose-ports.c
index 86124b8779..bcaf0aaeaa 100644
--- a/src/nspawn/nspawn-expose-ports.c
+++ b/src/nspawn/nspawn-expose-ports.c
@@ -58,17 +58,17 @@ int expose_port_parse(ExposePort **l, const char *s) {
memcpy(v, e, split - e);
v[split - e] = 0;
- r = safe_atou16(v, &host_port);
- if (r < 0 || host_port <= 0)
+ r = parse_ip_port(v, &host_port);
+ if (r < 0)
return -EINVAL;
- r = safe_atou16(split + 1, &container_port);
+ r = parse_ip_port(split + 1, &container_port);
} else {
- r = safe_atou16(e, &container_port);
+ r = parse_ip_port(e, &container_port);
host_port = container_port;
}
- if (r < 0 || container_port <= 0)
+ if (r < 0)
return -EINVAL;
LIST_FOREACH(ports, p, *l)
diff --git a/src/nspawn/nspawn-gperf.gperf b/src/nspawn/nspawn-gperf.gperf
index 3231a48d5a..e5fdf63162 100644
--- a/src/nspawn/nspawn-gperf.gperf
+++ b/src/nspawn/nspawn-gperf.gperf
@@ -26,6 +26,7 @@ Exec.KillSignal, config_parse_signal, 0, offsetof(Settings,
Exec.Personality, config_parse_personality, 0, offsetof(Settings, personality)
Exec.MachineID, config_parse_id128, 0, offsetof(Settings, machine_id)
Exec.WorkingDirectory, config_parse_path, 0, offsetof(Settings, working_directory)
+Exec.PivotRoot, config_parse_pivot_root, 0, 0
Exec.PrivateUsers, config_parse_private_users, 0, 0
Exec.NotifyReady, config_parse_bool, 0, offsetof(Settings, notify_ready)
Files.ReadOnly, config_parse_tristate, 0, offsetof(Settings, read_only)
@@ -33,6 +34,8 @@ Files.Volatile, config_parse_volatile_mode, 0, offsetof(Settings,
Files.Bind, config_parse_bind, 0, 0
Files.BindReadOnly, config_parse_bind, 1, 0
Files.TemporaryFileSystem, config_parse_tmpfs, 0, 0
+Files.Overlay, config_parse_overlay, 0, 0
+Files.OverlayReadOnly, config_parse_overlay, 1, 0
Files.PrivateUsersChown, config_parse_tristate, 0, offsetof(Settings, userns_chown)
Network.Private, config_parse_tristate, 0, offsetof(Settings, private_network)
Network.Interface, config_parse_strv, 0, offsetof(Settings, network_interfaces)
diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c
index 68d844bfaf..ce052e7af1 100644
--- a/src/nspawn/nspawn-mount.c
+++ b/src/nspawn/nspawn-mount.c
@@ -47,7 +47,7 @@ CustomMount* custom_mount_add(CustomMount **l, unsigned *n, CustomMountType t) {
assert(t >= 0);
assert(t < _CUSTOM_MOUNT_TYPE_MAX);
- c = realloc(*l, (*n + 1) * sizeof(CustomMount));
+ c = realloc_multiply(*l, (*n + 1), sizeof(CustomMount));
if (!c)
return NULL;
@@ -75,13 +75,18 @@ void custom_mount_free_all(CustomMount *l, unsigned n) {
free(m->work_dir);
}
+ if (m->rm_rf_tmpdir) {
+ (void) rm_rf(m->rm_rf_tmpdir, REMOVE_ROOT|REMOVE_PHYSICAL);
+ free(m->rm_rf_tmpdir);
+ }
+
strv_free(m->lower);
}
free(l);
}
-int custom_mount_compare(const void *a, const void *b) {
+static int custom_mount_compare(const void *a, const void *b) {
const CustomMount *x = a, *y = b;
int r;
@@ -97,6 +102,109 @@ int custom_mount_compare(const void *a, const void *b) {
return 0;
}
+static bool source_path_is_valid(const char *p) {
+ assert(p);
+
+ if (*p == '+')
+ p++;
+
+ return path_is_absolute(p);
+}
+
+static char *resolve_source_path(const char *dest, const char *source) {
+
+ if (!source)
+ return NULL;
+
+ if (source[0] == '+')
+ return prefix_root(dest, source + 1);
+
+ return strdup(source);
+}
+
+int custom_mount_prepare_all(const char *dest, CustomMount *l, unsigned n) {
+ unsigned i;
+ int r;
+
+ /* Prepare all custom mounts. This will make source we know all temporary directories. This is called in the
+ * parent process, so that we know the temporary directories to remove on exit before we fork off the
+ * children. */
+
+ assert(l || n == 0);
+
+ /* Order the custom mounts, and make sure we have a working directory */
+ qsort_safe(l, n, sizeof(CustomMount), custom_mount_compare);
+
+ for (i = 0; i < n; i++) {
+ CustomMount *m = l + i;
+
+ if (m->source) {
+ char *s;
+
+ s = resolve_source_path(dest, m->source);
+ if (!s)
+ return log_oom();
+
+ free(m->source);
+ m->source = s;
+ } else {
+ /* No source specified? In that case, use a throw-away temporary directory in /var/tmp */
+
+ m->rm_rf_tmpdir = strdup("/var/tmp/nspawn-temp-XXXXXX");
+ if (!m->rm_rf_tmpdir)
+ return log_oom();
+
+ if (!mkdtemp(m->rm_rf_tmpdir)) {
+ m->rm_rf_tmpdir = mfree(m->rm_rf_tmpdir);
+ return log_error_errno(errno, "Failed to acquire temporary directory: %m");
+ }
+
+ m->source = strjoin(m->rm_rf_tmpdir, "/src");
+ if (!m->source)
+ return log_oom();
+
+ if (mkdir(m->source, 0755) < 0)
+ return log_error_errno(errno, "Failed to create %s: %m", m->source);
+ }
+
+ if (m->type == CUSTOM_MOUNT_OVERLAY) {
+ char **j;
+
+ STRV_FOREACH(j, m->lower) {
+ char *s;
+
+ s = resolve_source_path(dest, *j);
+ if (!s)
+ return log_oom();
+
+ free(*j);
+ *j = s;
+ }
+
+ if (m->work_dir) {
+ char *s;
+
+ s = resolve_source_path(dest, m->work_dir);
+ if (!s)
+ return log_oom();
+
+ free(m->work_dir);
+ m->work_dir = s;
+ } else {
+ assert(m->source);
+
+ r = tempfn_random(m->source, NULL, &m->work_dir);
+ if (r < 0)
+ return log_error_errno(r, "Failed to acquire working directory: %m");
+ }
+
+ (void) mkdir_label(m->work_dir, 0700);
+ }
+ }
+
+ return 0;
+}
+
int bind_mount_parse(CustomMount **l, unsigned *n, const char *s, bool read_only) {
_cleanup_free_ char *source = NULL, *destination = NULL, *opts = NULL;
const char *p = s;
@@ -111,20 +219,20 @@ int bind_mount_parse(CustomMount **l, unsigned *n, const char *s, bool read_only
return r;
if (r == 0)
return -EINVAL;
-
if (r == 1) {
- destination = strdup(source);
+ destination = strdup(source[0] == '+' ? source+1 : source);
if (!destination)
return -ENOMEM;
}
-
if (r == 2 && !isempty(p)) {
opts = strdup(p);
if (!opts)
return -ENOMEM;
}
- if (!path_is_absolute(source))
+ if (isempty(source))
+ source = NULL;
+ else if (!source_path_is_valid(source))
return -EINVAL;
if (!path_is_absolute(destination))
@@ -132,7 +240,7 @@ int bind_mount_parse(CustomMount **l, unsigned *n, const char *s, bool read_only
m = custom_mount_add(l, n, CUSTOM_MOUNT_BIND);
if (!m)
- return log_oom();
+ return -ENOMEM;
m->source = source;
m->destination = destination;
@@ -180,6 +288,71 @@ int tmpfs_mount_parse(CustomMount **l, unsigned *n, const char *s) {
return 0;
}
+int overlay_mount_parse(CustomMount **l, unsigned *n, const char *s, bool read_only) {
+ _cleanup_free_ char *upper = NULL, *destination = NULL;
+ _cleanup_strv_free_ char **lower = NULL;
+ CustomMount *m;
+ int k;
+
+ k = strv_split_extract(&lower, s, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
+ if (k < 0)
+ return k;
+ if (k < 2)
+ return -EADDRNOTAVAIL;
+ if (k == 2) {
+ /* If two parameters are specified, the first one is the lower, the second one the upper directory. And
+ * we'll also define the destination mount point the same as the upper. */
+
+ if (!source_path_is_valid(lower[0]) ||
+ !source_path_is_valid(lower[1]))
+ return -EINVAL;
+
+ upper = lower[1];
+ lower[1] = NULL;
+
+ destination = strdup(upper[0] == '+' ? upper+1 : upper); /* take the destination without "+" prefix */
+ if (!destination)
+ return -ENOMEM;
+ } else {
+ char **i;
+
+ /* If more than two parameters are specified, the last one is the destination, the second to last one
+ * the "upper", and all before that the "lower" directories. */
+
+ destination = lower[k - 1];
+ upper = lower[k - 2];
+ lower[k - 2] = NULL;
+
+ STRV_FOREACH(i, lower)
+ if (!source_path_is_valid(*i))
+ return -EINVAL;
+
+ /* If the upper directory is unspecified, then let's create it automatically as a throw-away directory
+ * in /var/tmp */
+ if (isempty(upper))
+ upper = NULL;
+ else if (!source_path_is_valid(upper))
+ return -EINVAL;
+
+ if (!path_is_absolute(destination))
+ return -EINVAL;
+ }
+
+ m = custom_mount_add(l, n, CUSTOM_MOUNT_OVERLAY);
+ if (!m)
+ return -ENOMEM;
+
+ m->destination = destination;
+ m->source = upper;
+ m->lower = lower;
+ m->read_only = read_only;
+
+ upper = destination = NULL;
+ lower = NULL;
+
+ return 0;
+}
+
int tmpfs_patch_options(
const char *options,
uid_t uid_shift,
@@ -189,11 +362,9 @@ int tmpfs_patch_options(
char *buf = NULL;
if (uid_shift != UID_INVALID) {
- if (options)
- (void) asprintf(&buf, "%s,uid=" UID_FMT ",gid=" UID_FMT, options, uid_shift, uid_shift);
- else
- (void) asprintf(&buf, "uid=" UID_FMT ",gid=" UID_FMT, uid_shift, uid_shift);
- if (!buf)
+ if (asprintf(&buf, "%s%suid=" UID_FMT ",gid=" UID_FMT,
+ options ?: "", options ? "," : "",
+ uid_shift, uid_shift) < 0)
return -ENOMEM;
options = buf;
@@ -203,16 +374,12 @@ int tmpfs_patch_options(
if (selinux_apifs_context) {
char *t;
- if (options)
- t = strjoin(options, ",context=\"", selinux_apifs_context, "\"", NULL);
- else
- t = strjoin("context=\"", selinux_apifs_context, "\"", NULL);
- if (!t) {
- free(buf);
+ t = strjoin(options ?: "", options ? "," : "",
+ "context=\"", selinux_apifs_context, "\"");
+ free(buf);
+ if (!t)
return -ENOMEM;
- }
- free(buf);
buf = t;
}
#endif
@@ -227,9 +394,10 @@ int tmpfs_patch_options(
return !!buf;
}
-int mount_sysfs(const char *dest) {
+int mount_sysfs(const char *dest, MountSettingsMask mount_settings) {
const char *full, *top, *x;
int r;
+ unsigned long extra_flags = 0;
top = prefix_roota(dest, "/sys");
r = path_check_fstype(top, SYSFS_MAGIC);
@@ -246,8 +414,11 @@ int mount_sysfs(const char *dest) {
(void) mkdir(full, 0755);
+ if (mount_settings & MOUNT_APPLY_APIVFS_RO)
+ extra_flags |= MS_RDONLY;
+
r = mount_verbose(LOG_ERR, "sysfs", full, "sysfs",
- MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
+ MS_NOSUID|MS_NOEXEC|MS_NODEV|extra_flags, NULL);
if (r < 0)
return r;
@@ -269,7 +440,7 @@ int mount_sysfs(const char *dest) {
return r;
r = mount_verbose(LOG_ERR, NULL, to, NULL,
- MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, NULL);
+ MS_BIND|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT|extra_flags, NULL);
if (r < 0)
return r;
}
@@ -300,10 +471,10 @@ int mount_sysfs(const char *dest) {
}
return mount_verbose(LOG_ERR, NULL, top, NULL,
- MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, NULL);
+ MS_BIND|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT|extra_flags, NULL);
}
-static int mkdir_userns(const char *path, mode_t mode, bool in_userns, uid_t uid_shift) {
+static int mkdir_userns(const char *path, mode_t mode, uid_t uid_shift) {
int r;
assert(path);
@@ -312,16 +483,17 @@ static int mkdir_userns(const char *path, mode_t mode, bool in_userns, uid_t uid
if (r < 0 && errno != EEXIST)
return -errno;
- if (!in_userns) {
- r = lchown(path, uid_shift, uid_shift);
- if (r < 0)
- return -errno;
- }
+ if (uid_shift == UID_INVALID)
+ return 0;
+
+ r = lchown(path, uid_shift, uid_shift);
+ if (r < 0)
+ return -errno;
return 0;
}
-static int mkdir_userns_p(const char *prefix, const char *path, mode_t mode, bool in_userns, uid_t uid_shift) {
+static int mkdir_userns_p(const char *prefix, const char *path, mode_t mode, uid_t uid_shift) {
const char *p, *e;
int r;
@@ -348,17 +520,16 @@ static int mkdir_userns_p(const char *prefix, const char *path, mode_t mode, boo
if (prefix && path_startswith(prefix, t))
continue;
- r = mkdir_userns(t, mode, in_userns, uid_shift);
+ r = mkdir_userns(t, mode, uid_shift);
if (r < 0)
return r;
}
- return mkdir_userns(path, mode, in_userns, uid_shift);
+ return mkdir_userns(path, mode, uid_shift);
}
int mount_all(const char *dest,
- bool in_userns,
- bool use_netns,
+ MountSettingsMask mount_settings,
uid_t uid_shift,
const char *selinux_apifs_context) {
@@ -368,48 +539,59 @@ int mount_all(const char *dest,
const char *type;
const char *options;
unsigned long flags;
- bool fatal;
- bool in_userns;
- bool use_netns;
+ MountSettingsMask mount_settings;
} MountPoint;
static const MountPoint mount_table[] = {
- { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true, true, false },
- { "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND, true, true, false }, /* Bind mount first ...*/
- { "/proc/sys/net", "/proc/sys/net", NULL, NULL, MS_BIND, true, true, true }, /* (except for this) */
- { NULL, "/proc/sys", NULL, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, true, true, false }, /* ... then, make it r/o */
- { "/proc/sysrq-trigger", "/proc/sysrq-trigger", NULL, NULL, MS_BIND, false, true, false }, /* Bind mount first ...*/
- { NULL, "/proc/sysrq-trigger", NULL, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, false, true, false }, /* ... then, make it r/o */
- { "tmpfs", "/sys", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV, true, false, true },
- { "sysfs", "/sys", "sysfs", NULL, MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, true, false, false },
- { "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME, true, false, false },
- { "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true, false, false },
- { "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true, false, false },
- { "tmpfs", "/tmp", "tmpfs", "mode=1777", MS_STRICTATIME, true, false, false },
+ /* inner child mounts */
+ { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, MOUNT_FATAL|MOUNT_IN_USERNS },
+ { "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND, MOUNT_FATAL|MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO }, /* Bind mount first ... */
+ { "/proc/sys/net", "/proc/sys/net", NULL, NULL, MS_BIND, MOUNT_FATAL|MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO|MOUNT_APPLY_APIVFS_NETNS }, /* (except for this) */
+ { NULL, "/proc/sys", NULL, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, MOUNT_FATAL|MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO }, /* ... then, make it r/o */
+ { "/proc/sysrq-trigger", "/proc/sysrq-trigger", NULL, NULL, MS_BIND, MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO }, /* Bind mount first ... */
+ { NULL, "/proc/sysrq-trigger", NULL, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO }, /* ... then, make it r/o */
+
+ /* outer child mounts */
+ { "tmpfs", "/tmp", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, MOUNT_FATAL },
+ { "tmpfs", "/sys", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV, MOUNT_FATAL|MOUNT_APPLY_APIVFS_NETNS },
+ { "sysfs", "/sys", "sysfs", NULL, MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, MOUNT_FATAL|MOUNT_APPLY_APIVFS_RO }, /* skipped if above was mounted */
+ { "sysfs", "/sys", "sysfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, MOUNT_FATAL }, /* skipped if above was mounted */
+
+ { "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME, MOUNT_FATAL },
+ { "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, MOUNT_FATAL },
+ { "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, MOUNT_FATAL },
#ifdef HAVE_SELINUX
- { "/sys/fs/selinux", "/sys/fs/selinux", NULL, NULL, MS_BIND, false, false, false }, /* Bind mount first */
- { NULL, "/sys/fs/selinux", NULL, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, false, false, false }, /* Then, make it r/o */
+ { "/sys/fs/selinux", "/sys/fs/selinux", NULL, NULL, MS_BIND, 0 }, /* Bind mount first */
+ { NULL, "/sys/fs/selinux", NULL, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, 0 }, /* Then, make it r/o */
#endif
};
unsigned k;
int r;
+ bool use_userns = (mount_settings & MOUNT_USE_USERNS);
+ bool netns = (mount_settings & MOUNT_APPLY_APIVFS_NETNS);
+ bool ro = (mount_settings & MOUNT_APPLY_APIVFS_RO);
+ bool in_userns = (mount_settings & MOUNT_IN_USERNS);
for (k = 0; k < ELEMENTSOF(mount_table); k++) {
_cleanup_free_ char *where = NULL, *options = NULL;
const char *o;
+ bool fatal = (mount_table[k].mount_settings & MOUNT_FATAL);
- if (in_userns != mount_table[k].in_userns)
+ if (in_userns != (bool)(mount_table[k].mount_settings & MOUNT_IN_USERNS))
continue;
- if (!use_netns && mount_table[k].use_netns)
+ if (!netns && (bool)(mount_table[k].mount_settings & MOUNT_APPLY_APIVFS_NETNS))
continue;
- where = prefix_root(dest, mount_table[k].where);
- if (!where)
- return log_oom();
+ if (!ro && (bool)(mount_table[k].mount_settings & MOUNT_APPLY_APIVFS_RO))
+ continue;
+
+ r = chase_symlinks(mount_table[k].where, dest, CHASE_NONEXISTENT|CHASE_PREFIX_ROOT, &where);
+ if (r < 0)
+ return log_error_errno(r, "Failed to resolve %s/%s: %m", dest, mount_table[k].where);
- r = path_is_mount_point(where, AT_SYMLINK_FOLLOW);
+ r = path_is_mount_point(where, NULL, 0);
if (r < 0 && r != -ENOENT)
return log_error_errno(r, "Failed to detect whether %s is a mount point: %m", where);
@@ -417,9 +599,9 @@ int mount_all(const char *dest,
if (mount_table[k].what && r > 0)
continue;
- r = mkdir_userns_p(dest, where, 0755, in_userns, uid_shift);
+ r = mkdir_userns_p(dest, where, 0755, (use_userns && !in_userns) ? uid_shift : UID_INVALID);
if (r < 0 && r != -EEXIST) {
- if (mount_table[k].fatal)
+ if (fatal)
return log_error_errno(r, "Failed to create directory %s: %m", where);
log_debug_errno(r, "Failed to create directory %s: %m", where);
@@ -435,13 +617,13 @@ int mount_all(const char *dest,
o = options;
}
- r = mount_verbose(mount_table[k].fatal ? LOG_ERR : LOG_WARNING,
+ r = mount_verbose(fatal ? LOG_ERR : LOG_DEBUG,
mount_table[k].what,
where,
mount_table[k].type,
mount_table[k].flags,
o);
- if (r < 0 && mount_table[k].fatal)
+ if (r < 0 && fatal)
return r;
}
@@ -452,12 +634,14 @@ static int parse_mount_bind_options(const char *options, unsigned long *mount_fl
const char *p = options;
unsigned long flags = *mount_flags;
char *opts = NULL;
+ int r;
assert(options);
for (;;) {
_cleanup_free_ char *word = NULL;
- int r = extract_first_word(&p, &word, ",", 0);
+
+ r = extract_first_word(&p, &word, ",", 0);
if (r < 0)
return log_error_errno(r, "Failed to extract mount option: %m");
if (r == 0)
@@ -481,12 +665,13 @@ static int parse_mount_bind_options(const char *options, unsigned long *mount_fl
}
static int mount_bind(const char *dest, CustomMount *m) {
- struct stat source_st, dest_st;
- const char *where;
+
+ _cleanup_free_ char *mount_opts = NULL, *where = NULL;
unsigned long mount_flags = MS_BIND | MS_REC;
- _cleanup_free_ char *mount_opts = NULL;
+ struct stat source_st, dest_st;
int r;
+ assert(dest);
assert(m);
if (m->options) {
@@ -498,9 +683,14 @@ static int mount_bind(const char *dest, CustomMount *m) {
if (stat(m->source, &source_st) < 0)
return log_error_errno(errno, "Failed to stat %s: %m", m->source);
- where = prefix_roota(dest, m->destination);
+ r = chase_symlinks(m->destination, dest, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &where);
+ if (r < 0)
+ return log_error_errno(r, "Failed to resolve %s/%s: %m", dest, m->destination);
+ if (r > 0) { /* Path exists already? */
+
+ if (stat(where, &dest_st) < 0)
+ return log_error_errno(errno, "Failed to stat %s: %m", where);
- if (stat(where, &dest_st) >= 0) {
if (S_ISDIR(source_st.st_mode) && !S_ISDIR(dest_st.st_mode)) {
log_error("Cannot bind mount directory %s on file %s.", m->source, where);
return -EINVAL;
@@ -511,7 +701,7 @@ static int mount_bind(const char *dest, CustomMount *m) {
return -EINVAL;
}
- } else if (errno == ENOENT) {
+ } else { /* Path doesn't exist yet? */
r = mkdir_parents_label(where, 0755);
if (r < 0)
return log_error_errno(r, "Failed to make parents of %s: %m", where);
@@ -527,8 +717,7 @@ static int mount_bind(const char *dest, CustomMount *m) {
if (r < 0)
return log_error_errno(r, "Failed to create mount point %s: %m", where);
- } else
- return log_error_errno(errno, "Failed to stat %s: %m", where);
+ }
r = mount_verbose(LOG_ERR, m->source, where, NULL, mount_flags, mount_opts);
if (r < 0)
@@ -549,18 +738,21 @@ static int mount_tmpfs(
bool userns, uid_t uid_shift, uid_t uid_range,
const char *selinux_apifs_context) {
- const char *where, *options;
- _cleanup_free_ char *buf = NULL;
+ const char *options;
+ _cleanup_free_ char *buf = NULL, *where = NULL;
int r;
assert(dest);
assert(m);
- where = prefix_roota(dest, m->destination);
-
- r = mkdir_p_label(where, 0755);
- if (r < 0 && r != -EEXIST)
- return log_error_errno(r, "Creating mount point for tmpfs %s failed: %m", where);
+ r = chase_symlinks(m->destination, dest, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &where);
+ if (r < 0)
+ return log_error_errno(r, "Failed to resolve %s/%s: %m", dest, m->destination);
+ if (r == 0) { /* Doesn't exist yet? */
+ r = mkdir_p_label(where, 0755);
+ if (r < 0)
+ return log_error_errno(r, "Creating mount point for tmpfs %s failed: %m", where);
+ }
r = tmpfs_patch_options(m->options, uid_shift == 0 ? UID_INVALID : uid_shift, selinux_apifs_context, &buf);
if (r < 0)
@@ -570,7 +762,7 @@ static int mount_tmpfs(
return mount_verbose(LOG_ERR, "tmpfs", where, "tmpfs", MS_NODEV|MS_STRICTATIME, options);
}
-static char *joined_and_escaped_lower_dirs(char * const *lower) {
+static char *joined_and_escaped_lower_dirs(char **lower) {
_cleanup_strv_free_ char **sv = NULL;
sv = strv_copy(lower);
@@ -586,18 +778,22 @@ static char *joined_and_escaped_lower_dirs(char * const *lower) {
}
static int mount_overlay(const char *dest, CustomMount *m) {
- _cleanup_free_ char *lower = NULL;
- const char *where, *options;
+
+ _cleanup_free_ char *lower = NULL, *where = NULL, *escaped_source = NULL;
+ const char *options;
int r;
assert(dest);
assert(m);
- where = prefix_roota(dest, m->destination);
-
- r = mkdir_label(where, 0755);
- if (r < 0 && r != -EEXIST)
- return log_error_errno(r, "Creating mount point for overlay %s failed: %m", where);
+ r = chase_symlinks(m->destination, dest, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &where);
+ if (r < 0)
+ return log_error_errno(r, "Failed to resolve %s/%s: %m", dest, m->destination);
+ if (r == 0) { /* Doesn't exist yet? */
+ r = mkdir_label(where, 0755);
+ if (r < 0)
+ return log_error_errno(r, "Creating mount point for overlay %s failed: %m", where);
+ }
(void) mkdir_p_label(m->source, 0755);
@@ -605,23 +801,15 @@ static int mount_overlay(const char *dest, CustomMount *m) {
if (!lower)
return log_oom();
- if (m->read_only) {
- _cleanup_free_ char *escaped_source = NULL;
-
- escaped_source = shell_escape(m->source, ",:");
- if (!escaped_source)
- return log_oom();
+ escaped_source = shell_escape(m->source, ",:");
+ if (!escaped_source)
+ return log_oom();
+ if (m->read_only)
options = strjoina("lowerdir=", escaped_source, ":", lower);
- } else {
- _cleanup_free_ char *escaped_source = NULL, *escaped_work_dir = NULL;
-
- assert(m->work_dir);
- (void) mkdir_label(m->work_dir, 0700);
+ else {
+ _cleanup_free_ char *escaped_work_dir = NULL;
- escaped_source = shell_escape(m->source, ",:");
- if (!escaped_source)
- return log_oom();
escaped_work_dir = shell_escape(m->work_dir, ",:");
if (!escaped_work_dir)
return log_oom();
@@ -783,20 +971,115 @@ fail:
return r;
}
-VolatileMode volatile_mode_from_string(const char *s) {
- int b;
+/* Expects *pivot_root_new and *pivot_root_old to be initialised to allocated memory or NULL. */
+int pivot_root_parse(char **pivot_root_new, char **pivot_root_old, const char *s) {
+ _cleanup_free_ char *root_new = NULL, *root_old = NULL;
+ const char *p = s;
+ int r;
- if (isempty(s))
- return _VOLATILE_MODE_INVALID;
+ assert(pivot_root_new);
+ assert(pivot_root_old);
- b = parse_boolean(s);
- if (b > 0)
- return VOLATILE_YES;
- if (b == 0)
- return VOLATILE_NO;
+ r = extract_first_word(&p, &root_new, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return -EINVAL;
+
+ if (isempty(p))
+ root_old = NULL;
+ else {
+ root_old = strdup(p);
+ if (!root_old)
+ return -ENOMEM;
+ }
+
+ if (!path_is_absolute(root_new))
+ return -EINVAL;
+ if (root_old && !path_is_absolute(root_old))
+ return -EINVAL;
+
+ free_and_replace(*pivot_root_new, root_new);
+ free_and_replace(*pivot_root_old, root_old);
+
+ return 0;
+}
+
+int setup_pivot_root(const char *directory, const char *pivot_root_new, const char *pivot_root_old) {
+ _cleanup_free_ char *directory_pivot_root_new = NULL;
+ _cleanup_free_ char *pivot_tmp_pivot_root_old = NULL;
+ char pivot_tmp[] = "/tmp/nspawn-pivot-XXXXXX";
+ bool remove_pivot_tmp = false;
+ int r;
+
+ assert(directory);
+
+ if (!pivot_root_new)
+ return 0;
+
+ /* Pivot pivot_root_new to / and the existing / to pivot_root_old.
+ * If pivot_root_old is NULL, the existing / disappears.
+ * This requires a temporary directory, pivot_tmp, which is
+ * not a child of either.
+ *
+ * This is typically used for OSTree-style containers, where
+ * the root partition contains several sysroots which could be
+ * run. Normally, one would be chosen by the bootloader and
+ * pivoted to / by initramfs.
+ *
+ * For example, for an OSTree deployment, pivot_root_new
+ * would be: /ostree/deploy/$os/deploy/$checksum. Note that this
+ * code doesn’t do the /var mount which OSTree expects: use
+ * --bind +/sysroot/ostree/deploy/$os/var:/var for that.
+ *
+ * So in the OSTree case, we’ll end up with something like:
+ * - directory = /tmp/nspawn-root-123456
+ * - pivot_root_new = /ostree/deploy/os/deploy/123abc
+ * - pivot_root_old = /sysroot
+ * - directory_pivot_root_new =
+ * /tmp/nspawn-root-123456/ostree/deploy/os/deploy/123abc
+ * - pivot_tmp = /tmp/nspawn-pivot-123456
+ * - pivot_tmp_pivot_root_old = /tmp/nspawn-pivot-123456/sysroot
+ *
+ * Requires all file systems at directory and below to be mounted
+ * MS_PRIVATE or MS_SLAVE so they can be moved.
+ */
+ directory_pivot_root_new = prefix_root(directory, pivot_root_new);
+
+ /* Remount directory_pivot_root_new to make it movable. */
+ r = mount_verbose(LOG_ERR, directory_pivot_root_new, directory_pivot_root_new, NULL, MS_BIND, NULL);
+ if (r < 0)
+ goto done;
+
+ if (pivot_root_old) {
+ if (!mkdtemp(pivot_tmp)) {
+ r = log_error_errno(errno, "Failed to create temporary directory: %m");
+ goto done;
+ }
+
+ remove_pivot_tmp = true;
+ pivot_tmp_pivot_root_old = prefix_root(pivot_tmp, pivot_root_old);
- if (streq(s, "state"))
- return VOLATILE_STATE;
+ r = mount_verbose(LOG_ERR, directory_pivot_root_new, pivot_tmp, NULL, MS_MOVE, NULL);
+ if (r < 0)
+ goto done;
+
+ r = mount_verbose(LOG_ERR, directory, pivot_tmp_pivot_root_old, NULL, MS_MOVE, NULL);
+ if (r < 0)
+ goto done;
+
+ r = mount_verbose(LOG_ERR, pivot_tmp, directory, NULL, MS_MOVE, NULL);
+ if (r < 0)
+ goto done;
+ } else {
+ r = mount_verbose(LOG_ERR, directory_pivot_root_new, directory, NULL, MS_MOVE, NULL);
+ if (r < 0)
+ goto done;
+ }
- return _VOLATILE_MODE_INVALID;
+done:
+ if (remove_pivot_tmp)
+ (void) rmdir(pivot_tmp);
+
+ return r;
}
diff --git a/src/nspawn/nspawn-mount.h b/src/nspawn/nspawn-mount.h
index 660bf118d0..26171efe66 100644
--- a/src/nspawn/nspawn-mount.h
+++ b/src/nspawn/nspawn-mount.h
@@ -22,14 +22,16 @@
#include <stdbool.h>
#include "cgroup-util.h"
+#include "volatile-util.h"
-typedef enum VolatileMode {
- VOLATILE_NO,
- VOLATILE_YES,
- VOLATILE_STATE,
- _VOLATILE_MODE_MAX,
- _VOLATILE_MODE_INVALID = -1
-} VolatileMode;
+typedef enum MountSettingsMask {
+ MOUNT_FATAL = 1 << 0, /* if set, a mount error is considered fatal */
+ MOUNT_USE_USERNS = 1 << 1, /* if set, mounts are patched considering uid/gid shifts in a user namespace */
+ MOUNT_IN_USERNS = 1 << 2, /* if set, the mount is executed in the inner child, otherwise in the outer child */
+ MOUNT_APPLY_APIVFS_RO = 1 << 3, /* if set, /proc/sys, and /sysfs will be mounted read-only, otherwise read-write. */
+ MOUNT_APPLY_APIVFS_NETNS = 1 << 4, /* if set, /proc/sys/net will be mounted read-write.
+ Works only if MOUNT_APPLY_APIVFS_RO is also set. */
+} MountSettingsMask;
typedef enum CustomMountType {
CUSTOM_MOUNT_BIND,
@@ -47,24 +49,26 @@ typedef struct CustomMount {
char *options;
char *work_dir;
char **lower;
+ char *rm_rf_tmpdir;
} CustomMount;
CustomMount* custom_mount_add(CustomMount **l, unsigned *n, CustomMountType t);
-
void custom_mount_free_all(CustomMount *l, unsigned n);
+int custom_mount_prepare_all(const char *dest, CustomMount *l, unsigned n);
+
int bind_mount_parse(CustomMount **l, unsigned *n, const char *s, bool read_only);
int tmpfs_mount_parse(CustomMount **l, unsigned *n, const char *s);
+int overlay_mount_parse(CustomMount **l, unsigned *n, const char *s, bool read_only);
-int custom_mount_compare(const void *a, const void *b);
-
-int mount_all(const char *dest, bool in_userns, bool use_netns, uid_t uid_shift, const char *selinux_apifs_context);
-int mount_sysfs(const char *dest);
+int mount_all(const char *dest, MountSettingsMask mount_settings, uid_t uid_shift, const char *selinux_apifs_context);
+int mount_sysfs(const char *dest, MountSettingsMask mount_settings);
int mount_custom(const char *dest, CustomMount *mounts, unsigned n, bool userns, uid_t uid_shift, uid_t uid_range, const char *selinux_apifs_context);
int setup_volatile(const char *directory, VolatileMode mode, bool userns, uid_t uid_shift, uid_t uid_range, const char *selinux_apifs_context);
int setup_volatile_state(const char *directory, VolatileMode mode, bool userns, uid_t uid_shift, uid_t uid_range, const char *selinux_apifs_context);
-VolatileMode volatile_mode_from_string(const char *s);
+int pivot_root_parse(char **pivot_root_new, char **pivot_root_old, const char *s);
+int setup_pivot_root(const char *directory, const char *pivot_root_new, const char *pivot_root_old);
int tmpfs_patch_options(const char *options, uid_t uid_shift, const char *selinux_apifs_context, char **ret);
diff --git a/src/nspawn/nspawn-patch-uid.c b/src/nspawn/nspawn-patch-uid.c
index ded5866d05..1a3f129db0 100644
--- a/src/nspawn/nspawn-patch-uid.c
+++ b/src/nspawn/nspawn-patch-uid.c
@@ -375,7 +375,7 @@ static int recurse_fd(int fd, bool donate_fd, const struct stat *st, uid_t shift
FOREACH_DIRENT_ALL(de, d, r = -errno; goto finish) {
struct stat fst;
- if (STR_IN_SET(de->d_name, ".", ".."))
+ if (dot_or_dot_dot(de->d_name))
continue;
if (fstatat(dirfd(d), de->d_name, &fst, AT_SYMLINK_NOFOLLOW) < 0) {
diff --git a/src/nspawn/nspawn-register.c b/src/nspawn/nspawn-register.c
index 06c56d9ec8..e3ab39faea 100644
--- a/src/nspawn/nspawn-register.c
+++ b/src/nspawn/nspawn-register.c
@@ -135,6 +135,11 @@ int register_machine(
continue;
r = is_device_node(cm->source);
+ if (r == -ENOENT) {
+ /* The bind source might only appear as the image is put together, hence don't complain */
+ log_debug_errno(r, "Bind mount source %s not found, ignoring: %m", cm->source);
+ continue;
+ }
if (r < 0)
return log_error_errno(r, "Failed to stat %s: %m", cm->source);
diff --git a/src/nspawn/nspawn-seccomp.c b/src/nspawn/nspawn-seccomp.c
index 03a397d30c..72ecc51b16 100644
--- a/src/nspawn/nspawn-seccomp.c
+++ b/src/nspawn/nspawn-seccomp.c
@@ -26,20 +26,21 @@
#include <seccomp.h>
#endif
+#include "alloc-util.h"
#include "log.h"
-
+#include "nspawn-seccomp.h"
#ifdef HAVE_SECCOMP
#include "seccomp-util.h"
#endif
-
-#include "nspawn-seccomp.h"
+#include "string-util.h"
#ifdef HAVE_SECCOMP
-static int seccomp_add_default_syscall_filter(scmp_filter_ctx ctx,
- uint64_t cap_list_retain) {
- unsigned i;
- int r;
+static int seccomp_add_default_syscall_filter(
+ scmp_filter_ctx ctx,
+ uint32_t arch,
+ uint64_t cap_list_retain) {
+
static const struct {
uint64_t capability;
int syscall_num;
@@ -111,23 +112,29 @@ static int seccomp_add_default_syscall_filter(scmp_filter_ctx ctx,
{ CAP_SYS_TIME, SCMP_SYS(settimeofday) },
{ CAP_SYS_TIME, SCMP_SYS(stime) },
};
+ unsigned i;
+ int r, c = 0;
for (i = 0; i < ELEMENTSOF(blacklist); i++) {
if (blacklist[i].capability != 0 && (cap_list_retain & (1ULL << blacklist[i].capability)))
continue;
- r = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), blacklist[i].syscall_num, 0);
- if (r == -EFAULT)
- continue; /* unknown syscall */
- if (r < 0)
- return log_error_errno(r, "Failed to block syscall: %m");
+ r = seccomp_rule_add_exact(ctx, SCMP_ACT_ERRNO(EPERM), blacklist[i].syscall_num, 0);
+ if (r < 0) {
+ /* If the system call is not known on this architecture, then that's fine, let's ignore it */
+ _cleanup_free_ char *n = NULL;
+
+ n = seccomp_syscall_resolve_num_arch(arch, blacklist[i].syscall_num);
+ log_debug_errno(r, "Failed to add rule for system call %s, ignoring: %m", strna(n));
+ } else
+ c++;
}
- return 0;
+ return c;
}
int setup_seccomp(uint64_t cap_list_retain) {
- scmp_filter_ctx seccomp;
+ uint32_t arch;
int r;
if (!is_seccomp_available()) {
@@ -135,45 +142,51 @@ int setup_seccomp(uint64_t cap_list_retain) {
return 0;
}
- r = seccomp_init_conservative(&seccomp, SCMP_ACT_ALLOW);
- if (r < 0)
- return log_error_errno(r, "Failed to allocate seccomp object: %m");
-
- r = seccomp_add_default_syscall_filter(seccomp, cap_list_retain);
- if (r < 0)
- goto finish;
-
- /*
- Audit is broken in containers, much of the userspace audit
- hookup will fail if running inside a container. We don't
- care and just turn off creation of audit sockets.
-
- This will make socket(AF_NETLINK, *, NETLINK_AUDIT) fail
- with EAFNOSUPPORT which audit userspace uses as indication
- that audit is disabled in the kernel.
- */
-
- r = seccomp_rule_add(
- seccomp,
- SCMP_ACT_ERRNO(EAFNOSUPPORT),
- SCMP_SYS(socket),
- 2,
- SCMP_A0(SCMP_CMP_EQ, AF_NETLINK),
- SCMP_A2(SCMP_CMP_EQ, NETLINK_AUDIT));
- if (r < 0) {
- log_error_errno(r, "Failed to add audit seccomp rule: %m");
- goto finish;
- }
+ SECCOMP_FOREACH_LOCAL_ARCH(arch) {
+ _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
+ int n;
+
+ log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch));
+
+ r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ALLOW);
+ if (r < 0)
+ return log_error_errno(r, "Failed to allocate seccomp object: %m");
+
+ n = seccomp_add_default_syscall_filter(seccomp, arch, cap_list_retain);
+ if (n < 0)
+ return n;
+
+ /*
+ Audit is broken in containers, much of the userspace audit hookup will fail if running inside a
+ container. We don't care and just turn off creation of audit sockets.
+
+ This will make socket(AF_NETLINK, *, NETLINK_AUDIT) fail with EAFNOSUPPORT which audit userspace uses
+ as indication that audit is disabled in the kernel.
+ */
+
+ r = seccomp_rule_add_exact(
+ seccomp,
+ SCMP_ACT_ERRNO(EAFNOSUPPORT),
+ SCMP_SYS(socket),
+ 2,
+ SCMP_A0(SCMP_CMP_EQ, AF_NETLINK),
+ SCMP_A2(SCMP_CMP_EQ, NETLINK_AUDIT));
+ if (r < 0)
+ log_debug_errno(r, "Failed to add audit seccomp rule, ignoring: %m");
+ else
+ n++;
+
+ if (n <= 0) /* no rule added? then skip this architecture */
+ continue;
- r = seccomp_load(seccomp);
- if (r < 0) {
- log_error_errno(r, "Failed to install seccomp audit filter: %m");
- goto finish;
+ r = seccomp_load(seccomp);
+ if (IN_SET(r, -EPERM, -EACCES))
+ return log_error_errno(r, "Failed to install seccomp audit filter: %m");
+ if (r < 0)
+ log_debug_errno(r, "Failed to install filter set for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
}
-finish:
- seccomp_release(seccomp);
- return r;
+ return 0;
}
#else
diff --git a/src/nspawn/nspawn-settings.c b/src/nspawn/nspawn-settings.c
index 09c8f070ba..5217d10665 100644
--- a/src/nspawn/nspawn-settings.c
+++ b/src/nspawn/nspawn-settings.c
@@ -90,6 +90,8 @@ Settings* settings_free(Settings *s) {
strv_free(s->parameters);
strv_free(s->environment);
free(s->user);
+ free(s->pivot_root_new);
+ free(s->pivot_root_old);
free(s->working_directory);
strv_free(s->network_interfaces);
@@ -237,6 +239,34 @@ int config_parse_id128(
return 0;
}
+int config_parse_pivot_root(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ Settings *settings = data;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+
+ r = pivot_root_parse(&settings->pivot_root_new, &settings->pivot_root_old, rvalue);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Invalid pivot root mount specification %s: %m", rvalue);
+ return 0;
+ }
+
+ return 0;
+}
+
int config_parse_bind(
const char *unit,
const char *filename,
@@ -293,6 +323,32 @@ int config_parse_tmpfs(
return 0;
}
+int config_parse_overlay(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ Settings *settings = data;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+
+ r = overlay_mount_parse(&settings->custom_mounts, &settings->n_custom_mounts, rvalue, ltype);
+ if (r < 0)
+ log_syntax(unit, LOG_ERR, filename, line, r, "Invalid overlay file system specification %s, ignoring: %m", rvalue);
+
+ return 0;
+}
+
int config_parse_veth_extra(
const char *unit,
const char *filename,
diff --git a/src/nspawn/nspawn-settings.h b/src/nspawn/nspawn-settings.h
index 4ae34f8e28..021403258f 100644
--- a/src/nspawn/nspawn-settings.h
+++ b/src/nspawn/nspawn-settings.h
@@ -57,7 +57,8 @@ typedef enum SettingsMask {
SETTING_WORKING_DIRECTORY = 1 << 12,
SETTING_USERNS = 1 << 13,
SETTING_NOTIFY_READY = 1 << 14,
- _SETTINGS_MASK_ALL = (1 << 15) -1
+ SETTING_PIVOT_ROOT = 1 << 15,
+ _SETTINGS_MASK_ALL = (1 << 16) -1
} SettingsMask;
typedef struct Settings {
@@ -72,6 +73,8 @@ typedef struct Settings {
unsigned long personality;
sd_id128_t machine_id;
char *working_directory;
+ char *pivot_root_new;
+ char *pivot_root_old;
UserNamespaceMode userns_mode;
uid_t uid_shift, uid_range;
bool notify_ready;
@@ -109,8 +112,10 @@ int config_parse_capability(const char *unit, const char *filename, unsigned lin
int config_parse_id128(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_expose_port(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_volatile_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_pivot_root(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_bind(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_tmpfs(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_overlay(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_veth_extra(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_network_zone(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_boot(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
diff --git a/src/nspawn/nspawn-stub-pid1.c b/src/nspawn/nspawn-stub-pid1.c
index 2de87e3c63..7f2a53a245 100644
--- a/src/nspawn/nspawn-stub-pid1.c
+++ b/src/nspawn/nspawn-stub-pid1.c
@@ -20,6 +20,7 @@
#include <sys/reboot.h>
#include <sys/unistd.h>
#include <sys/wait.h>
+#include <sys/prctl.h>
#include "fd-util.h"
#include "log.h"
@@ -29,7 +30,22 @@
#include "time-util.h"
#include "def.h"
-int stub_pid1(void) {
+static int reset_environ(const char *new_environment, size_t length) {
+ unsigned long start, end;
+
+ start = (unsigned long) new_environment;
+ end = start + length;
+
+ if (prctl(PR_SET_MM, PR_SET_MM_ENV_START, start, 0, 0) < 0)
+ return -errno;
+
+ if (prctl(PR_SET_MM, PR_SET_MM_ENV_END, end, 0, 0) < 0)
+ return -errno;
+
+ return 0;
+}
+
+int stub_pid1(sd_id128_t uuid) {
enum {
STATE_RUNNING,
STATE_REBOOT,
@@ -41,6 +57,11 @@ int stub_pid1(void) {
pid_t pid;
int r;
+ /* The new environment we set up, on the stack. */
+ char new_environment[] =
+ "container=systemd-nspawn\0"
+ "container_uuid=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
+
/* Implements a stub PID 1, that reaps all processes and processes a couple of standard signals. This is useful
* for allowing arbitrary processes run in a container, and still have all zombies reaped. */
@@ -64,6 +85,12 @@ int stub_pid1(void) {
close_all_fds(NULL, 0);
log_open();
+ /* Flush out /proc/self/environ, so that we don't leak the environment from the host into the container. Also,
+ * set $container= and $container_uuid= so that clients in the container that query it from /proc/1/environ
+ * find them set. */
+ sd_id128_to_string(uuid, new_environment + sizeof(new_environment) - SD_ID128_STRING_MAX);
+ reset_environ(new_environment, sizeof(new_environment));
+
rename_process("STUBINIT");
assert_se(sigemptyset(&waitmask) >= 0);
diff --git a/src/nspawn/nspawn-stub-pid1.h b/src/nspawn/nspawn-stub-pid1.h
index 36c1aaf5dd..7ca83078c0 100644
--- a/src/nspawn/nspawn-stub-pid1.h
+++ b/src/nspawn/nspawn-stub-pid1.h
@@ -19,4 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-int stub_pid1(void);
+#include "sd-id128.h"
+
+int stub_pid1(sd_id128_t uuid);
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 1de119867b..670fef2991 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -38,8 +38,10 @@
#include <sys/personality.h>
#include <sys/prctl.h>
#include <sys/types.h>
+#include <sys/wait.h>
#include <unistd.h>
+#include "sd-bus.h"
#include "sd-daemon.h"
#include "sd-id128.h"
@@ -48,21 +50,25 @@
#include "base-filesystem.h"
#include "blkid-util.h"
#include "btrfs-util.h"
+#include "bus-util.h"
#include "cap-list.h"
#include "capability-util.h"
#include "cgroup-util.h"
#include "copy.h"
#include "dev-setup.h"
+#include "dissect-image.h"
#include "env-util.h"
#include "fd-util.h"
#include "fdset.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "fs-util.h"
#include "gpt.h"
+#include "hexdecoct.h"
#include "hostname-util.h"
#include "id128-util.h"
#include "log.h"
+#include "loop-util.h"
#include "loopback-setup.h"
#include "machine-image.h"
#include "macro.h"
@@ -111,6 +117,8 @@
* the init process in the container pid can send messages to nspawn following the sd_notify(3) protocol */
#define NSPAWN_NOTIFY_SOCKET_PATH "/run/systemd/nspawn/notify"
+#define EXIT_FORCE_RESTART 133
+
typedef enum ContainerStatus {
CONTAINER_TERMINATED,
CONTAINER_REBOOTED
@@ -126,6 +134,8 @@ typedef enum LinkJournal {
static char *arg_directory = NULL;
static char *arg_template = NULL;
static char *arg_chdir = NULL;
+static char *arg_pivot_root_new = NULL;
+static char *arg_pivot_root_old = NULL;
static char *arg_user = NULL;
static sd_id128_t arg_uuid = {};
static char *arg_machine = NULL;
@@ -195,6 +205,9 @@ static const char *arg_container_service_name = "systemd-nspawn";
static bool arg_notify_ready = false;
static bool arg_use_cgns = true;
static unsigned long arg_clone_ns_flags = CLONE_NEWIPC|CLONE_NEWPID|CLONE_NEWUTS;
+static MountSettingsMask arg_mount_settings = MOUNT_APPLY_APIVFS_RO;
+static void *arg_root_hash = NULL;
+static size_t arg_root_hash_size = 0;
static void help(void) {
printf("%s [OPTIONS...] [PATH] [ARGUMENTS...]\n\n"
@@ -208,9 +221,12 @@ static void help(void) {
" -x --ephemeral Run container with snapshot of root directory, and\n"
" remove it after exit\n"
" -i --image=PATH File system device or disk image for the container\n"
+ " --root-hash=HASH Specify verity root hash\n"
" -a --as-pid2 Maintain a stub init as PID1, invoke binary as PID2\n"
" -b --boot Boot up full system (i.e. invoke init)\n"
" --chdir=PATH Set working directory in the container\n"
+ " --pivot-root=PATH[:PATH]\n"
+ " Pivot root to given directory in the container\n"
" -u --user=USER Run the command under specified user or uid\n"
" -M --machine=NAME Set the machine name for the container\n"
" --uuid=UUID Set a specific machine UUID for the container\n"
@@ -281,14 +297,9 @@ static void help(void) {
, program_invocation_short_name);
}
-static int custom_mounts_prepare(void) {
+static int custom_mount_check_all(void) {
unsigned i;
- int r;
- /* Ensure the mounts are applied prefix first. */
- qsort_safe(arg_custom_mounts, arg_n_custom_mounts, sizeof(CustomMount), custom_mount_compare);
-
- /* Allocate working directories for the overlay file systems that need it */
for (i = 0; i < arg_n_custom_mounts; i++) {
CustomMount *m = &arg_custom_mounts[i];
@@ -302,31 +313,17 @@ static int custom_mounts_prepare(void) {
return -EINVAL;
}
}
-
- if (m->type != CUSTOM_MOUNT_OVERLAY)
- continue;
-
- if (m->work_dir)
- continue;
-
- if (m->read_only)
- continue;
-
- r = tempfn_random(m->source, NULL, &m->work_dir);
- if (r < 0)
- return log_error_errno(r, "Failed to generate work directory from %s: %m", m->source);
}
return 0;
}
-static int pick_cgroup_version(const char *directory, CGroupUnified outer) {
+static int pick_cgroup_version(const char *directory, CGroupUnified outer_cgver) {
int r;
- /* Otherwise inherit the default from the host system, unless
- * the container doesn't have a new enough systemd (detected
+ /* By default, inherit from the host system, unless the container doesn't have a new enough systemd (detected
* by checking libsystemd-shared). */
- switch (outer) {
+ switch (outer_cgver) {
default:
case CGROUP_UNIFIED_INHERIT:
assert_not_reached("Invalid host cgroup version");
@@ -334,13 +331,9 @@ static int pick_cgroup_version(const char *directory, CGroupUnified outer) {
case CGROUP_UNIFIED_UNKNOWN:
arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_INHERIT;
break;
- case CGROUP_UNIFIED_NONE: /* cgroup v1-sd */
- arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_INHERIT;
- break;
- case CGROUP_UNIFIED_ALL: /* cgroup v2 */
- /* Unified cgroup hierarchy support was added in 230. Unfortunately libsystemd-shared,
- * which we use to sniff the systemd version, was only added in 231, so we'll have a
- * false negative here for 230. */
+ case CGROUP_UNIFIED_ALL:
+ /* Unified cgroup hierarchy support was added in 230. Unfortunately, libsystemd-shared (which we use
+ * to sniff the systemd version) was only added in 231, so we'll have a false negative here for 230. */
r = systemd_installation_has_version(directory, 230);
if (r < 0)
return log_error_errno(r, "Failed to decide cgroup version to use: Failed to determine systemd version in container: %m");
@@ -349,8 +342,18 @@ static int pick_cgroup_version(const char *directory, CGroupUnified outer) {
else
arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_NONE;
break;
- case CGROUP_UNIFIED_SYSTEMD: /* cgroup v1/v2 mixed-sd232 */
- /* Mixed cgroup hierarchy support was added in 232 */
+ case CGROUP_UNIFIED_SYSTEMD233:
+ /* systemd v233+ -style mixed cgroup hierarchy */
+ r = systemd_installation_has_version(directory, 233);
+ if (r < 0)
+ return log_error_errno(r, "Failed to decide cgroup version to use: Failed to determine systemd version in container: %m");
+ if (r > 0)
+ arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_INHERIT;
+ else
+ arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_NONE;
+ break;
+ case CGROUP_UNIFIED_SYSTEMD232:
+ /* systemd v232 -style mixed cgroup hierarchy */
r = systemd_installation_has_version(directory, 232);
if (r < 0)
return log_error_errno(r, "Failed to decide cgroup version to use: Failed to determine systemd version in container: %m");
@@ -359,6 +362,9 @@ static int pick_cgroup_version(const char *directory, CGroupUnified outer) {
else
arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_NONE;
break;
+ case CGROUP_UNIFIED_NONE:
+ arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_INHERIT;
+ break;
}
return 0;
@@ -375,6 +381,31 @@ static void parse_share_ns_env(const char *name, unsigned long ns_flag) {
arg_clone_ns_flags = (arg_clone_ns_flags & ~ns_flag) | (r > 0 ? 0 : ns_flag);
}
+static void parse_mount_settings_env(void) {
+ int r;
+ const char *e;
+
+ e = getenv("SYSTEMD_NSPAWN_API_VFS_WRITABLE");
+ if (!e)
+ return;
+
+ if (streq(e, "network")) {
+ arg_mount_settings |= MOUNT_APPLY_APIVFS_RO|MOUNT_APPLY_APIVFS_NETNS;
+ return;
+ }
+
+ r = parse_boolean(e);
+ if (r < 0) {
+ log_warning_errno(r, "Failed to parse SYSTEMD_NSPAWN_API_VFS_WRITABLE from environment, ignoring.");
+ return;
+ } else if (r > 0)
+ arg_mount_settings &= ~MOUNT_APPLY_APIVFS_RO;
+ else
+ arg_mount_settings |= MOUNT_APPLY_APIVFS_RO;
+
+ arg_mount_settings &= ~MOUNT_APPLY_APIVFS_NETNS;
+}
+
static int parse_argv(int argc, char *argv[]) {
enum {
@@ -407,8 +438,10 @@ static int parse_argv(int argc, char *argv[]) {
ARG_KILL_SIGNAL,
ARG_SETTINGS,
ARG_CHDIR,
+ ARG_PIVOT_ROOT,
ARG_PRIVATE_USERS_CHOWN,
ARG_NOTIFY_READY,
+ ARG_ROOT_HASH,
};
static const struct option options[] = {
@@ -457,7 +490,9 @@ static int parse_argv(int argc, char *argv[]) {
{ "kill-signal", required_argument, NULL, ARG_KILL_SIGNAL },
{ "settings", required_argument, NULL, ARG_SETTINGS },
{ "chdir", required_argument, NULL, ARG_CHDIR },
+ { "pivot-root", required_argument, NULL, ARG_PIVOT_ROOT },
{ "notify-ready", required_argument, NULL, ARG_NOTIFY_READY },
+ { "root-hash", required_argument, NULL, ARG_ROOT_HASH },
{}
};
@@ -757,69 +792,15 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_OVERLAY:
- case ARG_OVERLAY_RO: {
- _cleanup_free_ char *upper = NULL, *destination = NULL;
- _cleanup_strv_free_ char **lower = NULL;
- CustomMount *m;
- unsigned n = 0;
- char **i;
-
- r = strv_split_extract(&lower, optarg, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
- if (r == -ENOMEM)
- return log_oom();
- else if (r < 0) {
- log_error("Invalid overlay specification: %s", optarg);
- return r;
- }
-
- STRV_FOREACH(i, lower) {
- if (!path_is_absolute(*i)) {
- log_error("Overlay path %s is not absolute.", *i);
- return -EINVAL;
- }
-
- n++;
- }
-
- if (n < 2) {
- log_error("--overlay= needs at least two colon-separated directories specified.");
- return -EINVAL;
- }
-
- if (n == 2) {
- /* If two parameters are specified,
- * the first one is the lower, the
- * second one the upper directory. And
- * we'll also define the destination
- * mount point the same as the upper. */
- upper = lower[1];
- lower[1] = NULL;
-
- destination = strdup(upper);
- if (!destination)
- return log_oom();
-
- } else {
- upper = lower[n - 2];
- destination = lower[n - 1];
- lower[n - 2] = NULL;
- }
-
- m = custom_mount_add(&arg_custom_mounts, &arg_n_custom_mounts, CUSTOM_MOUNT_OVERLAY);
- if (!m)
- return log_oom();
-
- m->destination = destination;
- m->source = upper;
- m->lower = lower;
- m->read_only = c == ARG_OVERLAY_RO;
-
- upper = destination = NULL;
- lower = NULL;
+ case ARG_OVERLAY_RO:
+ r = overlay_mount_parse(&arg_custom_mounts, &arg_n_custom_mounts, optarg, c == ARG_OVERLAY_RO);
+ if (r == -EADDRNOTAVAIL)
+ return log_error_errno(r, "--overlay(-ro)= needs at least two colon-separated directories specified.");
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse --overlay(-ro)= argument %s: %m", optarg);
arg_settings_mask |= SETTING_CUSTOM_MOUNTS;
break;
- }
case 'E': {
char **n;
@@ -1044,6 +1025,14 @@ static int parse_argv(int argc, char *argv[]) {
arg_settings_mask |= SETTING_WORKING_DIRECTORY;
break;
+ case ARG_PIVOT_ROOT:
+ r = pivot_root_parse(&arg_pivot_root_new, &arg_pivot_root_old, optarg);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse --pivot-root= argument %s: %m", optarg);
+
+ arg_settings_mask |= SETTING_PIVOT_ROOT;
+ break;
+
case ARG_NOTIFY_READY:
r = parse_boolean(optarg);
if (r < 0) {
@@ -1054,6 +1043,25 @@ static int parse_argv(int argc, char *argv[]) {
arg_settings_mask |= SETTING_NOTIFY_READY;
break;
+ case ARG_ROOT_HASH: {
+ void *k;
+ size_t l;
+
+ r = unhexmem(optarg, strlen(optarg), &k, &l);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse root hash: %s", optarg);
+ if (l < sizeof(sd_id128_t)) {
+ log_error("Root hash must be at least 128bit long: %s", optarg);
+ free(k);
+ return -EINVAL;
+ }
+
+ free(arg_root_hash);
+ arg_root_hash = k;
+ arg_root_hash_size = l;
+ break;
+ }
+
case '?':
return -EINVAL;
@@ -1066,6 +1074,14 @@ static int parse_argv(int argc, char *argv[]) {
parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_NS_UTS", CLONE_NEWUTS);
parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_SYSTEM", CLONE_NEWIPC|CLONE_NEWPID|CLONE_NEWUTS);
+ if (arg_userns_mode != USER_NAMESPACE_NO)
+ arg_mount_settings |= MOUNT_USE_USERNS;
+
+ if (arg_private_network)
+ arg_mount_settings |= MOUNT_APPLY_APIVFS_NETNS;
+
+ parse_mount_settings_env();
+
if (!(arg_clone_ns_flags & CLONE_NEWPID) ||
!(arg_clone_ns_flags & CLONE_NEWUTS)) {
arg_register = false;
@@ -1093,6 +1109,16 @@ static int parse_argv(int argc, char *argv[]) {
return -EINVAL;
}
+ if (arg_ephemeral && arg_template && !arg_directory) {
+ /* User asked for ephemeral execution but specified --template= instead of --directory=. Semantically
+ * such an invocation makes some sense, see https://github.com/systemd/systemd/issues/3667. Let's
+ * accept this here, and silently make "--ephemeral --template=" equivalent to "--ephemeral
+ * --directory=". */
+
+ arg_directory = arg_template;
+ arg_template = NULL;
+ }
+
if (arg_template && !(arg_directory || arg_machine)) {
log_error("--template= needs --directory= or --machine=.");
return -EINVAL;
@@ -1103,11 +1129,6 @@ static int parse_argv(int argc, char *argv[]) {
return -EINVAL;
}
- if (arg_ephemeral && arg_image) {
- log_error("--ephemeral and --image= may not be combined.");
- return -EINVAL;
- }
-
if (arg_ephemeral && !IN_SET(arg_link_journal, LINK_NO, LINK_AUTO)) {
log_error("--ephemeral and --link-journal= may not be combined.");
return -EINVAL;
@@ -1167,10 +1188,23 @@ static int parse_argv(int argc, char *argv[]) {
arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_NONE;
}
+ r = custom_mount_check_all();
+ if (r < 0)
+ return r;
+
return 1;
}
static int verify_arguments(void) {
+ if (arg_userns_mode != USER_NAMESPACE_NO && (arg_mount_settings & MOUNT_APPLY_APIVFS_NETNS) && !arg_private_network) {
+ log_error("Invalid namespacing settings. Mounting sysfs with --private-users requires --private-network.");
+ return -EINVAL;
+ }
+
+ if (arg_userns_mode != USER_NAMESPACE_NO && !(arg_mount_settings & MOUNT_APPLY_APIVFS_RO)) {
+ log_error("Cannot combine --private-users with read-write mounts.");
+ return -EINVAL;
+ }
if (arg_volatile_mode != VOLATILE_NO && arg_read_only) {
log_error("Cannot combine --read-only with --volatile. Note that --volatile already implies a read-only base hierarchy.");
@@ -1285,15 +1319,18 @@ static int setup_timezone(const char *dest) {
return 0;
}
- r = unlink(where);
- if (r < 0 && errno != ENOENT) {
- log_error_errno(errno, "Failed to remove existing timezone info %s in container: %m", where);
+ if (unlink(where) < 0 && errno != ENOENT) {
+ log_full_errno(IN_SET(errno, EROFS, EACCES, EPERM) ? LOG_DEBUG : LOG_WARNING, /* Don't complain on read-only images */
+ errno,
+ "Failed to remove existing timezone info %s in container, ignoring: %m", where);
return 0;
}
what = strjoina("../usr/share/zoneinfo/", z);
if (symlink(what, where) < 0) {
- log_error_errno(errno, "Failed to correct timezone of container: %m");
+ log_full_errno(IN_SET(errno, EROFS, EACCES, EPERM) ? LOG_DEBUG : LOG_WARNING,
+ errno,
+ "Failed to correct timezone of container, ignoring: %m");
return 0;
}
@@ -1304,36 +1341,75 @@ static int setup_timezone(const char *dest) {
return 0;
}
-static int setup_resolv_conf(const char *dest) {
- const char *where = NULL;
+static int resolved_running(void) {
+ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
int r;
+ /* Check if resolved is running */
+
+ r = sd_bus_open_system(&bus);
+ if (r < 0)
+ return r;
+
+ return bus_name_has_owner(bus, "org.freedesktop.resolve1", NULL);
+}
+
+static int setup_resolv_conf(const char *dest) {
+ _cleanup_free_ char *resolved = NULL, *etc = NULL;
+ const char *where;
+ int r, found;
+
assert(dest);
if (arg_private_network)
return 0;
- /* Fix resolv.conf, if possible */
- where = prefix_roota(dest, "/etc/resolv.conf");
+ r = chase_symlinks("/etc", dest, CHASE_PREFIX_ROOT, &etc);
+ if (r < 0) {
+ log_warning_errno(r, "Failed to resolve /etc path in container, ignoring: %m");
+ return 0;
+ }
+
+ where = strjoina(etc, "/resolv.conf");
+ found = chase_symlinks(where, dest, CHASE_NONEXISTENT, &resolved);
+ if (found < 0) {
+ log_warning_errno(found, "Failed to resolve /etc/resolv.conf path in container, ignoring: %m");
+ return 0;
+ }
+
+ if (access("/usr/lib/systemd/resolv.conf", F_OK) >= 0 &&
+ resolved_running() > 0) {
+
+ /* resolved is enabled on the host. In this, case bind mount its static resolv.conf file into the
+ * container, so that the container can use the host's resolver. Given that network namespacing is
+ * disabled it's only natural of the container also uses the host's resolver. It also has the big
+ * advantage that the container will be able to follow the host's DNS server configuration changes
+ * transparently. */
+
+ if (found == 0) /* missing? */
+ (void) touch(resolved);
+
+ r = mount_verbose(LOG_DEBUG, "/usr/lib/systemd/resolv.conf", resolved, NULL, MS_BIND, NULL);
+ if (r >= 0)
+ return mount_verbose(LOG_ERR, NULL, resolved, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NODEV, NULL);
+ }
- r = copy_file("/etc/resolv.conf", where, O_TRUNC|O_NOFOLLOW, 0644, 0);
+ /* If that didn't work, let's copy the file */
+ r = copy_file("/etc/resolv.conf", where, O_TRUNC|O_NOFOLLOW, 0644, 0, COPY_REFLINK);
if (r < 0) {
- /* If the file already exists as symlink, let's
- * suppress the warning, under the assumption that
- * resolved or something similar runs inside and the
- * symlink points there.
+ /* If the file already exists as symlink, let's suppress the warning, under the assumption that
+ * resolved or something similar runs inside and the symlink points there.
*
- * If the disk image is read-only, there's also no
- * point in complaining.
+ * If the disk image is read-only, there's also no point in complaining.
*/
- log_full_errno(IN_SET(r, -ELOOP, -EROFS) ? LOG_DEBUG : LOG_WARNING, r,
- "Failed to copy /etc/resolv.conf to %s: %m", where);
+ log_full_errno(IN_SET(r, -ELOOP, -EROFS, -EACCES, -EPERM) ? LOG_DEBUG : LOG_WARNING, r,
+ "Failed to copy /etc/resolv.conf to %s, ignoring: %m", where);
return 0;
}
r = userns_lchown(where, 0, 0);
if (r < 0)
- log_warning_errno(r, "Failed to chown /etc/resolv.conf: %m");
+ log_warning_errno(r, "Failed to chown /etc/resolv.conf, ignoring: %m");
return 0;
}
@@ -1408,12 +1484,9 @@ static int copy_devnodes(const char *dest) {
} else {
if (mknod(to, st.st_mode, st.st_rdev) < 0) {
- /*
- * This is some sort of protection too against
- * recursive userns chown on shared /dev/
- */
+ /* Explicitly warn the user when /dev is already populated. */
if (errno == EEXIST)
- log_notice("%s/dev/ should be an empty directory", dest);
+ log_notice("%s/dev is pre-mounted and pre-populated. If a pre-mounted /dev is provided it needs to be an unpopulated file system.", dest);
if (errno != EPERM)
return log_error_errno(errno, "mknod(%s) failed: %m", to);
@@ -1621,7 +1694,7 @@ static int setup_journal(const char *directory) {
p = strjoina("/var/log/journal/", id);
q = prefix_roota(directory, p);
- if (path_is_mount_point(p, 0) > 0) {
+ if (path_is_mount_point(p, NULL, 0) > 0) {
if (try)
return 0;
@@ -1629,7 +1702,7 @@ static int setup_journal(const char *directory) {
return -EEXIST;
}
- if (path_is_mount_point(q, 0) > 0) {
+ if (path_is_mount_point(q, NULL, 0) > 0) {
if (try)
return 0;
@@ -1782,546 +1855,6 @@ static int setup_propagate(const char *root) {
return mount_verbose(LOG_ERR, NULL, q, NULL, MS_SLAVE, NULL);
}
-static int setup_image(char **device_path, int *loop_nr) {
- struct loop_info64 info = {
- .lo_flags = LO_FLAGS_AUTOCLEAR|LO_FLAGS_PARTSCAN
- };
- _cleanup_close_ int fd = -1, control = -1, loop = -1;
- _cleanup_free_ char* loopdev = NULL;
- struct stat st;
- int r, nr;
-
- assert(device_path);
- assert(loop_nr);
- assert(arg_image);
-
- fd = open(arg_image, O_CLOEXEC|(arg_read_only ? O_RDONLY : O_RDWR)|O_NONBLOCK|O_NOCTTY);
- if (fd < 0)
- return log_error_errno(errno, "Failed to open %s: %m", arg_image);
-
- if (fstat(fd, &st) < 0)
- return log_error_errno(errno, "Failed to stat %s: %m", arg_image);
-
- if (S_ISBLK(st.st_mode)) {
- char *p;
-
- p = strdup(arg_image);
- if (!p)
- return log_oom();
-
- *device_path = p;
-
- *loop_nr = -1;
-
- r = fd;
- fd = -1;
-
- return r;
- }
-
- if (!S_ISREG(st.st_mode)) {
- log_error("%s is not a regular file or block device.", arg_image);
- return -EINVAL;
- }
-
- control = open("/dev/loop-control", O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
- if (control < 0)
- return log_error_errno(errno, "Failed to open /dev/loop-control: %m");
-
- nr = ioctl(control, LOOP_CTL_GET_FREE);
- if (nr < 0)
- return log_error_errno(errno, "Failed to allocate loop device: %m");
-
- if (asprintf(&loopdev, "/dev/loop%i", nr) < 0)
- return log_oom();
-
- loop = open(loopdev, O_CLOEXEC|(arg_read_only ? O_RDONLY : O_RDWR)|O_NONBLOCK|O_NOCTTY);
- if (loop < 0)
- return log_error_errno(errno, "Failed to open loop device %s: %m", loopdev);
-
- if (ioctl(loop, LOOP_SET_FD, fd) < 0)
- return log_error_errno(errno, "Failed to set loopback file descriptor on %s: %m", loopdev);
-
- if (arg_read_only)
- info.lo_flags |= LO_FLAGS_READ_ONLY;
-
- if (ioctl(loop, LOOP_SET_STATUS64, &info) < 0)
- return log_error_errno(errno, "Failed to set loopback settings on %s: %m", loopdev);
-
- *device_path = loopdev;
- loopdev = NULL;
-
- *loop_nr = nr;
-
- r = loop;
- loop = -1;
-
- return r;
-}
-
-#define PARTITION_TABLE_BLURB \
- "Note that the disk image needs to either contain only a single MBR partition of\n" \
- "type 0x83 that is marked bootable, or a single GPT partition of type " \
- "0FC63DAF-8483-4772-8E79-3D69D8477DE4 or follow\n" \
- " http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/\n" \
- "to be bootable with systemd-nspawn."
-
-static int dissect_image(
- int fd,
- char **root_device, bool *root_device_rw,
- char **home_device, bool *home_device_rw,
- char **srv_device, bool *srv_device_rw,
- char **esp_device,
- bool *secondary) {
-
-#ifdef HAVE_BLKID
- int home_nr = -1, srv_nr = -1, esp_nr = -1;
-#ifdef GPT_ROOT_NATIVE
- int root_nr = -1;
-#endif
-#ifdef GPT_ROOT_SECONDARY
- int secondary_root_nr = -1;
-#endif
- _cleanup_free_ char *home = NULL, *root = NULL, *secondary_root = NULL, *srv = NULL, *esp = NULL, *generic = NULL;
- _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
- _cleanup_udev_device_unref_ struct udev_device *d = NULL;
- _cleanup_blkid_free_probe_ blkid_probe b = NULL;
- _cleanup_udev_unref_ struct udev *udev = NULL;
- struct udev_list_entry *first, *item;
- bool home_rw = true, root_rw = true, secondary_root_rw = true, srv_rw = true, generic_rw = true;
- bool is_gpt, is_mbr, multiple_generic = false;
- const char *pttype = NULL;
- blkid_partlist pl;
- struct stat st;
- unsigned i;
- int r;
-
- assert(fd >= 0);
- assert(root_device);
- assert(home_device);
- assert(srv_device);
- assert(esp_device);
- assert(secondary);
- assert(arg_image);
-
- b = blkid_new_probe();
- if (!b)
- return log_oom();
-
- errno = 0;
- r = blkid_probe_set_device(b, fd, 0, 0);
- if (r != 0) {
- if (errno == 0)
- return log_oom();
-
- return log_error_errno(errno, "Failed to set device on blkid probe: %m");
- }
-
- blkid_probe_enable_partitions(b, 1);
- blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
-
- errno = 0;
- r = blkid_do_safeprobe(b);
- if (r == -2 || r == 1) {
- log_error("Failed to identify any partition table on\n"
- " %s\n"
- PARTITION_TABLE_BLURB, arg_image);
- return -EINVAL;
- } else if (r != 0) {
- if (errno == 0)
- errno = EIO;
- return log_error_errno(errno, "Failed to probe: %m");
- }
-
- (void) blkid_probe_lookup_value(b, "PTTYPE", &pttype, NULL);
-
- is_gpt = streq_ptr(pttype, "gpt");
- is_mbr = streq_ptr(pttype, "dos");
-
- if (!is_gpt && !is_mbr) {
- log_error("No GPT or MBR partition table discovered on\n"
- " %s\n"
- PARTITION_TABLE_BLURB, arg_image);
- return -EINVAL;
- }
-
- errno = 0;
- pl = blkid_probe_get_partitions(b);
- if (!pl) {
- if (errno == 0)
- return log_oom();
-
- log_error("Failed to list partitions of %s", arg_image);
- return -errno;
- }
-
- udev = udev_new();
- if (!udev)
- return log_oom();
-
- if (fstat(fd, &st) < 0)
- return log_error_errno(errno, "Failed to stat block device: %m");
-
- d = udev_device_new_from_devnum(udev, 'b', st.st_rdev);
- if (!d)
- return log_oom();
-
- for (i = 0;; i++) {
- int n, m;
-
- if (i >= 10) {
- log_error("Kernel partitions never appeared.");
- return -ENXIO;
- }
-
- e = udev_enumerate_new(udev);
- if (!e)
- return log_oom();
-
- r = udev_enumerate_add_match_parent(e, d);
- if (r < 0)
- return log_oom();
-
- r = udev_enumerate_scan_devices(e);
- if (r < 0)
- return log_error_errno(r, "Failed to scan for partition devices of %s: %m", arg_image);
-
- /* Count the partitions enumerated by the kernel */
- n = 0;
- first = udev_enumerate_get_list_entry(e);
- udev_list_entry_foreach(item, first)
- n++;
-
- /* Count the partitions enumerated by blkid */
- m = blkid_partlist_numof_partitions(pl);
- if (n == m + 1)
- break;
- if (n > m + 1) {
- log_error("blkid and kernel partition list do not match.");
- return -EIO;
- }
- if (n < m + 1) {
- unsigned j;
-
- /* The kernel has probed fewer partitions than
- * blkid? Maybe the kernel prober is still
- * running or it got EBUSY because udev
- * already opened the device. Let's reprobe
- * the device, which is a synchronous call
- * that waits until probing is complete. */
-
- for (j = 0; j < 20; j++) {
-
- r = ioctl(fd, BLKRRPART, 0);
- if (r < 0)
- r = -errno;
- if (r >= 0 || r != -EBUSY)
- break;
-
- /* If something else has the device
- * open, such as an udev rule, the
- * ioctl will return EBUSY. Since
- * there's no way to wait until it
- * isn't busy anymore, let's just wait
- * a bit, and try again.
- *
- * This is really something they
- * should fix in the kernel! */
-
- usleep(50 * USEC_PER_MSEC);
- }
-
- if (r < 0)
- return log_error_errno(r, "Failed to reread partition table: %m");
- }
-
- e = udev_enumerate_unref(e);
- }
-
- first = udev_enumerate_get_list_entry(e);
- udev_list_entry_foreach(item, first) {
- _cleanup_udev_device_unref_ struct udev_device *q;
- const char *node;
- unsigned long long flags;
- blkid_partition pp;
- dev_t qn;
- int nr;
-
- errno = 0;
- q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
- if (!q) {
- if (!errno)
- errno = ENOMEM;
-
- return log_error_errno(errno, "Failed to get partition device of %s: %m", arg_image);
- }
-
- qn = udev_device_get_devnum(q);
- if (major(qn) == 0)
- continue;
-
- if (st.st_rdev == qn)
- continue;
-
- node = udev_device_get_devnode(q);
- if (!node)
- continue;
-
- pp = blkid_partlist_devno_to_partition(pl, qn);
- if (!pp)
- continue;
-
- flags = blkid_partition_get_flags(pp);
-
- nr = blkid_partition_get_partno(pp);
- if (nr < 0)
- continue;
-
- if (is_gpt) {
- sd_id128_t type_id;
- const char *stype;
-
- if (flags & GPT_FLAG_NO_AUTO)
- continue;
-
- stype = blkid_partition_get_type_string(pp);
- if (!stype)
- continue;
-
- if (sd_id128_from_string(stype, &type_id) < 0)
- continue;
-
- if (sd_id128_equal(type_id, GPT_HOME)) {
-
- if (home && nr >= home_nr)
- continue;
-
- home_nr = nr;
- home_rw = !(flags & GPT_FLAG_READ_ONLY);
-
- r = free_and_strdup(&home, node);
- if (r < 0)
- return log_oom();
-
- } else if (sd_id128_equal(type_id, GPT_SRV)) {
-
- if (srv && nr >= srv_nr)
- continue;
-
- srv_nr = nr;
- srv_rw = !(flags & GPT_FLAG_READ_ONLY);
-
- r = free_and_strdup(&srv, node);
- if (r < 0)
- return log_oom();
- } else if (sd_id128_equal(type_id, GPT_ESP)) {
-
- if (esp && nr >= esp_nr)
- continue;
-
- esp_nr = nr;
-
- r = free_and_strdup(&esp, node);
- if (r < 0)
- return log_oom();
- }
-#ifdef GPT_ROOT_NATIVE
- else if (sd_id128_equal(type_id, GPT_ROOT_NATIVE)) {
-
- if (root && nr >= root_nr)
- continue;
-
- root_nr = nr;
- root_rw = !(flags & GPT_FLAG_READ_ONLY);
-
- r = free_and_strdup(&root, node);
- if (r < 0)
- return log_oom();
- }
-#endif
-#ifdef GPT_ROOT_SECONDARY
- else if (sd_id128_equal(type_id, GPT_ROOT_SECONDARY)) {
-
- if (secondary_root && nr >= secondary_root_nr)
- continue;
-
- secondary_root_nr = nr;
- secondary_root_rw = !(flags & GPT_FLAG_READ_ONLY);
-
- r = free_and_strdup(&secondary_root, node);
- if (r < 0)
- return log_oom();
- }
-#endif
- else if (sd_id128_equal(type_id, GPT_LINUX_GENERIC)) {
-
- if (generic)
- multiple_generic = true;
- else {
- generic_rw = !(flags & GPT_FLAG_READ_ONLY);
-
- r = free_and_strdup(&generic, node);
- if (r < 0)
- return log_oom();
- }
- }
-
- } else if (is_mbr) {
- int type;
-
- if (flags != 0x80) /* Bootable flag */
- continue;
-
- type = blkid_partition_get_type(pp);
- if (type != 0x83) /* Linux partition */
- continue;
-
- if (generic)
- multiple_generic = true;
- else {
- generic_rw = true;
-
- r = free_and_strdup(&root, node);
- if (r < 0)
- return log_oom();
- }
- }
- }
-
- if (root) {
- *root_device = root;
- root = NULL;
-
- *root_device_rw = root_rw;
- *secondary = false;
- } else if (secondary_root) {
- *root_device = secondary_root;
- secondary_root = NULL;
-
- *root_device_rw = secondary_root_rw;
- *secondary = true;
- } else if (generic) {
-
- /* There were no partitions with precise meanings
- * around, but we found generic partitions. In this
- * case, if there's only one, we can go ahead and boot
- * it, otherwise we bail out, because we really cannot
- * make any sense of it. */
-
- if (multiple_generic) {
- log_error("Identified multiple bootable Linux partitions on\n"
- " %s\n"
- PARTITION_TABLE_BLURB, arg_image);
- return -EINVAL;
- }
-
- *root_device = generic;
- generic = NULL;
-
- *root_device_rw = generic_rw;
- *secondary = false;
- } else {
- log_error("Failed to identify root partition in disk image\n"
- " %s\n"
- PARTITION_TABLE_BLURB, arg_image);
- return -EINVAL;
- }
-
- if (home) {
- *home_device = home;
- home = NULL;
-
- *home_device_rw = home_rw;
- }
-
- if (srv) {
- *srv_device = srv;
- srv = NULL;
-
- *srv_device_rw = srv_rw;
- }
-
- if (esp) {
- *esp_device = esp;
- esp = NULL;
- }
-
- return 0;
-#else
- log_error("--image= is not supported, compiled without blkid support.");
- return -EOPNOTSUPP;
-#endif
-}
-
-static int mount_device(const char *what, const char *where, const char *directory, bool rw) {
-#ifdef HAVE_BLKID
- _cleanup_blkid_free_probe_ blkid_probe b = NULL;
- const char *fstype, *p, *options;
- int r;
-
- assert(what);
- assert(where);
-
- if (arg_read_only)
- rw = false;
-
- if (directory)
- p = strjoina(where, directory);
- else
- p = where;
-
- errno = 0;
- b = blkid_new_probe_from_filename(what);
- if (!b) {
- if (errno == 0)
- return log_oom();
- return log_error_errno(errno, "Failed to allocate prober for %s: %m", what);
- }
-
- blkid_probe_enable_superblocks(b, 1);
- blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
-
- errno = 0;
- r = blkid_do_safeprobe(b);
- if (r == -1 || r == 1) {
- log_error("Cannot determine file system type of %s", what);
- return -EINVAL;
- } else if (r != 0) {
- if (errno == 0)
- errno = EIO;
- return log_error_errno(errno, "Failed to probe %s: %m", what);
- }
-
- errno = 0;
- if (blkid_probe_lookup_value(b, "TYPE", &fstype, NULL) < 0) {
- if (errno == 0)
- errno = EINVAL;
- log_error("Failed to determine file system type of %s", what);
- return -errno;
- }
-
- if (streq(fstype, "crypto_LUKS")) {
- log_error("nspawn currently does not support LUKS disk images.");
- return -EOPNOTSUPP;
- }
-
- /* If this is a loopback device then let's mount the image with discard, so that the underlying file remains
- * sparse when possible. */
- if (STR_IN_SET(fstype, "btrfs", "ext4", "vfat", "xfs")) {
- const char *l;
-
- l = path_startswith(what, "/dev");
- if (l && startswith(l, "loop"))
- options = "discard";
- }
-
- return mount_verbose(LOG_ERR, what, p, fstype, MS_NODEV|(rw ? 0 : MS_RDONLY), options);
-#else
- log_error("--image= is not supported, compiled without blkid support.");
- return -EOPNOTSUPP;
-#endif
-}
-
static int setup_machine_id(const char *directory) {
const char *etc_machine_id;
sd_id128_t id;
@@ -2381,83 +1914,6 @@ static int recursive_chown(const char *directory, uid_t shift, uid_t range) {
return r;
}
-static int mount_devices(
- const char *where,
- const char *root_device, bool root_device_rw,
- const char *home_device, bool home_device_rw,
- const char *srv_device, bool srv_device_rw,
- const char *esp_device) {
- int r;
-
- assert(where);
-
- if (root_device) {
- r = mount_device(root_device, arg_directory, NULL, root_device_rw);
- if (r < 0)
- return log_error_errno(r, "Failed to mount root directory: %m");
- }
-
- if (home_device) {
- r = mount_device(home_device, arg_directory, "/home", home_device_rw);
- if (r < 0)
- return log_error_errno(r, "Failed to mount home directory: %m");
- }
-
- if (srv_device) {
- r = mount_device(srv_device, arg_directory, "/srv", srv_device_rw);
- if (r < 0)
- return log_error_errno(r, "Failed to mount server data directory: %m");
- }
-
- if (esp_device) {
- const char *mp, *x;
-
- /* Mount the ESP to /efi if it exists and is empty. If it doesn't exist, use /boot instead. */
-
- mp = "/efi";
- x = strjoina(arg_directory, mp);
- r = dir_is_empty(x);
- if (r == -ENOENT) {
- mp = "/boot";
- x = strjoina(arg_directory, mp);
- r = dir_is_empty(x);
- }
-
- if (r > 0) {
- r = mount_device(esp_device, arg_directory, mp, true);
- if (r < 0)
- return log_error_errno(r, "Failed to mount ESP: %m");
- }
- }
-
- return 0;
-}
-
-static void loop_remove(int nr, int *image_fd) {
- _cleanup_close_ int control = -1;
- int r;
-
- if (nr < 0)
- return;
-
- if (image_fd && *image_fd >= 0) {
- r = ioctl(*image_fd, LOOP_CLR_FD);
- if (r < 0)
- log_debug_errno(errno, "Failed to close loop image: %m");
- *image_fd = safe_close(*image_fd);
- }
-
- control = open("/dev/loop-control", O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
- if (control < 0) {
- log_warning_errno(errno, "Failed to open /dev/loop-control: %m");
- return;
- }
-
- r = ioctl(control, LOOP_CTL_REMOVE, nr);
- if (r < 0)
- log_debug_errno(errno, "Failed to remove loop %d: %m", nr);
-}
-
/*
* Return values:
* < 0 : wait_for_terminate() failed to get the state of the
@@ -2534,6 +1990,26 @@ static int on_orderly_shutdown(sd_event_source *s, const struct signalfd_siginfo
return 0;
}
+static int on_sigchld(sd_event_source *s, const struct signalfd_siginfo *ssi, void *userdata) {
+ for (;;) {
+ siginfo_t si = {};
+ if (waitid(P_ALL, 0, &si, WNOHANG|WNOWAIT|WEXITED) < 0)
+ return log_error_errno(errno, "Failed to waitid(): %m");
+ if (si.si_pid == 0) /* No pending children. */
+ break;
+ if (si.si_pid == PTR_TO_PID(userdata)) {
+ /* The main process we care for has exited. Return from
+ * signal handler but leave the zombie. */
+ sd_event_exit(sd_event_source_get_event(s), 0);
+ break;
+ }
+ /* Reap all other children. */
+ (void) waitid(P_PID, si.si_pid, &si, WNOHANG|WEXITED);
+ }
+
+ return 0;
+}
+
static int determine_names(void) {
int r;
@@ -2543,7 +2019,7 @@ static int determine_names(void) {
* search for a machine, but instead create a new one
* in /var/lib/machine. */
- arg_directory = strjoin("/var/lib/machines/", arg_machine, NULL);
+ arg_directory = strjoin("/var/lib/machines/", arg_machine);
if (!arg_directory)
return log_oom();
}
@@ -2555,8 +2031,8 @@ static int determine_names(void) {
r = image_find(arg_machine, &i);
if (r < 0)
return log_error_errno(r, "Failed to find image for machine '%s': %m", arg_machine);
- else if (r == 0) {
- log_error("No image for machine '%s': %m", arg_machine);
+ if (r == 0) {
+ log_error("No image for machine '%s'.", arg_machine);
return -ENOENT;
}
@@ -2565,25 +2041,36 @@ static int determine_names(void) {
else
r = free_and_strdup(&arg_directory, i->path);
if (r < 0)
- return log_error_errno(r, "Invalid image directory: %m");
+ return log_oom();
if (!arg_ephemeral)
arg_read_only = arg_read_only || i->read_only;
} else
arg_directory = get_current_dir_name();
- if (!arg_directory && !arg_machine) {
+ if (!arg_directory && !arg_image) {
log_error("Failed to determine path, please use -D or -i.");
return -EINVAL;
}
}
if (!arg_machine) {
+
if (arg_directory && path_equal(arg_directory, "/"))
arg_machine = gethostname_malloc();
- else
- arg_machine = strdup(basename(arg_image ?: arg_directory));
+ else {
+ if (arg_image) {
+ char *e;
+ arg_machine = strdup(basename(arg_image));
+
+ /* Truncate suffix if there is one */
+ e = endswith(arg_machine, ".raw");
+ if (e)
+ *e = 0;
+ } else
+ arg_machine = strdup(basename(arg_directory));
+ }
if (!arg_machine)
return log_oom();
@@ -2612,6 +2099,25 @@ static int determine_names(void) {
return 0;
}
+static int chase_symlinks_and_update(char **p, unsigned flags) {
+ char *chased;
+ int r;
+
+ assert(p);
+
+ if (!*p)
+ return 0;
+
+ r = chase_symlinks(*p, NULL, flags, &chased);
+ if (r < 0)
+ return log_error_errno(r, "Failed to resolve path %s: %m", *p);
+
+ free(*p);
+ *p = chased;
+
+ return 0;
+}
+
static int determine_uid_shift(const char *directory) {
int r;
@@ -2670,6 +2176,7 @@ static int inner_child(
NULL, /* NOTIFY_SOCKET */
NULL
};
+ const char *exec_target;
_cleanup_strv_free_ char **env_use = NULL;
int r;
@@ -2694,15 +2201,14 @@ static int inner_child(
return log_error_errno(r, "Couldn't become new root: %m");
r = mount_all(NULL,
- true,
- arg_private_network,
+ arg_mount_settings | MOUNT_IN_USERNS,
arg_uid_shift,
arg_selinux_apifs_context);
if (r < 0)
return r;
- r = mount_sysfs(NULL);
+ r = mount_sysfs(NULL, arg_mount_settings);
if (r < 0)
return r;
@@ -2813,7 +2319,7 @@ static int inner_child(
return log_error_errno(errno, "Failed to change to specified working directory %s: %m", arg_chdir);
if (arg_start_mode == START_PID2) {
- r = stub_pid1();
+ r = stub_pid1(arg_uuid);
if (r < 0)
return r;
}
@@ -2848,20 +2354,25 @@ static int inner_child(
a[0] = (char*) "/sbin/init";
execve(a[0], a, env_use);
- } else if (!strv_isempty(arg_parameters))
+
+ exec_target = "/usr/lib/systemd/systemd, /lib/systemd/systemd, /sbin/init";
+ } else if (!strv_isempty(arg_parameters)) {
+ exec_target = arg_parameters[0];
execvpe(arg_parameters[0], arg_parameters, env_use);
- else {
+ } else {
if (!arg_chdir)
/* If we cannot change the directory, we'll end up in /, that is expected. */
(void) chdir(home ?: "/root");
execle("/bin/bash", "-bash", NULL, env_use);
execle("/bin/sh", "-sh", NULL, env_use);
+
+ exec_target = "/bin/bash, /bin/sh";
}
r = -errno;
(void) log_open();
- return log_error_errno(r, "execv() failed: %m");
+ return log_error_errno(r, "execv(%s) failed: %m", exec_target);
}
static int setup_sd_notify_child(void) {
@@ -2886,6 +2397,12 @@ static int setup_sd_notify_child(void) {
return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
}
+ r = userns_lchown(NSPAWN_NOTIFY_SOCKET_PATH, 0, 0);
+ if (r < 0) {
+ safe_close(fd);
+ return log_error_errno(r, "Failed to chown " NSPAWN_NOTIFY_SOCKET_PATH ": %m");
+ }
+
r = setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
if (r < 0) {
safe_close(fd);
@@ -2899,10 +2416,7 @@ static int outer_child(
Barrier *barrier,
const char *directory,
const char *console,
- const char *root_device, bool root_device_rw,
- const char *home_device, bool home_device_rw,
- const char *srv_device, bool srv_device_rw,
- const char *esp_device,
+ DissectedImage *dissected_image,
bool interactive,
bool secondary,
int pid_socket,
@@ -2964,13 +2478,11 @@ static int outer_child(
if (r < 0)
return r;
- r = mount_devices(directory,
- root_device, root_device_rw,
- home_device, home_device_rw,
- srv_device, srv_device_rw,
- esp_device);
- if (r < 0)
- return r;
+ if (dissected_image) {
+ r = dissected_image_mount(dissected_image, directory, DISSECT_IMAGE_DISCARD_ON_LOOP|(arg_read_only ? DISSECT_IMAGE_READ_ONLY : 0));
+ if (r < 0)
+ return r;
+ }
r = determine_uid_shift(directory);
if (r < 0)
@@ -3008,17 +2520,10 @@ static int outer_child(
if (r < 0)
return r;
- /* Mark everything as shared so our mounts get propagated down. This is
- * required to make new bind mounts available in systemd services
- * inside the containter that create a new mount namespace.
- * See https://github.com/systemd/systemd/issues/3860
- * Further submounts (such as /dev) done after this will inherit the
- * shared propagation mode.*/
- r = mount_verbose(LOG_ERR, NULL, directory, NULL, MS_SHARED|MS_REC, NULL);
- if (r < 0)
- return r;
-
- r = recursive_chown(directory, arg_uid_shift, arg_uid_range);
+ r = setup_pivot_root(
+ directory,
+ arg_pivot_root_new,
+ arg_pivot_root_old);
if (r < 0)
return r;
@@ -3042,6 +2547,20 @@ static int outer_child(
if (r < 0)
return r;
+ /* Mark everything as shared so our mounts get propagated down. This is
+ * required to make new bind mounts available in systemd services
+ * inside the containter that create a new mount namespace.
+ * See https://github.com/systemd/systemd/issues/3860
+ * Further submounts (such as /dev) done after this will inherit the
+ * shared propagation mode. */
+ r = mount_verbose(LOG_ERR, NULL, directory, NULL, MS_SHARED|MS_REC, NULL);
+ if (r < 0)
+ return r;
+
+ r = recursive_chown(directory, arg_uid_shift, arg_uid_range);
+ if (r < 0)
+ return r;
+
r = base_filesystem_create(directory, arg_uid_shift, (gid_t) arg_uid_shift);
if (r < 0)
return r;
@@ -3053,8 +2572,7 @@ static int outer_child(
}
r = mount_all(directory,
- false,
- arg_private_network,
+ arg_mount_settings,
arg_uid_shift,
arg_selinux_apifs_context);
if (r < 0)
@@ -3366,15 +2884,14 @@ static int nspawn_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t r
return 0;
}
-static int setup_sd_notify_parent(sd_event *event, int fd, pid_t *inner_child_pid) {
+static int setup_sd_notify_parent(sd_event *event, int fd, pid_t *inner_child_pid, sd_event_source **notify_event_source) {
int r;
- sd_event_source *notify_event_source;
- r = sd_event_add_io(event, &notify_event_source, fd, EPOLLIN, nspawn_dispatch_notify_fd, inner_child_pid);
+ r = sd_event_add_io(event, notify_event_source, fd, EPOLLIN, nspawn_dispatch_notify_fd, inner_child_pid);
if (r < 0)
return log_error_errno(r, "Failed to allocate notify event source: %m");
- (void) sd_event_source_set_description(notify_event_source, "nspawn-notify");
+ (void) sd_event_source_set_description(*notify_event_source, "nspawn-notify");
return 0;
}
@@ -3397,7 +2914,7 @@ static int load_settings(void) {
FOREACH_STRING(i, "/etc/systemd/nspawn", "/run/systemd/nspawn") {
_cleanup_free_ char *j = NULL;
- j = strjoin(i, "/", fn, NULL);
+ j = strjoin(i, "/", fn);
if (!j)
return log_oom();
@@ -3463,6 +2980,12 @@ static int load_settings(void) {
settings->parameters = NULL;
}
+ if ((arg_settings_mask & SETTING_PIVOT_ROOT) == 0 &&
+ settings->pivot_root_new) {
+ free_and_replace(arg_pivot_root_new, settings->pivot_root_new);
+ free_and_replace(arg_pivot_root_old, settings->pivot_root_old);
+ }
+
if ((arg_settings_mask & SETTING_WORKING_DIRECTORY) == 0 &&
settings->working_directory) {
free(arg_chdir);
@@ -3615,10 +3138,7 @@ static int load_settings(void) {
static int run(int master,
const char* console,
- const char *root_device, bool root_device_rw,
- const char *home_device, bool home_device_rw,
- const char *srv_device, bool srv_device_rw,
- const char *esp_device,
+ DissectedImage *dissected_image,
bool interactive,
bool secondary,
CGroupUnified outer_cgver,
@@ -3630,7 +3150,7 @@ static int run(int master,
static const struct sigaction sa = {
.sa_handler = nop_signal_handler,
- .sa_flags = SA_NOCLDSTOP,
+ .sa_flags = SA_NOCLDSTOP|SA_RESTART,
};
_cleanup_release_lock_file_ LockFile uid_shift_lock = LOCK_FILE_INIT;
@@ -3645,6 +3165,7 @@ static int run(int master,
cgroup_socket_pair[2] = {-1, -1 };
_cleanup_close_ int notify_socket= -1;
_cleanup_(barrier_destroy) Barrier barrier = BARRIER_NULL;
+ _cleanup_(sd_event_source_unrefp) sd_event_source *notify_event_source = NULL;
_cleanup_(sd_event_unrefp) sd_event *event = NULL;
_cleanup_(pty_forward_freep) PTYForward *forward = NULL;
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
@@ -3732,10 +3253,7 @@ static int run(int master,
r = outer_child(&barrier,
arg_directory,
console,
- root_device, root_device_rw,
- home_device, home_device_rw,
- srv_device, srv_device_rw,
- esp_device,
+ dissected_image,
interactive,
secondary,
pid_socket_pair[1],
@@ -3770,7 +3288,6 @@ static int run(int master,
l = recv(uid_shift_socket_pair[0], &arg_uid_shift, sizeof arg_uid_shift, 0);
if (l < 0)
return log_error_errno(errno, "Failed to read UID shift: %m");
-
if (l != sizeof arg_uid_shift) {
log_error("Short read while reading UID shift.");
return -EIO;
@@ -3956,7 +3473,7 @@ static int run(int master,
if (r < 0)
return log_error_errno(r, "Failed to get default event source: %m");
- r = setup_sd_notify_parent(event, notify_socket, PID_TO_PTR(*main_pid));
+ r = setup_sd_notify_parent(event, notify_socket, PID_TO_PTR(*main_pid), &notify_event_source);
if (r < 0)
return r;
@@ -3986,8 +3503,8 @@ static int run(int master,
sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
}
- /* simply exit on sigchld */
- sd_event_add_signal(event, NULL, SIGCHLD, NULL, NULL);
+ /* Exit when the child exits */
+ sd_event_add_signal(event, NULL, SIGCHLD, on_sigchld, PID_TO_PTR(*main_pid));
if (arg_expose_ports) {
r = expose_port_watch_rtnl(event, rtnl_socket_pair[0], on_address_change, exposed, &rtnl);
@@ -4021,7 +3538,7 @@ static int run(int master,
terminate_machine(*main_pid);
/* Normally redundant, but better safe than sorry */
- kill(*main_pid, SIGKILL);
+ (void) kill(*main_pid, SIGKILL);
r = wait_for_container(*main_pid, &container_status);
*main_pid = 0;
@@ -4035,7 +3552,7 @@ static int run(int master,
* because 133 is special-cased in the service file to reboot the container.
* otherwise → The container exited with zero status and a reboot was not requested.
*/
- if (r == 133)
+ if (r == EXIT_FORCE_RESTART)
r = EXIT_FAILURE; /* replace 133 with the general failure code */
*ret = r;
return 0; /* finito */
@@ -4050,8 +3567,8 @@ static int run(int master,
* file uses RestartForceExitStatus=133 so that this results in a full
* nspawn restart. This is necessary since we might have cgroup parameters
* set we want to have flushed out. */
- *ret = 0;
- return 133;
+ *ret = EXIT_FORCE_RESTART;
+ return 0; /* finito */
}
expose_port_flush(arg_expose_ports, exposed);
@@ -4063,17 +3580,20 @@ static int run(int master,
int main(int argc, char *argv[]) {
- _cleanup_free_ char *device_path = NULL, *root_device = NULL, *home_device = NULL, *srv_device = NULL, *esp_device = NULL, *console = NULL;
- bool root_device_rw = true, home_device_rw = true, srv_device_rw = true;
- _cleanup_close_ int master = -1, image_fd = -1;
+ _cleanup_free_ char *console = NULL;
+ _cleanup_close_ int master = -1;
_cleanup_fdset_free_ FDSet *fds = NULL;
- int r, n_fd_passed, loop_nr = -1, ret = EXIT_SUCCESS;
+ int r, n_fd_passed, ret = EXIT_SUCCESS;
char veth_name[IFNAMSIZ] = "";
- bool secondary = false, remove_subvol = false;
+ bool secondary = false, remove_directory = false, remove_image = false;
pid_t helper_pid = 0, main_pid = 0;
union in_addr_union exposed = {};
_cleanup_release_lock_file_ LockFile tree_global_lock = LOCK_FILE_INIT, tree_local_lock = LOCK_FILE_INIT;
- bool interactive, veth_created = false;
+ bool interactive, veth_created = false, remove_tmprootdir = false;
+ char tmprootdir[] = "/tmp/nspawn-root-XXXXXX";
+ _cleanup_(loop_device_unrefp) LoopDevice *loop = NULL;
+ _cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
+ _cleanup_(dissected_image_unrefp) DissectedImage *dissected_image = NULL;
CGroupUnified outer_cgver;
log_parse_environment();
@@ -4096,6 +3616,7 @@ int main(int argc, char *argv[]) {
r = -EPERM;
goto finish;
}
+
r = determine_names();
if (r < 0)
goto finish;
@@ -4129,13 +3650,17 @@ int main(int argc, char *argv[]) {
if (arg_ephemeral) {
_cleanup_free_ char *np = NULL;
+ r = chase_symlinks_and_update(&arg_directory, 0);
+ if (r < 0)
+ goto finish;
+
/* If the specified path is a mount point we
* generate the new snapshot immediately
* inside it under a random name. However if
* the specified is not a mount point we
* create the new snapshot in the parent
* directory, just next to it. */
- r = path_is_mount_point(arg_directory, 0);
+ r = path_is_mount_point(arg_directory, NULL, 0);
if (r < 0) {
log_error_errno(r, "Failed to determine whether directory %s is mount point: %m", arg_directory);
goto finish;
@@ -4145,7 +3670,7 @@ int main(int argc, char *argv[]) {
else
r = tempfn_random(arg_directory, "machine.", &np);
if (r < 0) {
- log_error_errno(r, "Failed to generate name for snapshot: %m");
+ log_error_errno(r, "Failed to generate name for directory snapshot: %m");
goto finish;
}
@@ -4155,7 +3680,12 @@ int main(int argc, char *argv[]) {
goto finish;
}
- r = btrfs_subvol_snapshot(arg_directory, np, (arg_read_only ? BTRFS_SNAPSHOT_READ_ONLY : 0) | BTRFS_SNAPSHOT_FALLBACK_COPY | BTRFS_SNAPSHOT_RECURSIVE | BTRFS_SNAPSHOT_QUOTA);
+ r = btrfs_subvol_snapshot(arg_directory, np,
+ (arg_read_only ? BTRFS_SNAPSHOT_READ_ONLY : 0) |
+ BTRFS_SNAPSHOT_FALLBACK_COPY |
+ BTRFS_SNAPSHOT_FALLBACK_DIRECTORY |
+ BTRFS_SNAPSHOT_RECURSIVE |
+ BTRFS_SNAPSHOT_QUOTA);
if (r < 0) {
log_error_errno(r, "Failed to create snapshot %s from %s: %m", np, arg_directory);
goto finish;
@@ -4165,9 +3695,13 @@ int main(int argc, char *argv[]) {
arg_directory = np;
np = NULL;
- remove_subvol = true;
+ remove_directory = true;
} else {
+ r = chase_symlinks_and_update(&arg_directory, arg_template ? CHASE_NONEXISTENT : 0);
+ if (r < 0)
+ goto finish;
+
r = image_path_lock(arg_directory, (arg_read_only ? LOCK_SH : LOCK_EX) | LOCK_NB, &tree_global_lock, &tree_local_lock);
if (r == -EBUSY) {
log_error_errno(r, "Directory tree %s is currently busy.", arg_directory);
@@ -4179,7 +3713,17 @@ int main(int argc, char *argv[]) {
}
if (arg_template) {
- r = btrfs_subvol_snapshot(arg_template, arg_directory, (arg_read_only ? BTRFS_SNAPSHOT_READ_ONLY : 0) | BTRFS_SNAPSHOT_FALLBACK_COPY | BTRFS_SNAPSHOT_RECURSIVE | BTRFS_SNAPSHOT_QUOTA);
+ r = chase_symlinks_and_update(&arg_template, 0);
+ if (r < 0)
+ goto finish;
+
+ r = btrfs_subvol_snapshot(arg_template, arg_directory,
+ (arg_read_only ? BTRFS_SNAPSHOT_READ_ONLY : 0) |
+ BTRFS_SNAPSHOT_FALLBACK_COPY |
+ BTRFS_SNAPSHOT_FALLBACK_DIRECTORY |
+ BTRFS_SNAPSHOT_FALLBACK_IMMUTABLE |
+ BTRFS_SNAPSHOT_RECURSIVE |
+ BTRFS_SNAPSHOT_QUOTA);
if (r == -EEXIST) {
if (!arg_quiet)
log_info("Directory %s already exists, not populating from template %s.", arg_directory, arg_template);
@@ -4211,50 +3755,120 @@ int main(int argc, char *argv[]) {
}
} else {
- char template[] = "/tmp/nspawn-root-XXXXXX";
-
assert(arg_image);
assert(!arg_template);
- r = image_path_lock(arg_image, (arg_read_only ? LOCK_SH : LOCK_EX) | LOCK_NB, &tree_global_lock, &tree_local_lock);
- if (r == -EBUSY) {
- r = log_error_errno(r, "Disk image %s is currently busy.", arg_image);
- goto finish;
- }
- if (r < 0) {
- r = log_error_errno(r, "Failed to create image lock: %m");
+ r = chase_symlinks_and_update(&arg_image, 0);
+ if (r < 0)
goto finish;
+
+ if (arg_ephemeral) {
+ _cleanup_free_ char *np = NULL;
+
+ r = tempfn_random(arg_image, "machine.", &np);
+ if (r < 0) {
+ log_error_errno(r, "Failed to generate name for image snapshot: %m");
+ goto finish;
+ }
+
+ r = image_path_lock(np, (arg_read_only ? LOCK_SH : LOCK_EX) | LOCK_NB, &tree_global_lock, &tree_local_lock);
+ if (r < 0) {
+ r = log_error_errno(r, "Failed to create image lock: %m");
+ goto finish;
+ }
+
+ r = copy_file(arg_image, np, O_EXCL, arg_read_only ? 0400 : 0600, FS_NOCOW_FL, COPY_REFLINK);
+ if (r < 0) {
+ r = log_error_errno(r, "Failed to copy image file: %m");
+ goto finish;
+ }
+
+ free(arg_image);
+ arg_image = np;
+ np = NULL;
+
+ remove_image = true;
+ } else {
+ r = image_path_lock(arg_image, (arg_read_only ? LOCK_SH : LOCK_EX) | LOCK_NB, &tree_global_lock, &tree_local_lock);
+ if (r == -EBUSY) {
+ r = log_error_errno(r, "Disk image %s is currently busy.", arg_image);
+ goto finish;
+ }
+ if (r < 0) {
+ r = log_error_errno(r, "Failed to create image lock: %m");
+ goto finish;
+ }
+
+ if (!arg_root_hash) {
+ r = root_hash_load(arg_image, &arg_root_hash, &arg_root_hash_size);
+ if (r < 0) {
+ log_error_errno(r, "Failed to load root hash file for %s: %m", arg_image);
+ goto finish;
+ }
+ }
}
- if (!mkdtemp(template)) {
- log_error_errno(errno, "Failed to create temporary directory: %m");
- r = -errno;
+ if (!mkdtemp(tmprootdir)) {
+ r = log_error_errno(errno, "Failed to create temporary directory: %m");
goto finish;
}
- arg_directory = strdup(template);
+ remove_tmprootdir = true;
+
+ arg_directory = strdup(tmprootdir);
if (!arg_directory) {
r = log_oom();
goto finish;
}
- image_fd = setup_image(&device_path, &loop_nr);
- if (image_fd < 0) {
- r = image_fd;
+ r = loop_device_make_by_path(arg_image, arg_read_only ? O_RDONLY : O_RDWR, &loop);
+ if (r < 0) {
+ log_error_errno(r, "Failed to set up loopback block device: %m");
goto finish;
}
- r = dissect_image(image_fd,
- &root_device, &root_device_rw,
- &home_device, &home_device_rw,
- &srv_device, &srv_device_rw,
- &esp_device,
- &secondary);
+ r = dissect_image(
+ loop->fd,
+ arg_root_hash, arg_root_hash_size,
+ DISSECT_IMAGE_REQUIRE_ROOT,
+ &dissected_image);
+ if (r == -ENOPKG) {
+ log_error_errno(r, "Could not find a suitable file system or partition table in image: %s", arg_image);
+
+ log_notice("Note that the disk image needs to\n"
+ " a) either contain only a single MBR partition of type 0x83 that is marked bootable\n"
+ " b) or contain a single GPT partition of type 0FC63DAF-8483-4772-8E79-3D69D8477DE4\n"
+ " c) or follow http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/\n"
+ " d) or contain a file system without a partition table\n"
+ "in order to be bootable with systemd-nspawn.");
+ goto finish;
+ }
+ if (r == -EADDRNOTAVAIL) {
+ log_error_errno(r, "No root partition for specified root hash found.");
+ goto finish;
+ }
+ if (r == -EOPNOTSUPP) {
+ log_error_errno(r, "--image= is not supported, compiled without blkid support.");
+ goto finish;
+ }
+ if (r < 0) {
+ log_error_errno(r, "Failed to dissect image: %m");
+ goto finish;
+ }
+
+ if (!arg_root_hash && dissected_image->can_verity)
+ log_notice("Note: image %s contains verity information, but no root hash specified! Proceeding without integrity checking.", arg_image);
+
+ r = dissected_image_decrypt_interactively(dissected_image, NULL, arg_root_hash, arg_root_hash_size, 0, &decrypted_image);
if (r < 0)
goto finish;
+
+ /* Now that we mounted the image, let's try to remove it again, if it is ephemeral */
+ if (remove_image && unlink(arg_image) >= 0)
+ remove_image = false;
}
- r = custom_mounts_prepare();
+ r = custom_mount_prepare_all(arg_directory, arg_custom_mounts, arg_n_custom_mounts);
if (r < 0)
goto finish;
@@ -4311,10 +3925,7 @@ int main(int argc, char *argv[]) {
for (;;) {
r = run(master,
console,
- root_device, root_device_rw,
- home_device, home_device_rw,
- srv_device, srv_device_rw,
- esp_device,
+ dissected_image,
interactive, secondary,
outer_cgver,
fds,
@@ -4328,26 +3939,41 @@ int main(int argc, char *argv[]) {
finish:
sd_notify(false,
- "STOPPING=1\n"
- "STATUS=Terminating...");
+ r == 0 && ret == EXIT_FORCE_RESTART ? "STOPPING=1\nSTATUS=Restarting..." :
+ "STOPPING=1\nSTATUS=Terminating...");
if (helper_pid > 0)
- kill(helper_pid, SIGKILL);
+ (void) kill(helper_pid, SIGKILL);
if (main_pid > 0)
- kill(main_pid, SIGKILL);
+ (void) kill(main_pid, SIGKILL);
/* Try to flush whatever is still queued in the pty */
- if (master >= 0)
- (void) copy_bytes(master, STDOUT_FILENO, (uint64_t) -1, false);
+ if (master >= 0) {
+ (void) copy_bytes(master, STDOUT_FILENO, (uint64_t) -1, 0);
+ master = safe_close(master);
+ }
- loop_remove(loop_nr, &image_fd);
+ if (helper_pid > 0)
+ (void) wait_for_terminate(helper_pid, NULL);
+ if (main_pid > 0)
+ (void) wait_for_terminate(main_pid, NULL);
- if (remove_subvol && arg_directory) {
+ if (remove_directory && arg_directory) {
int k;
- k = btrfs_subvol_remove(arg_directory, BTRFS_REMOVE_RECURSIVE|BTRFS_REMOVE_QUOTA);
+ k = rm_rf(arg_directory, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
if (k < 0)
- log_warning_errno(k, "Cannot remove subvolume '%s', ignoring: %m", arg_directory);
+ log_warning_errno(k, "Cannot remove '%s', ignoring: %m", arg_directory);
+ }
+
+ if (remove_image && arg_image) {
+ if (unlink(arg_image) < 0)
+ log_warning_errno(errno, "Can't remove image file '%s', ignoring: %m", arg_image);
+ }
+
+ if (remove_tmprootdir) {
+ if (rmdir(tmprootdir) < 0)
+ log_debug_errno(errno, "Can't remove temporary root directory '%s', ignoring: %m", tmprootdir);
}
if (arg_machine) {
@@ -4368,6 +3994,8 @@ finish:
free(arg_image);
free(arg_machine);
free(arg_user);
+ free(arg_pivot_root_new);
+ free(arg_pivot_root_old);
free(arg_chdir);
strv_free(arg_setenv);
free(arg_network_bridge);
@@ -4378,6 +4006,7 @@ finish:
strv_free(arg_parameters);
custom_mount_free_all(arg_custom_mounts, arg_n_custom_mounts);
expose_port_free_all(arg_expose_ports);
+ free(arg_root_hash);
return r < 0 ? EXIT_FAILURE : ret;
}
diff --git a/src/nss-myhostname/nss-myhostname.c b/src/nss-myhostname/nss-myhostname.c
index 11c27575c0..0570fde592 100644
--- a/src/nss-myhostname/nss-myhostname.c
+++ b/src/nss-myhostname/nss-myhostname.c
@@ -55,7 +55,7 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
_cleanup_free_ struct local_address *addresses = NULL;
_cleanup_free_ char *hn = NULL;
const char *canonical = NULL;
- int n_addresses = 0, lo_ifi;
+ int n_addresses = 0;
uint32_t local_address_ipv4;
struct local_address *a;
size_t l, idx, ms;
@@ -111,14 +111,11 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
local_address_ipv4 = LOCALADDRESS_IPV4;
}
- /* If this call fails we fill in 0 as scope. Which is fine */
- lo_ifi = n_addresses <= 0 ? LOOPBACK_IFINDEX : 0;
-
l = strlen(canonical);
ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * (n_addresses > 0 ? n_addresses : 2);
if (buflen < ms) {
- *errnop = ENOMEM;
- *h_errnop = NO_RECOVERY;
+ *errnop = ERANGE;
+ *h_errnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
@@ -135,7 +132,7 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
r_tuple->name = r_name;
r_tuple->family = AF_INET6;
memcpy(r_tuple->addr, LOCALADDRESS_IPV6, 16);
- r_tuple->scopeid = (uint32_t) lo_ifi;
+ r_tuple->scopeid = 0;
idx += ALIGN(sizeof(struct gaih_addrtuple));
r_tuple_prev = r_tuple;
@@ -146,7 +143,7 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
r_tuple->name = r_name;
r_tuple->family = AF_INET;
*(uint32_t*) r_tuple->addr = local_address_ipv4;
- r_tuple->scopeid = (uint32_t) lo_ifi;
+ r_tuple->scopeid = 0;
idx += ALIGN(sizeof(struct gaih_addrtuple));
r_tuple_prev = r_tuple;
@@ -158,7 +155,7 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
r_tuple->next = r_tuple_prev;
r_tuple->name = r_name;
r_tuple->family = a->family;
- r_tuple->scopeid = a->ifindex;
+ r_tuple->scopeid = a->family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&a->address.in6) ? a->ifindex : 0;
memcpy(r_tuple->addr, &a->address, 16);
idx += ALIGN(sizeof(struct gaih_addrtuple));
@@ -223,8 +220,8 @@ static enum nss_status fill_in_hostent(
(c > 0 ? c+1 : 2) * sizeof(char*);
if (buflen < ms) {
- *errnop = ENOMEM;
- *h_errnop = NO_RECOVERY;
+ *errnop = ERANGE;
+ *h_errnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
diff --git a/src/nss-mymachines/nss-mymachines.c b/src/nss-mymachines/nss-mymachines.c
index 895f61c462..ea90953abb 100644
--- a/src/nss-mymachines/nss-mymachines.c
+++ b/src/nss-mymachines/nss-mymachines.c
@@ -151,8 +151,8 @@ enum nss_status _nss_mymachines_gethostbyname4_r(
l = strlen(name);
ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * c;
if (buflen < ms) {
- *errnop = ENOMEM;
- *h_errnop = TRY_AGAIN;
+ *errnop = ERANGE;
+ *h_errnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
@@ -306,8 +306,8 @@ enum nss_status _nss_mymachines_gethostbyname3_r(
ms = ALIGN(l+1) + c * ALIGN(alen) + (c+2) * sizeof(char*);
if (buflen < ms) {
- *errnop = ENOMEM;
- *h_errnop = NO_RECOVERY;
+ *errnop = ERANGE;
+ *h_errnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
@@ -471,7 +471,7 @@ enum nss_status _nss_mymachines_getpwnam_r(
l = strlen(name);
if (buflen < l+1) {
- *errnop = ENOMEM;
+ *errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
@@ -512,10 +512,8 @@ enum nss_status _nss_mymachines_getpwuid_r(
BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
- if (!uid_is_valid(uid)) {
- r = -EINVAL;
- goto fail;
- }
+ if (!uid_is_valid(uid))
+ goto not_found;
/* We consider all uids < 65536 host uids */
if (uid < HOST_UID_LIMIT)
@@ -552,7 +550,7 @@ enum nss_status _nss_mymachines_getpwuid_r(
goto not_found;
if (snprintf(buffer, buflen, "vu-%s-" UID_FMT, machine, (uid_t) mapped) >= (int) buflen) {
- *errnop = ENOMEM;
+ *errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
@@ -647,7 +645,7 @@ enum nss_status _nss_mymachines_getgrnam_r(
l = sizeof(char*) + strlen(name) + 1;
if (buflen < l) {
- *errnop = ENOMEM;
+ *errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
@@ -686,10 +684,8 @@ enum nss_status _nss_mymachines_getgrgid_r(
BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
- if (!gid_is_valid(gid)) {
- r = -EINVAL;
- goto fail;
- }
+ if (!gid_is_valid(gid))
+ goto not_found;
/* We consider all gids < 65536 host gids */
if (gid < HOST_GID_LIMIT)
@@ -726,13 +722,13 @@ enum nss_status _nss_mymachines_getgrgid_r(
goto not_found;
if (buflen < sizeof(char*) + 1) {
- *errnop = ENOMEM;
+ *errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
memzero(buffer, sizeof(char*));
if (snprintf(buffer + sizeof(char*), buflen - sizeof(char*), "vg-%s-" GID_FMT, machine, (gid_t) mapped) >= (int) buflen) {
- *errnop = ENOMEM;
+ *errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
diff --git a/src/nss-resolve/nss-resolve.c b/src/nss-resolve/nss-resolve.c
index d46a3afe91..ec059d9586 100644
--- a/src/nss-resolve/nss-resolve.c
+++ b/src/nss-resolve/nss-resolve.c
@@ -17,7 +17,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <dlfcn.h>
#include <errno.h>
#include <netdb.h>
#include <nss.h>
@@ -39,20 +38,6 @@ NSS_GETHOSTBYADDR_PROTOTYPES(resolve);
#define DNS_CALL_TIMEOUT_USEC (45*USEC_PER_SEC)
-typedef void (*voidfunc_t)(void);
-
-static voidfunc_t find_fallback(const char *module, const char *symbol) {
- void *dl;
-
- /* Try to find a fallback NSS module symbol */
-
- dl = dlopen(module, RTLD_LAZY|RTLD_NODELETE);
- if (!dl)
- return NULL;
-
- return dlsym(dl, symbol);
-}
-
static bool bus_error_shall_fallback(sd_bus_error *e) {
return sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN) ||
sd_bus_error_has_name(e, SD_BUS_ERROR_NAME_HAS_NO_OWNER) ||
@@ -110,6 +95,20 @@ static int count_addresses(sd_bus_message *m, int af, const char **canonical) {
return c;
}
+static uint32_t ifindex_to_scopeid(int family, const void *a, int ifindex) {
+ struct in6_addr in6;
+
+ if (family != AF_INET6)
+ return 0;
+
+ /* Some apps can't deal with the scope ID attached to non-link-local addresses. Hence, let's suppress that. */
+
+ assert(sizeof(in6) == FAMILY_ADDRESS_SIZE(AF_INET6));
+ memcpy(&in6, a, sizeof(struct in6_addr));
+
+ return IN6_IS_ADDR_LINKLOCAL(&in6) ? ifindex : 0;
+}
+
enum nss_status _nss_resolve_gethostbyname4_r(
const char *name,
struct gaih_addrtuple **pat,
@@ -137,7 +136,7 @@ enum nss_status _nss_resolve_gethostbyname4_r(
r = sd_bus_open_system(&bus);
if (r < 0)
- goto fallback;
+ goto fail;
r = sd_bus_message_new_method_call(
bus,
@@ -165,13 +164,14 @@ enum nss_status _nss_resolve_gethostbyname4_r(
return NSS_STATUS_NOTFOUND;
}
- if (bus_error_shall_fallback(&error))
- goto fallback;
+ /* Return NSS_STATUS_UNAVAIL when communication with systemd-resolved fails,
+ allowing falling back to other nss modules. Treat all other error conditions as
+ NOTFOUND. This includes DNSSEC errors and suchlike. (We don't use UNAVAIL in this
+ case so that the nsswitch.conf configuration can distuingish such executed but
+ negative replies from complete failure to talk to resolved). */
+ if (!bus_error_shall_fallback(&error))
+ ret = NSS_STATUS_NOTFOUND;
- /* Treat all other error conditions as NOTFOUND, and fail. This includes DNSSEC errors and
- suchlike. (We don't use UNAVAIL in this case so that the nsswitch.conf configuration can distuingish
- such executed but negative replies from complete failure to talk to resolved. */
- ret = NSS_STATUS_NOTFOUND;
goto fail;
}
@@ -192,8 +192,8 @@ enum nss_status _nss_resolve_gethostbyname4_r(
l = strlen(canonical);
ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * c;
if (buflen < ms) {
- *errnop = ENOMEM;
- *h_errnop = TRY_AGAIN;
+ *errnop = ERANGE;
+ *h_errnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
@@ -245,7 +245,7 @@ enum nss_status _nss_resolve_gethostbyname4_r(
r_tuple->next = i == c-1 ? NULL : (struct gaih_addrtuple*) ((char*) r_tuple + ALIGN(sizeof(struct gaih_addrtuple)));
r_tuple->name = r_name;
r_tuple->family = family;
- r_tuple->scopeid = ifindex;
+ r_tuple->scopeid = ifindex_to_scopeid(family, a, ifindex);
memcpy(r_tuple->addr, a, sz);
idx += ALIGN(sizeof(struct gaih_addrtuple));
@@ -272,17 +272,6 @@ enum nss_status _nss_resolve_gethostbyname4_r(
return NSS_STATUS_SUCCESS;
-fallback:
- {
- _nss_gethostbyname4_r_t fallback;
-
- fallback = (_nss_gethostbyname4_r_t)
- find_fallback("libnss_dns.so.2", "_nss_dns_gethostbyname4_r");
-
- if (fallback)
- return fallback(name, pat, buffer, buflen, errnop, h_errnop, ttlp);
- }
-
fail:
*errnop = -r;
*h_errnop = NO_RECOVERY;
@@ -325,7 +314,7 @@ enum nss_status _nss_resolve_gethostbyname3_r(
r = sd_bus_open_system(&bus);
if (r < 0)
- goto fallback;
+ goto fail;
r = sd_bus_message_new_method_call(
bus,
@@ -353,10 +342,9 @@ enum nss_status _nss_resolve_gethostbyname3_r(
return NSS_STATUS_NOTFOUND;
}
- if (bus_error_shall_fallback(&error))
- goto fallback;
+ if (!bus_error_shall_fallback(&error))
+ ret = NSS_STATUS_NOTFOUND;
- ret = NSS_STATUS_NOTFOUND;
goto fail;
}
@@ -380,8 +368,8 @@ enum nss_status _nss_resolve_gethostbyname3_r(
ms = ALIGN(l+1) + c * ALIGN(alen) + (c+2) * sizeof(char*);
if (buflen < ms) {
- *errnop = ENOMEM;
- *h_errnop = TRY_AGAIN;
+ *errnop = ERANGE;
+ *h_errnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
@@ -470,16 +458,6 @@ enum nss_status _nss_resolve_gethostbyname3_r(
return NSS_STATUS_SUCCESS;
-fallback:
- {
- _nss_gethostbyname3_r_t fallback;
-
- fallback = (_nss_gethostbyname3_r_t)
- find_fallback("libnss_dns.so.2", "_nss_dns_gethostbyname3_r");
- if (fallback)
- return fallback(name, af, result, buffer, buflen, errnop, h_errnop, ttlp, canonp);
- }
-
fail:
*errnop = -r;
*h_errnop = NO_RECOVERY;
@@ -526,7 +504,7 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
r = sd_bus_open_system(&bus);
if (r < 0)
- goto fallback;
+ goto fail;
r = sd_bus_message_new_method_call(
bus,
@@ -562,10 +540,9 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
return NSS_STATUS_NOTFOUND;
}
- if (bus_error_shall_fallback(&error))
- goto fallback;
+ if (!bus_error_shall_fallback(&error))
+ ret = NSS_STATUS_NOTFOUND;
- ret = NSS_STATUS_NOTFOUND;
goto fail;
}
@@ -601,8 +578,8 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
c * sizeof(char*); /* pointers to aliases, plus trailing NULL */
if (buflen < ms) {
- *errnop = ENOMEM;
- *h_errnop = TRY_AGAIN;
+ *errnop = ERANGE;
+ *h_errnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
@@ -660,17 +637,6 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
return NSS_STATUS_SUCCESS;
-fallback:
- {
- _nss_gethostbyaddr2_r_t fallback;
-
- fallback = (_nss_gethostbyaddr2_r_t)
- find_fallback("libnss_dns.so.2", "_nss_dns_gethostbyaddr2_r");
-
- if (fallback)
- return fallback(addr, len, af, result, buffer, buflen, errnop, h_errnop, ttlp);
- }
-
fail:
*errnop = -r;
*h_errnop = NO_RECOVERY;
diff --git a/src/nss-systemd/nss-systemd.c b/src/nss-systemd/nss-systemd.c
index 17d04e958d..f404755dac 100644
--- a/src/nss-systemd/nss-systemd.c
+++ b/src/nss-systemd/nss-systemd.c
@@ -33,14 +33,6 @@
#include "user-util.h"
#include "util.h"
-#ifndef NOBODY_USER_NAME
-#define NOBODY_USER_NAME "nobody"
-#endif
-
-#ifndef NOBODY_GROUP_NAME
-#define NOBODY_GROUP_NAME "nobody"
-#endif
-
static const struct passwd root_passwd = {
.pw_name = (char*) "root",
.pw_passwd = (char*) "x", /* see shadow file */
@@ -131,10 +123,10 @@ enum nss_status _nss_systemd_getpwnam_r(
assert(name);
assert(pwd);
- if (!valid_user_group_name(name)) {
- r = -EINVAL;
- goto fail;
- }
+ /* If the username is not valid, then we don't know it. Ideally libc would filter these for us anyway. We don't
+ * generate EINVAL here, because it isn't really out business to complain about invalid user names. */
+ if (!valid_user_group_name(name))
+ goto not_found;
/* Synthesize entries for the root and nobody users, in case they are missing in /etc/passwd */
if (streq(name, root_passwd.pw_name)) {
@@ -193,7 +185,7 @@ enum nss_status _nss_systemd_getpwnam_r(
l = strlen(name);
if (buflen < l+1) {
- *errnop = ENOMEM;
+ *errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
@@ -235,10 +227,8 @@ enum nss_status _nss_systemd_getpwuid_r(
BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
- if (!uid_is_valid(uid)) {
- r = -EINVAL;
- goto fail;
- }
+ if (!uid_is_valid(uid))
+ goto not_found;
/* Synthesize data for the root user and for nobody in case they are missing from /etc/passwd */
if (uid == root_passwd.pw_uid) {
@@ -296,7 +286,7 @@ enum nss_status _nss_systemd_getpwuid_r(
l = strlen(translated) + 1;
if (buflen < l) {
- *errnop = ENOMEM;
+ *errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
@@ -337,10 +327,8 @@ enum nss_status _nss_systemd_getgrnam_r(
assert(name);
assert(gr);
- if (!valid_user_group_name(name)) {
- r = -EINVAL;
- goto fail;
- }
+ if (!valid_user_group_name(name))
+ goto not_found;
/* Synthesize records for root and nobody, in case they are missing form /etc/group */
if (streq(name, root_group.gr_name)) {
@@ -398,7 +386,7 @@ enum nss_status _nss_systemd_getgrnam_r(
l = sizeof(char*) + strlen(name) + 1;
if (buflen < l) {
- *errnop = ENOMEM;
+ *errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
@@ -438,10 +426,8 @@ enum nss_status _nss_systemd_getgrgid_r(
BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
- if (!gid_is_valid(gid)) {
- r = -EINVAL;
- goto fail;
- }
+ if (!gid_is_valid(gid))
+ goto not_found;
/* Synthesize records for root and nobody, in case they are missing from /etc/group */
if (gid == root_group.gr_gid) {
@@ -498,7 +484,7 @@ enum nss_status _nss_systemd_getgrgid_r(
l = sizeof(char*) + strlen(translated) + 1;
if (buflen < l) {
- *errnop = ENOMEM;
+ *errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
diff --git a/src/quotacheck/quotacheck.c b/src/quotacheck/quotacheck.c
index 2714cde5c7..a42fce377e 100644
--- a/src/quotacheck/quotacheck.c
+++ b/src/quotacheck/quotacheck.c
@@ -34,7 +34,10 @@ static bool arg_force = false;
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
- if (streq(key, "quotacheck.mode") && value) {
+ if (streq(key, "quotacheck.mode")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
if (streq(value, "auto"))
arg_force = arg_skip = false;
@@ -88,7 +91,7 @@ int main(int argc, char *argv[]) {
umask(0022);
- r = parse_proc_cmdline(parse_proc_cmdline_item, NULL, false);
+ r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
if (r < 0)
log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
@@ -104,9 +107,10 @@ int main(int argc, char *argv[]) {
pid = fork();
if (pid < 0) {
- log_error_errno(errno, "fork(): %m");
- return EXIT_FAILURE;
- } else if (pid == 0) {
+ r = log_error_errno(errno, "fork(): %m");
+ goto finish;
+ }
+ if (pid == 0) {
/* Child */
@@ -120,5 +124,6 @@ int main(int argc, char *argv[]) {
r = wait_for_terminate_and_warn("quotacheck", pid, true);
+finish:
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/src/rc-local-generator/rc-local-generator.c b/src/rc-local-generator/rc-local-generator.c
index 618bbe428d..b704ca3b4b 100644
--- a/src/rc-local-generator/rc-local-generator.c
+++ b/src/rc-local-generator/rc-local-generator.c
@@ -45,11 +45,11 @@ static int add_symlink(const char *service, const char *where) {
assert(service);
assert(where);
- from = strjoin(SYSTEM_DATA_UNIT_PATH, "/", service, NULL);
+ from = strjoin(SYSTEM_DATA_UNIT_PATH, "/", service);
if (!from)
return log_oom();
- to = strjoin(arg_dest, "/", where, ".wants/", service, NULL);
+ to = strjoin(arg_dest, "/", where, ".wants/", service);
if (!to)
return log_oom();
diff --git a/src/remount-fs/remount-fs.c b/src/remount-fs/remount-fs.c
index c3bdcaf1da..0cb9bd9261 100644
--- a/src/remount-fs/remount-fs.c
+++ b/src/remount-fs/remount-fs.c
@@ -56,7 +56,7 @@ int main(int argc, char *argv[]) {
umask(0022);
- f = setmntent("/etc/fstab", "r");
+ f = setmntent("/etc/fstab", "re");
if (!f) {
if (errno == ENOENT) {
r = 0;
diff --git a/src/reply-password/reply-password.c b/src/reply-password/reply-password.c
index 17eab9772e..a17c8a62b8 100644
--- a/src/reply-password/reply-password.c
+++ b/src/reply-password/reply-password.c
@@ -90,7 +90,7 @@ int main(int argc, char *argv[]) {
r = send_on_socket(fd, argv[2], packet, length);
finish:
- memory_erase(packet, sizeof(packet));
+ explicit_bzero(packet, sizeof(packet));
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/src/resolve/resolve-tool.c b/src/resolve/resolve-tool.c
index 9d4d04220c..c62058917f 100644
--- a/src/resolve/resolve-tool.c
+++ b/src/resolve/resolve-tool.c
@@ -38,7 +38,7 @@
#include "strv.h"
#include "terminal-util.h"
-#define DNS_CALL_TIMEOUT_USEC (45*USEC_PER_SEC)
+#define DNS_CALL_TIMEOUT_USEC (90*USEC_PER_SEC)
static int arg_family = AF_UNSPEC;
static int arg_ifindex = 0;
@@ -114,8 +114,8 @@ static void print_source(uint64_t flags, usec_t rtt) {
flags & SD_RESOLVED_DNS ? " DNS" :"",
flags & SD_RESOLVED_LLMNR_IPV4 ? " LLMNR/IPv4" : "",
flags & SD_RESOLVED_LLMNR_IPV6 ? " LLMNR/IPv6" : "",
- flags & SD_RESOLVED_MDNS_IPV4 ? "mDNS/IPv4" : "",
- flags & SD_RESOLVED_MDNS_IPV6 ? "mDNS/IPv6" : "");
+ flags & SD_RESOLVED_MDNS_IPV4 ? " mDNS/IPv4" : "",
+ flags & SD_RESOLVED_MDNS_IPV6 ? " mDNS/IPv6" : "");
assert_se(format_timespan(rtt_str, sizeof(rtt_str), rtt, 100));
@@ -881,8 +881,8 @@ static int resolve_tlsa(sd_bus *bus, const char *address) {
port = strrchr(address, ':');
if (port) {
- r = safe_atou16(port + 1, &port_num);
- if (r < 0 || port_num == 0)
+ r = parse_ip_port(port + 1, &port_num);
+ if (r < 0)
return log_error_errno(r, "Invalid port \"%s\".", port + 1);
address = strndupa(address, port - address);
@@ -1186,6 +1186,7 @@ static int status_ifindex(sd_bus *bus, int ifindex, const char *name, bool *empt
{}
};
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_free_ char *ifi = NULL, *p = NULL;
char ifname[IF_NAMESIZE] = "";
char **i;
@@ -1213,9 +1214,10 @@ static int status_ifindex(sd_bus *bus, int ifindex, const char *name, bool *empt
"org.freedesktop.resolve1",
p,
property_map,
+ &error,
&link_info);
if (r < 0) {
- log_error_errno(r, "Failed to get link data for %i: %m", ifindex);
+ log_error_errno(r, "Failed to get link data for %i: %s", ifindex, bus_error_message(&error, r));
goto finish;
}
@@ -1405,6 +1407,7 @@ static int status_global(sd_bus *bus, bool *empty_line) {
{}
};
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
char **i;
int r;
@@ -1415,9 +1418,10 @@ static int status_global(sd_bus *bus, bool *empty_line) {
"org.freedesktop.resolve1",
"/org/freedesktop/resolve1",
property_map,
+ &error,
&global_info);
if (r < 0) {
- log_error_errno(r, "Failed to get global data: %m");
+ log_error_errno(r, "Failed to get global data: %s", bus_error_message(&error, r));
goto finish;
}
@@ -1524,7 +1528,7 @@ static int status_all(sd_bus *bus) {
static void help_protocol_types(void) {
if (arg_legend)
puts("Known protocol types:");
- puts("dns\nllmnr\nllmnr-ipv4\nllmnr-ipv6");
+ puts("dns\nllmnr\nllmnr-ipv4\nllmnr-ipv6\nmdns\nmnds-ipv4\nmdns-ipv6");
}
static void help_dns_types(void) {
@@ -1722,6 +1726,12 @@ static int parse_argv(int argc, char *argv[]) {
arg_flags |= SD_RESOLVED_LLMNR_IPV4;
else if (streq(optarg, "llmnr-ipv6"))
arg_flags |= SD_RESOLVED_LLMNR_IPV6;
+ else if (streq(optarg, "mdns"))
+ arg_flags |= SD_RESOLVED_MDNS;
+ else if (streq(optarg, "mdns-ipv4"))
+ arg_flags |= SD_RESOLVED_MDNS_IPV4;
+ else if (streq(optarg, "mdns-ipv6"))
+ arg_flags |= SD_RESOLVED_MDNS_IPV6;
else {
log_error("Unknown protocol specifier: %s", optarg);
return -EINVAL;
diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
index 2ca65e6953..2c50109388 100644
--- a/src/resolve/resolved-bus.c
+++ b/src/resolve/resolved-bus.c
@@ -211,7 +211,7 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) {
r = sd_bus_message_append(
reply, "st",
normalized,
- SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, q->answer_authenticated));
+ SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q)));
if (r < 0)
goto finish;
@@ -439,7 +439,7 @@ static void bus_method_resolve_address_complete(DnsQuery *q) {
if (r < 0)
goto finish;
- r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, q->answer_authenticated));
+ r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q)));
if (r < 0)
goto finish;
@@ -605,7 +605,7 @@ static void bus_method_resolve_record_complete(DnsQuery *q) {
if (r < 0)
goto finish;
- r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, q->answer_authenticated));
+ r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q)));
if (r < 0)
goto finish;
@@ -979,7 +979,7 @@ static void resolve_service_all_complete(DnsQuery *q) {
reply,
"ssst",
name, type, domain,
- SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, q->answer_authenticated));
+ SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q)));
if (r < 0)
goto finish;
diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c
index ab85754bf7..db86b4dcf6 100644
--- a/src/resolve/resolved-dns-answer.c
+++ b/src/resolve/resolved-dns-answer.c
@@ -148,7 +148,7 @@ int dns_answer_add(DnsAnswer *a, DnsResourceRecord *rr, int ifindex, DnsAnswerFl
* match. We don't really care if they match
* precisely, but we do care whether one is 0
* and the other is not. See RFC 2181, Section
- * 5.2.*/
+ * 5.2. */
if ((rr->ttl == 0) != (a->items[i].rr->ttl == 0))
return -EINVAL;
diff --git a/src/resolve/resolved-dns-answer.h b/src/resolve/resolved-dns-answer.h
index 4a92bd1150..11d2e25eeb 100644
--- a/src/resolve/resolved-dns-answer.h
+++ b/src/resolve/resolved-dns-answer.h
@@ -33,9 +33,11 @@ typedef struct DnsAnswerItem DnsAnswerItem;
* Note that we usually encode the empty DnsAnswer object as a simple NULL. */
typedef enum DnsAnswerFlags {
- DNS_ANSWER_AUTHENTICATED = 1, /* Item has been authenticated */
- DNS_ANSWER_CACHEABLE = 2, /* Item is subject to caching */
- DNS_ANSWER_SHARED_OWNER = 4, /* For mDNS: RRset may be owner by multiple peers */
+ DNS_ANSWER_AUTHENTICATED = 1, /* Item has been authenticated */
+ DNS_ANSWER_CACHEABLE = 2, /* Item is subject to caching */
+ DNS_ANSWER_SHARED_OWNER = 4, /* For mDNS: RRset may be owner by multiple peers */
+ DNS_ANSWER_CACHE_FLUSH = 8, /* For mDNS: sets cache-flush bit in the rrclass of response records */
+ DNS_ANSWER_GOODBYE = 16, /* For mDNS: item is subject to disappear */
} DnsAnswerFlags;
struct DnsAnswerItem {
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
index 9233fb0ac1..f8dab01308 100644
--- a/src/resolve/resolved-dns-cache.c
+++ b/src/resolve/resolved-dns-cache.c
@@ -34,6 +34,10 @@
/* We never keep any item longer than 2h in our cache */
#define CACHE_TTL_MAX_USEC (2 * USEC_PER_HOUR)
+/* How long to cache strange rcodes, i.e. rcodes != SUCCESS and != NXDOMAIN (specifically: that's only SERVFAIL for
+ * now) */
+#define CACHE_TTL_STRANGE_RCODE_USEC (30 * USEC_PER_SEC)
+
typedef enum DnsCacheItemType DnsCacheItemType;
typedef struct DnsCacheItem DnsCacheItem;
@@ -41,12 +45,14 @@ enum DnsCacheItemType {
DNS_CACHE_POSITIVE,
DNS_CACHE_NODATA,
DNS_CACHE_NXDOMAIN,
+ DNS_CACHE_RCODE, /* "strange" RCODE (effective only SERVFAIL for now) */
};
struct DnsCacheItem {
DnsCacheItemType type;
DnsResourceKey *key;
DnsResourceRecord *rr;
+ int rcode;
usec_t until;
bool authenticated:1;
@@ -60,6 +66,27 @@ struct DnsCacheItem {
LIST_FIELDS(DnsCacheItem, by_key);
};
+static const char *dns_cache_item_type_to_string(DnsCacheItem *item) {
+ assert(item);
+
+ switch (item->type) {
+
+ case DNS_CACHE_POSITIVE:
+ return "POSITIVE";
+
+ case DNS_CACHE_NODATA:
+ return "NODATA";
+
+ case DNS_CACHE_NXDOMAIN:
+ return "NXDOMAIN";
+
+ case DNS_CACHE_RCODE:
+ return dns_rcode_to_string(item->rcode);
+ }
+
+ return NULL;
+}
+
static void dns_cache_item_free(DnsCacheItem *i) {
if (!i)
return;
@@ -406,7 +433,7 @@ static int dns_cache_put_positive(
return 0;
}
- /* Entry exists already? Update TTL, timestamp and owner*/
+ /* Entry exists already? Update TTL, timestamp and owner */
existing = dns_cache_get(c, rr);
if (existing) {
dns_cache_item_update_positive(
@@ -484,7 +511,6 @@ static int dns_cache_put_negative(
assert(c);
assert(key);
- assert(soa);
assert(owner_address);
/* Never cache pseudo RR keys. DNS_TYPE_ANY is particularly
@@ -495,13 +521,17 @@ static int dns_cache_put_negative(
if (dns_type_is_pseudo(key->type))
return 0;
- if (nsec_ttl <= 0 || soa->soa.minimum <= 0 || soa->ttl <= 0) {
- log_debug("Not caching negative entry with zero SOA/NSEC/NSEC3 TTL: %s",
- dns_resource_key_to_string(key, key_str, sizeof key_str));
- return 0;
- }
+ if (IN_SET(rcode, DNS_RCODE_SUCCESS, DNS_RCODE_NXDOMAIN)) {
+ if (!soa)
+ return 0;
- if (!IN_SET(rcode, DNS_RCODE_SUCCESS, DNS_RCODE_NXDOMAIN))
+ /* For negative replies, check if we have a TTL of a SOA */
+ if (nsec_ttl <= 0 || soa->soa.minimum <= 0 || soa->ttl <= 0) {
+ log_debug("Not caching negative entry with zero SOA/NSEC/NSEC3 TTL: %s",
+ dns_resource_key_to_string(key, key_str, sizeof key_str));
+ return 0;
+ }
+ } else if (rcode != DNS_RCODE_SERVFAIL)
return 0;
r = dns_cache_init(c);
@@ -514,12 +544,17 @@ static int dns_cache_put_negative(
if (!i)
return -ENOMEM;
- i->type = rcode == DNS_RCODE_SUCCESS ? DNS_CACHE_NODATA : DNS_CACHE_NXDOMAIN;
- i->until = calculate_until(soa, nsec_ttl, timestamp, true);
+ i->type =
+ rcode == DNS_RCODE_SUCCESS ? DNS_CACHE_NODATA :
+ rcode == DNS_RCODE_NXDOMAIN ? DNS_CACHE_NXDOMAIN : DNS_CACHE_RCODE;
+ i->until =
+ i->type == DNS_CACHE_RCODE ? timestamp + CACHE_TTL_STRANGE_RCODE_USEC :
+ calculate_until(soa, nsec_ttl, timestamp, true);
i->authenticated = authenticated;
i->owner_family = owner_family;
i->owner_address = *owner_address;
i->prioq_idx = PRIOQ_IDX_NULL;
+ i->rcode = rcode;
if (i->type == DNS_CACHE_NXDOMAIN) {
/* NXDOMAIN entries should apply equally to all types, so we use ANY as
@@ -543,7 +578,7 @@ static int dns_cache_put_negative(
return r;
log_debug("Added %s cache entry for %s "USEC_FMT"s",
- i->type == DNS_CACHE_NODATA ? "NODATA" : "NXDOMAIN",
+ dns_cache_item_type_to_string(i),
dns_resource_key_to_string(i->key, key_str, sizeof key_str),
(i->until - timestamp) / USEC_PER_SEC);
@@ -615,6 +650,7 @@ int dns_cache_put(
const union in_addr_union *owner_address) {
DnsResourceRecord *soa = NULL, *rr;
+ bool weird_rcode = false;
DnsAnswerFlags flags;
unsigned cache_keys;
int r, ifindex;
@@ -624,18 +660,28 @@ int dns_cache_put(
dns_cache_remove_previous(c, key, answer);
- /* We only care for positive replies and NXDOMAINs, on all
- * other replies we will simply flush the respective entries,
- * and that's it */
- if (!IN_SET(rcode, DNS_RCODE_SUCCESS, DNS_RCODE_NXDOMAIN))
- return 0;
+ /* We only care for positive replies and NXDOMAINs, on all other replies we will simply flush the respective
+ * entries, and that's it. (Well, with one further exception: since some DNS zones (akamai!) return SERVFAIL
+ * consistently for some lookups, and forwarders tend to propagate that we'll cache that too, but only for a
+ * short time.) */
- if (dns_answer_size(answer) <= 0) {
- char key_str[DNS_RESOURCE_KEY_STRING_MAX];
+ if (IN_SET(rcode, DNS_RCODE_SUCCESS, DNS_RCODE_NXDOMAIN)) {
- log_debug("Not caching negative entry without a SOA record: %s",
- dns_resource_key_to_string(key, key_str, sizeof key_str));
- return 0;
+ if (dns_answer_size(answer) <= 0) {
+ char key_str[DNS_RESOURCE_KEY_STRING_MAX];
+
+ log_debug("Not caching negative entry without a SOA record: %s",
+ dns_resource_key_to_string(key, key_str, sizeof key_str));
+ return 0;
+ }
+
+ } else {
+ /* Only cache SERVFAIL as "weird" rcode for now. We can add more later, should that turn out to be
+ * beneficial. */
+ if (rcode != DNS_RCODE_SERVFAIL)
+ return 0;
+
+ weird_rcode = true;
}
cache_keys = dns_answer_size(answer);
@@ -690,19 +736,20 @@ int dns_cache_put(
if (r > 0)
return 0;
- /* See https://tools.ietf.org/html/rfc2308, which say that a
- * matching SOA record in the packet is used to enable
- * negative caching. */
+ /* See https://tools.ietf.org/html/rfc2308, which say that a matching SOA record in the packet is used to
+ * enable negative caching. We apply one exception though: if we are about to cache a weird rcode we do so
+ * regardless of a SOA. */
r = dns_answer_find_soa(answer, key, &soa, &flags);
if (r < 0)
goto fail;
- if (r == 0)
- return 0;
-
- /* Refuse using the SOA data if it is unsigned, but the key is
- * signed */
- if (authenticated && (flags & DNS_ANSWER_AUTHENTICATED) == 0)
+ if (r == 0 && !weird_rcode)
return 0;
+ if (r > 0) {
+ /* Refuse using the SOA data if it is unsigned, but the key is
+ * signed */
+ if (authenticated && (flags & DNS_ANSWER_AUTHENTICATED) == 0)
+ return 0;
+ }
r = dns_cache_put_negative(
c,
@@ -799,6 +846,7 @@ int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, bool clamp_ttl, int *rcod
DnsCacheItem *j, *first, *nsec = NULL;
bool have_authenticated = false, have_non_authenticated = false;
usec_t current;
+ int found_rcode = -1;
assert(c);
assert(key);
@@ -817,6 +865,8 @@ int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, bool clamp_ttl, int *rcod
*ret = NULL;
*rcode = DNS_RCODE_SUCCESS;
+ *authenticated = false;
+
return 0;
}
@@ -831,6 +881,8 @@ int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, bool clamp_ttl, int *rcod
*ret = NULL;
*rcode = DNS_RCODE_SUCCESS;
+ *authenticated = false;
+
return 0;
}
@@ -842,6 +894,8 @@ int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, bool clamp_ttl, int *rcod
n++;
} else if (j->type == DNS_CACHE_NXDOMAIN)
nxdomain = true;
+ else if (j->type == DNS_CACHE_RCODE)
+ found_rcode = j->rcode;
if (j->authenticated)
have_authenticated = true;
@@ -849,6 +903,19 @@ int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, bool clamp_ttl, int *rcod
have_non_authenticated = true;
}
+ if (found_rcode >= 0) {
+ log_debug("RCODE %s cache hit for %s",
+ dns_rcode_to_string(found_rcode),
+ dns_resource_key_to_string(key, key_str, sizeof(key_str)));
+
+ *ret = NULL;
+ *rcode = found_rcode;
+ *authenticated = false;
+
+ c->n_hit++;
+ return 1;
+ }
+
if (nsec && !IN_SET(key->type, DNS_TYPE_NSEC, DNS_TYPE_DS)) {
/* Note that we won't derive information for DS RRs from an NSEC, because we only cache NSEC RRs from
* the lower-zone of a zone cut, but the DS RRs are on the upper zone. */
@@ -980,7 +1047,7 @@ int dns_cache_export_shared_to_packet(DnsCache *cache, DnsPacket *p) {
if (!j->shared_owner)
continue;
- r = dns_packet_append_rr(p, j->rr, NULL, NULL);
+ r = dns_packet_append_rr(p, j->rr, 0, NULL, NULL);
if (r == -EMSGSIZE && p->protocol == DNS_PROTOCOL_MDNS) {
/* For mDNS, if we're unable to stuff all known answers into the given packet,
* allocate a new one, push the RR into that one and link it to the current one.
@@ -995,7 +1062,7 @@ int dns_cache_export_shared_to_packet(DnsCache *cache, DnsPacket *p) {
/* continue with new packet */
p = p->more;
- r = dns_packet_append_rr(p, j->rr, NULL, NULL);
+ r = dns_packet_append_rr(p, j->rr, 0, NULL, NULL);
}
if (r < 0)
@@ -1042,7 +1109,7 @@ void dns_cache_dump(DnsCache *cache, FILE *f) {
fputs(dns_resource_key_to_string(j->key, key_str, sizeof key_str), f);
fputs(" -- ", f);
- fputs(j->type == DNS_CACHE_NODATA ? "NODATA" : "NXDOMAIN", f);
+ fputs(dns_cache_item_type_to_string(j), f);
fputc('\n', f);
}
}
diff --git a/src/resolve/resolved-dns-dnssec.c b/src/resolve/resolved-dns-dnssec.c
index d4a267c89f..eddab58a81 100644
--- a/src/resolve/resolved-dns-dnssec.c
+++ b/src/resolve/resolved-dns-dnssec.c
@@ -1303,7 +1303,7 @@ static int nsec3_hashed_domain_format(const uint8_t *hashed, size_t hashed_size,
if (!l)
return -ENOMEM;
- j = strjoin(l, ".", zone, NULL);
+ j = strjoin(l, ".", zone);
if (!j)
return -ENOMEM;
@@ -1710,7 +1710,8 @@ static int dnssec_nsec_covers(DnsResourceRecord *rr, const char *name) {
}
static int dnssec_nsec_covers_wildcard(DnsResourceRecord *rr, const char *name) {
- const char *common_suffix, *wc;
+ _cleanup_free_ char *wc = NULL;
+ const char *common_suffix;
int r;
assert(rr);
@@ -1734,7 +1735,10 @@ static int dnssec_nsec_covers_wildcard(DnsResourceRecord *rr, const char *name)
if (r <= 0)
return r;
- wc = strjoina("*.", common_suffix);
+ r = dns_name_concat("*", common_suffix, &wc);
+ if (r < 0)
+ return r;
+
return dns_name_between(dns_resource_key_name(rr->key), wc, rr->nsec.next_domain_name);
}
diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c
index 337a8c473f..a486216d68 100644
--- a/src/resolve/resolved-dns-packet.c
+++ b/src/resolve/resolved-dns-packet.c
@@ -28,6 +28,9 @@
#define EDNS0_OPT_DO (1<<15)
+#define DNS_PACKET_SIZE_START 512u
+assert_cc(DNS_PACKET_SIZE_START > UDP_PACKET_HEADER_SIZE)
+
typedef struct DnsPacketRewinder {
DnsPacket *packet;
size_t saved_rindex;
@@ -47,13 +50,14 @@ int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
assert(ret);
- if (mtu <= UDP_PACKET_HEADER_SIZE)
+ /* When dns_packet_new() is called with mtu == 0, allocate more than the
+ * absolute minimum (which is the dns packet header size), to avoid
+ * resizing immediately again after appending the first data to the packet.
+ */
+ if (mtu < UDP_PACKET_HEADER_SIZE)
a = DNS_PACKET_SIZE_START;
else
- a = mtu - UDP_PACKET_HEADER_SIZE;
-
- if (a < DNS_PACKET_HEADER_SIZE)
- a = DNS_PACKET_HEADER_SIZE;
+ a = MAX(mtu, DNS_PACKET_HEADER_SIZE);
/* round up to next page size */
a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));
@@ -569,8 +573,9 @@ fail:
return r;
}
-int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, size_t *start) {
+int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, const DnsAnswerFlags flags, size_t *start) {
size_t saved_size;
+ uint16_t class;
int r;
assert(p);
@@ -586,7 +591,8 @@ int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, size_t *start)
if (r < 0)
goto fail;
- r = dns_packet_append_uint16(p, k->class, NULL);
+ class = flags & DNS_ANSWER_CACHE_FLUSH ? k->class | MDNS_RR_CACHE_FLUSH : k->class;
+ r = dns_packet_append_uint16(p, class, NULL);
if (r < 0)
goto fail;
@@ -791,9 +797,10 @@ int dns_packet_truncate_opt(DnsPacket *p) {
return 1;
}
-int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start, size_t *rdata_start) {
+int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, const DnsAnswerFlags flags, size_t *start, size_t *rdata_start) {
size_t saved_size, rdlength_offset, end, rdlength, rds;
+ uint32_t ttl;
int r;
assert(p);
@@ -801,11 +808,12 @@ int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *star
saved_size = p->size;
- r = dns_packet_append_key(p, rr->key, NULL);
+ r = dns_packet_append_key(p, rr->key, flags, NULL);
if (r < 0)
goto fail;
- r = dns_packet_append_uint32(p, rr->ttl, NULL);
+ ttl = flags & DNS_ANSWER_GOODBYE ? 0 : rr->ttl;
+ r = dns_packet_append_uint32(p, ttl, NULL);
if (r < 0)
goto fail;
@@ -1143,7 +1151,7 @@ int dns_packet_append_question(DnsPacket *p, DnsQuestion *q) {
assert(p);
DNS_QUESTION_FOREACH(key, q) {
- r = dns_packet_append_key(p, key, NULL);
+ r = dns_packet_append_key(p, key, 0, NULL);
if (r < 0)
return r;
}
@@ -1153,12 +1161,13 @@ int dns_packet_append_question(DnsPacket *p, DnsQuestion *q) {
int dns_packet_append_answer(DnsPacket *p, DnsAnswer *a) {
DnsResourceRecord *rr;
+ DnsAnswerFlags flags;
int r;
assert(p);
- DNS_ANSWER_FOREACH(rr, a) {
- r = dns_packet_append_rr(p, rr, NULL, NULL);
+ DNS_ANSWER_FOREACH_FLAGS(rr, flags, a) {
+ r = dns_packet_append_rr(p, rr, flags, NULL, NULL);
if (r < 0)
return r;
}
@@ -2264,6 +2273,9 @@ int dns_packet_is_reply_for(DnsPacket *p, const DnsResourceKey *key) {
if (r < 0)
return r;
+ if (!p->question)
+ return 0;
+
if (p->question->n_keys != 1)
return 0;
diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h
index 054dc88a85..5dff272fd9 100644
--- a/src/resolve/resolved-dns-packet.h
+++ b/src/resolve/resolved-dns-packet.h
@@ -58,15 +58,13 @@ struct DnsPacketHeader {
/* The various DNS protocols deviate in how large a packet can grow,
but the TCP transport has a 16bit size field, hence that appears to
be the absolute maximum. */
-#define DNS_PACKET_SIZE_MAX 0xFFFF
+#define DNS_PACKET_SIZE_MAX 0xFFFFu
/* RFC 1035 say 512 is the maximum, for classic unicast DNS */
-#define DNS_PACKET_UNICAST_SIZE_MAX 512
+#define DNS_PACKET_UNICAST_SIZE_MAX 512u
/* With EDNS0 we can use larger packets, default to 4096, which is what is commonly used */
-#define DNS_PACKET_UNICAST_SIZE_LARGE_MAX 4096
-
-#define DNS_PACKET_SIZE_START 512
+#define DNS_PACKET_UNICAST_SIZE_LARGE_MAX 4096u
struct DnsPacket {
int n_ref;
@@ -209,8 +207,8 @@ int dns_packet_append_string(DnsPacket *p, const char *s, size_t *start);
int dns_packet_append_raw_string(DnsPacket *p, const void *s, size_t size, size_t *start);
int dns_packet_append_label(DnsPacket *p, const char *s, size_t l, bool canonical_candidate, size_t *start);
int dns_packet_append_name(DnsPacket *p, const char *name, bool allow_compression, bool canonical_candidate, size_t *start);
-int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *key, size_t *start);
-int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start, size_t *rdata_start);
+int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *key, const DnsAnswerFlags flags, size_t *start);
+int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, const DnsAnswerFlags flags, size_t *start, size_t *rdata_start);
int dns_packet_append_opt(DnsPacket *p, uint16_t max_udp_size, bool edns0_do, int rcode, size_t *start);
int dns_packet_append_question(DnsPacket *p, DnsQuestion *q);
int dns_packet_append_answer(DnsPacket *p, DnsAnswer *a);
diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c
index e03db4d003..2b091e6c45 100644
--- a/src/resolve/resolved-dns-query.c
+++ b/src/resolve/resolved-dns-query.c
@@ -28,7 +28,7 @@
#include "string-util.h"
/* How long to wait for the query in total */
-#define QUERY_TIMEOUT_USEC (30 * USEC_PER_SEC)
+#define QUERY_TIMEOUT_USEC (60 * USEC_PER_SEC)
#define CNAME_MAX 8
#define QUERIES_MAX 2048
@@ -403,6 +403,7 @@ DnsQuery *dns_query_free(DnsQuery *q) {
sd_bus_track_unref(q->bus_track);
dns_packet_unref(q->request_dns_packet);
+ dns_packet_unref(q->reply_dns_packet);
if (q->request_dns_stream) {
/* Detach the stream from our query, in case something else keeps a reference to it. */
@@ -810,6 +811,7 @@ static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) {
q->answer = dns_answer_unref(q->answer);
q->answer_rcode = 0;
q->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
+ q->answer_authenticated = false;
q->answer_errno = c->error_code;
}
@@ -846,15 +848,18 @@ static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) {
continue;
default:
- /* Any kind of failure? Store the data away,
- * if there's nothing stored yet. */
-
+ /* Any kind of failure? Store the data away, if there's nothing stored yet. */
if (state == DNS_TRANSACTION_SUCCESS)
continue;
+ /* If there's already an authenticated negative reply stored, then prefer that over any unauthenticated one */
+ if (q->answer_authenticated && !t->answer_authenticated)
+ continue;
+
q->answer = dns_answer_unref(q->answer);
q->answer_rcode = t->answer_rcode;
q->answer_dnssec_result = t->answer_dnssec_result;
+ q->answer_authenticated = t->answer_authenticated;
q->answer_errno = t->answer_errno;
state = t->state;
@@ -1028,6 +1033,9 @@ int dns_query_process_cname(DnsQuery *q) {
if (q->flags & SD_RESOLVED_NO_CNAME)
return -ELOOP;
+ if (!q->answer_authenticated)
+ q->previous_redirect_unauthenticated = true;
+
/* OK, let's actually follow the CNAME */
r = dns_query_cname_redirect(q, cname);
if (r < 0)
@@ -1115,3 +1123,9 @@ const char *dns_query_string(DnsQuery *q) {
return dns_question_first_name(q->question_idna);
}
+
+bool dns_query_fully_authenticated(DnsQuery *q) {
+ assert(q);
+
+ return q->answer_authenticated && !q->previous_redirect_unauthenticated;
+}
diff --git a/src/resolve/resolved-dns-query.h b/src/resolve/resolved-dns-query.h
index 49a35b846b..b8ea48f6af 100644
--- a/src/resolve/resolved-dns-query.h
+++ b/src/resolve/resolved-dns-query.h
@@ -71,7 +71,6 @@ struct DnsQuery {
* family */
bool suppress_unroutable_family;
-
/* If true, the RR TTLs of the answer will be clamped by their current left validity in the cache */
bool clamp_ttl;
@@ -90,6 +89,7 @@ struct DnsQuery {
int answer_family;
DnsSearchDomain *answer_search_domain;
int answer_errno; /* if state is DNS_TRANSACTION_ERRNO */
+ bool previous_redirect_unauthenticated;
/* Bus client information */
sd_bus_message *request;
@@ -102,6 +102,7 @@ struct DnsQuery {
/* DNS stub information */
DnsPacket *request_dns_packet;
DnsStream *request_dns_stream;
+ DnsPacket *reply_dns_packet;
/* Completion callback */
void (*complete)(DnsQuery* q);
@@ -139,3 +140,5 @@ DnsQuestion* dns_query_question_for_protocol(DnsQuery *q, DnsProtocol protocol);
const char *dns_query_string(DnsQuery *q);
DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQuery*, dns_query_free);
+
+bool dns_query_fully_authenticated(DnsQuery *q);
diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c
index 87e4abec6e..e8c05ed0da 100644
--- a/src/resolve/resolved-dns-rr.c
+++ b/src/resolve/resolved-dns-rr.c
@@ -792,7 +792,7 @@ static char *format_types(Bitmap *types) {
if (!str)
return NULL;
- return strjoin("( ", str, " )", NULL);
+ return strjoin("( ", str, " )");
}
static char *format_txt(DnsTxtItem *first) {
@@ -861,14 +861,14 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
case DNS_TYPE_NS:
case DNS_TYPE_CNAME:
case DNS_TYPE_DNAME:
- s = strjoin(k, " ", rr->ptr.name, NULL);
+ s = strjoin(k, " ", rr->ptr.name);
if (!s)
return NULL;
break;
case DNS_TYPE_HINFO:
- s = strjoin(k, " ", rr->hinfo.cpu, " ", rr->hinfo.os, NULL);
+ s = strjoin(k, " ", rr->hinfo.cpu, " ", rr->hinfo.os);
if (!s)
return NULL;
break;
@@ -879,7 +879,7 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
if (!t)
return NULL;
- s = strjoin(k, " ", t, NULL);
+ s = strjoin(k, " ", t);
if (!s)
return NULL;
break;
@@ -891,7 +891,7 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
if (r < 0)
return NULL;
- s = strjoin(k, " ", x, NULL);
+ s = strjoin(k, " ", x);
if (!s)
return NULL;
break;
@@ -902,7 +902,7 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
if (r < 0)
return NULL;
- s = strjoin(k, " ", t, NULL);
+ s = strjoin(k, " ", t);
if (!s)
return NULL;
break;
@@ -942,7 +942,7 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
if (!t)
return NULL;
- s = strjoin(k, " ", t, NULL);
+ s = strjoin(k, " ", t);
if (!s)
return NULL;
break;
@@ -1262,7 +1262,7 @@ int dns_resource_record_to_wire_format(DnsResourceRecord *rr, bool canonical) {
if (rr->wire_format && rr->wire_format_canonical == canonical)
return 0;
- r = dns_packet_append_rr(&packet, rr, &start, &rds);
+ r = dns_packet_append_rr(&packet, rr, 0, &start, &rds);
if (r < 0)
return r;
diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c
index 8dbc7f623b..ffaefbe3f2 100644
--- a/src/resolve/resolved-dns-scope.c
+++ b/src/resolve/resolved-dns-scope.c
@@ -124,6 +124,8 @@ DnsScope* dns_scope_free(DnsScope *s) {
ordered_hashmap_free(s->conflict_queue);
sd_event_source_unref(s->conflict_event_source);
+ sd_event_source_unref(s->announce_event_source);
+
dns_cache_flush(&s->cache);
dns_zone_flush(&s->zone);
@@ -549,7 +551,11 @@ static int dns_scope_multicast_membership(DnsScope *s, bool b, struct in_addr in
.imr_ifindex = s->link->ifindex,
};
- fd = manager_llmnr_ipv4_udp_fd(s->manager);
+ if (s->protocol == DNS_PROTOCOL_LLMNR)
+ fd = manager_llmnr_ipv4_udp_fd(s->manager);
+ else
+ fd = manager_mdns_ipv4_fd(s->manager);
+
if (fd < 0)
return fd;
@@ -568,7 +574,11 @@ static int dns_scope_multicast_membership(DnsScope *s, bool b, struct in_addr in
.ipv6mr_interface = s->link->ifindex,
};
- fd = manager_llmnr_ipv6_udp_fd(s->manager);
+ if (s->protocol == DNS_PROTOCOL_LLMNR)
+ fd = manager_llmnr_ipv6_udp_fd(s->manager);
+ else
+ fd = manager_mdns_ipv6_fd(s->manager);
+
if (fd < 0)
return fd;
@@ -601,7 +611,7 @@ int dns_scope_mdns_membership(DnsScope *s, bool b) {
return dns_scope_multicast_membership(s, b, MDNS_MULTICAST_IPV4_ADDRESS, MDNS_MULTICAST_IPV6_ADDRESS);
}
-static int dns_scope_make_reply_packet(
+int dns_scope_make_reply_packet(
DnsScope *s,
uint16_t id,
int rcode,
@@ -830,11 +840,11 @@ static int dns_scope_make_conflict_packet(
DNS_PACKET_HEADER(p)->qdcount = htobe16(1);
DNS_PACKET_HEADER(p)->arcount = htobe16(1);
- r = dns_packet_append_key(p, rr->key, NULL);
+ r = dns_packet_append_key(p, rr->key, 0, NULL);
if (r < 0)
return r;
- r = dns_packet_append_rr(p, rr, NULL, NULL);
+ r = dns_packet_append_rr(p, rr, 0, NULL, NULL);
if (r < 0)
return r;
@@ -928,17 +938,19 @@ void dns_scope_check_conflicts(DnsScope *scope, DnsPacket *p) {
assert(scope);
assert(p);
- if (p->protocol != DNS_PROTOCOL_LLMNR)
+ if (!IN_SET(p->protocol, DNS_PROTOCOL_LLMNR, DNS_PROTOCOL_MDNS))
return;
if (DNS_PACKET_RRCOUNT(p) <= 0)
return;
- if (DNS_PACKET_LLMNR_C(p) != 0)
- return;
+ if (p->protocol == DNS_PROTOCOL_LLMNR) {
+ if (DNS_PACKET_LLMNR_C(p) != 0)
+ return;
- if (DNS_PACKET_LLMNR_T(p) != 0)
- return;
+ if (DNS_PACKET_LLMNR_T(p) != 0)
+ return;
+ }
if (manager_our_packet(scope->manager, p))
return;
@@ -1041,3 +1053,77 @@ int dns_scope_ifindex(DnsScope *s) {
return 0;
}
+
+static int on_announcement_timeout(sd_event_source *s, usec_t usec, void *userdata) {
+ DnsScope *scope = userdata;
+
+ assert(s);
+
+ scope->announce_event_source = sd_event_source_unref(scope->announce_event_source);
+
+ (void) dns_scope_announce(scope, false);
+ return 0;
+}
+
+int dns_scope_announce(DnsScope *scope, bool goodbye) {
+ _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
+ _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
+ LinkAddress *a;
+ int r;
+
+ if (!scope)
+ return 0;
+
+ if (scope->protocol != DNS_PROTOCOL_MDNS)
+ return 0;
+
+ answer = dns_answer_new(scope->link->n_addresses * 2);
+ if (!answer)
+ return log_oom();
+
+ LIST_FOREACH(addresses, a, scope->link->addresses) {
+ r = dns_answer_add(answer, a->mdns_address_rr, 0, goodbye ? DNS_ANSWER_GOODBYE : DNS_ANSWER_CACHE_FLUSH);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to add address RR to answer: %m");
+
+ r = dns_answer_add(answer, a->mdns_ptr_rr, 0, goodbye ? DNS_ANSWER_GOODBYE : DNS_ANSWER_CACHE_FLUSH);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to add PTR RR to answer: %m");
+ }
+
+ if (dns_answer_isempty(answer))
+ return 0;
+
+ r = dns_scope_make_reply_packet(scope, 0, DNS_RCODE_SUCCESS, NULL, answer, NULL, false, &p);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to build reply packet: %m");
+
+ r = dns_scope_emit_udp(scope, -1, p);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to send reply packet: %m");
+
+ /* In section 8.3 of RFC6762: "The Multicast DNS responder MUST send at least two unsolicited
+ * responses, one second apart." */
+ if (!scope->announced) {
+ usec_t ts;
+
+ scope->announced = true;
+
+ assert_se(sd_event_now(scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
+ ts += MDNS_ANNOUNCE_DELAY;
+
+ r = sd_event_add_time(
+ scope->manager->event,
+ &scope->announce_event_source,
+ clock_boottime_or_monotonic(),
+ ts,
+ MDNS_JITTER_RANGE_USEC,
+ on_announcement_timeout, scope);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to schedule second announcement: %m");
+
+ (void) sd_event_source_set_description(scope->announce_event_source, "mdns-announce");
+ }
+
+ return 0;
+}
diff --git a/src/resolve/resolved-dns-scope.h b/src/resolve/resolved-dns-scope.h
index 01a83a76b2..6f94b1fdcd 100644
--- a/src/resolve/resolved-dns-scope.h
+++ b/src/resolve/resolved-dns-scope.h
@@ -56,6 +56,9 @@ struct DnsScope {
OrderedHashmap *conflict_queue;
sd_event_source *conflict_event_source;
+ bool announced:1;
+ sd_event_source *announce_event_source;
+
RateLimit ratelimit;
usec_t resend_timeout;
@@ -96,6 +99,7 @@ void dns_scope_next_dns_server(DnsScope *s);
int dns_scope_llmnr_membership(DnsScope *s, bool b);
int dns_scope_mdns_membership(DnsScope *s, bool b);
+int dns_scope_make_reply_packet(DnsScope *s, uint16_t id, int rcode, DnsQuestion *q, DnsAnswer *answer, DnsAnswer *soa, bool tentative, DnsPacket **ret);
void dns_scope_process_query(DnsScope *s, DnsStream *stream, DnsPacket *p);
DnsTransaction *dns_scope_find_transaction(DnsScope *scope, DnsResourceKey *key, bool cache_ok);
@@ -112,3 +116,5 @@ bool dns_scope_name_needs_search_domain(DnsScope *s, const char *name);
bool dns_scope_network_good(DnsScope *s);
int dns_scope_ifindex(DnsScope *s);
+
+int dns_scope_announce(DnsScope *scope, bool goodbye);
diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c
index 22c64e8491..5498f7b9cb 100644
--- a/src/resolve/resolved-dns-server.c
+++ b/src/resolve/resolved-dns-server.c
@@ -28,7 +28,7 @@
#include "string-util.h"
/* After how much time to repeat classic DNS requests */
-#define DNS_TIMEOUT_MIN_USEC (500 * USEC_PER_MSEC)
+#define DNS_TIMEOUT_MIN_USEC (750 * USEC_PER_MSEC)
#define DNS_TIMEOUT_MAX_USEC (5 * USEC_PER_SEC)
/* The amount of time to wait before retrying with a full feature set */
@@ -399,12 +399,24 @@ static bool dns_server_grace_period_expired(DnsServer *s) {
}
DnsServerFeatureLevel dns_server_possible_feature_level(DnsServer *s) {
+ DnsServerFeatureLevel best;
+
assert(s);
- if (s->possible_feature_level != DNS_SERVER_FEATURE_LEVEL_BEST &&
- dns_server_grace_period_expired(s)) {
+ /* Determine the best feature level we care about. If DNSSEC mode is off there's no point in using anything
+ * better than EDNS0, hence don't even try. */
+ best = dns_server_get_dnssec_mode(s) == DNSSEC_NO ?
+ DNS_SERVER_FEATURE_LEVEL_EDNS0 :
+ DNS_SERVER_FEATURE_LEVEL_BEST;
+
+ /* Clamp the feature level the highest level we care about. The DNSSEC mode might have changed since the last
+ * time, hence let's downgrade if we are still at a higher level. */
+ if (s->possible_feature_level > best)
+ s->possible_feature_level = best;
+
+ if (s->possible_feature_level < best && dns_server_grace_period_expired(s)) {
- s->possible_feature_level = DNS_SERVER_FEATURE_LEVEL_BEST;
+ s->possible_feature_level = best;
dns_server_reset_counters(s);
@@ -415,6 +427,8 @@ DnsServerFeatureLevel dns_server_possible_feature_level(DnsServer *s) {
dns_server_feature_level_to_string(s->possible_feature_level),
dns_server_string(s));
+ dns_server_flush_cache(s);
+
} else if (s->possible_feature_level <= s->verified_feature_level)
s->possible_feature_level = s->verified_feature_level;
else {
@@ -451,18 +465,22 @@ DnsServerFeatureLevel dns_server_possible_feature_level(DnsServer *s) {
s->possible_feature_level = DNS_SERVER_FEATURE_LEVEL_EDNS0;
} else if (s->n_failed_udp >= DNS_SERVER_FEATURE_RETRY_ATTEMPTS &&
- s->possible_feature_level >= DNS_SERVER_FEATURE_LEVEL_UDP) {
+ s->possible_feature_level >= (dns_server_get_dnssec_mode(s) == DNSSEC_YES ? DNS_SERVER_FEATURE_LEVEL_LARGE : DNS_SERVER_FEATURE_LEVEL_UDP)) {
/* We lost too many UDP packets in a row, and are on a feature level of UDP or higher. If the
* packets are lost, maybe the server cannot parse them, hence downgrading sounds like a good
- * idea. We might downgrade all the way down to TCP this way. */
+ * idea. We might downgrade all the way down to TCP this way.
+ *
+ * If strict DNSSEC mode is used we won't downgrade below DO level however, as packet loss
+ * might have many reasons, a broken DNSSEC implementation being only one reason. And if the
+ * user is strict on DNSSEC, then let's assume that DNSSEC is not the fault here. */
log_debug("Lost too many UDP packets, downgrading feature level...");
s->possible_feature_level--;
} else if (s->n_failed_tcp >= DNS_SERVER_FEATURE_RETRY_ATTEMPTS &&
s->packet_truncated &&
- s->possible_feature_level > DNS_SERVER_FEATURE_LEVEL_UDP) {
+ s->possible_feature_level > (dns_server_get_dnssec_mode(s) == DNSSEC_YES ? DNS_SERVER_FEATURE_LEVEL_LARGE : DNS_SERVER_FEATURE_LEVEL_UDP)) {
/* We got too many TCP connection failures in a row, we had at least one truncated packet, and
* are on a feature level above UDP. By downgrading things and getting rid of DNSSEC or EDNS0
@@ -566,7 +584,7 @@ void dns_server_warn_downgrade(DnsServer *server) {
return;
log_struct(LOG_NOTICE,
- LOG_MESSAGE_ID(SD_MESSAGE_DNSSEC_DOWNGRADE),
+ "MESSAGE_ID=" SD_MESSAGE_DNSSEC_DOWNGRADE_STR,
LOG_MESSAGE("Server %s does not support DNSSEC, downgrading to non-DNSSEC mode.", dns_server_string(server)),
"DNS_SERVER=%s", dns_server_string(server),
"DNS_SERVER_FEATURE_LEVEL=%s", dns_server_feature_level_to_string(server->possible_feature_level),
@@ -779,6 +797,34 @@ bool dns_server_address_valid(int family, const union in_addr_union *sa) {
return true;
}
+DnssecMode dns_server_get_dnssec_mode(DnsServer *s) {
+ assert(s);
+
+ if (s->link)
+ return link_get_dnssec_mode(s->link);
+
+ return manager_get_dnssec_mode(s->manager);
+}
+
+void dns_server_flush_cache(DnsServer *s) {
+ DnsServer *current;
+ DnsScope *scope;
+
+ assert(s);
+
+ /* Flush the cache of the scope this server belongs to */
+
+ current = s->link ? s->link->current_dns_server : s->manager->current_dns_server;
+ if (current != s)
+ return;
+
+ scope = s->link ? s->link->unicast_scope : s->manager->unicast_scope;
+ if (!scope)
+ return;
+
+ dns_cache_flush(&scope->cache);
+}
+
static const char* const dns_server_type_table[_DNS_SERVER_TYPE_MAX] = {
[DNS_SERVER_SYSTEM] = "system",
[DNS_SERVER_FALLBACK] = "fallback",
diff --git a/src/resolve/resolved-dns-server.h b/src/resolve/resolved-dns-server.h
index 83e288a202..bc95d53c6a 100644
--- a/src/resolve/resolved-dns-server.h
+++ b/src/resolve/resolved-dns-server.h
@@ -144,6 +144,10 @@ void manager_next_dns_server(Manager *m);
bool dns_server_address_valid(int family, const union in_addr_union *sa);
+DnssecMode dns_server_get_dnssec_mode(DnsServer *s);
+
DEFINE_TRIVIAL_CLEANUP_FUNC(DnsServer*, dns_server_unref);
extern const struct hash_ops dns_server_hash_ops;
+
+void dns_server_flush_cache(DnsServer *s);
diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c
index e76de6c06a..7afbfedfb0 100644
--- a/src/resolve/resolved-dns-stub.c
+++ b/src/resolve/resolved-dns-stub.c
@@ -29,49 +29,33 @@ static int manager_dns_stub_udp_fd(Manager *m);
static int manager_dns_stub_tcp_fd(Manager *m);
static int dns_stub_make_reply_packet(
- uint16_t id,
- int rcode,
+ DnsPacket **p,
DnsQuestion *q,
- DnsAnswer *answer,
- bool add_opt, /* add an OPT RR to this packet */
- bool edns0_do, /* set the EDNS0 DNSSEC OK bit */
- bool ad, /* set the DNSSEC authenticated data bit */
- DnsPacket **ret) {
+ DnsAnswer *answer) {
- _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
DnsResourceRecord *rr;
unsigned c = 0;
int r;
+ assert(p);
+
/* Note that we don't bother with any additional RRs, as this is stub is for local lookups only, and hence
* roundtrips aren't expensive. */
- r = dns_packet_new(&p, DNS_PROTOCOL_DNS, 0);
- if (r < 0)
- return r;
-
- /* If the client didn't do EDNS, clamp the rcode to 4 bit */
- if (!add_opt && rcode > 0xF)
- rcode = DNS_RCODE_SERVFAIL;
+ if (!*p) {
+ r = dns_packet_new(p, DNS_PROTOCOL_DNS, 0);
+ if (r < 0)
+ return r;
- DNS_PACKET_HEADER(p)->id = id;
- DNS_PACKET_HEADER(p)->flags = htobe16(DNS_PACKET_MAKE_FLAGS(
- 1 /* qr */,
- 0 /* opcode */,
- 0 /* aa */,
- 0 /* tc */,
- 1 /* rd */,
- 1 /* ra */,
- ad /* ad */,
- 0 /* cd */,
- rcode));
+ r = dns_packet_append_question(*p, q);
+ if (r < 0)
+ return r;
- r = dns_packet_append_question(p, q);
- if (r < 0)
- return r;
- DNS_PACKET_HEADER(p)->qdcount = htobe16(dns_question_size(q));
+ DNS_PACKET_HEADER(*p)->qdcount = htobe16(dns_question_size(q));
+ }
DNS_ANSWER_FOREACH(rr, answer) {
+
r = dns_question_matches_rr(q, rr, NULL);
if (r < 0)
return r;
@@ -86,13 +70,55 @@ static int dns_stub_make_reply_packet(
continue;
add:
- r = dns_packet_append_rr(p, rr, NULL, NULL);
+ r = dns_packet_append_rr(*p, rr, 0, NULL, NULL);
if (r < 0)
return r;
c++;
}
- DNS_PACKET_HEADER(p)->ancount = htobe16(c);
+
+ DNS_PACKET_HEADER(*p)->ancount = htobe16(be16toh(DNS_PACKET_HEADER(*p)->ancount) + c);
+
+ return 0;
+}
+
+static int dns_stub_finish_reply_packet(
+ DnsPacket *p,
+ uint16_t id,
+ int rcode,
+ bool add_opt, /* add an OPT RR to this packet? */
+ bool edns0_do, /* set the EDNS0 DNSSEC OK bit? */
+ bool ad) { /* set the DNSSEC authenticated data bit? */
+
+ int r;
+
+ assert(p);
+
+ if (!add_opt) {
+ /* If the client can't to EDNS0, don't do DO either */
+ edns0_do = false;
+
+ /* If the client didn't do EDNS, clamp the rcode to 4 bit */
+ if (rcode > 0xF)
+ rcode = DNS_RCODE_SERVFAIL;
+ }
+
+ /* Don't set the AD bit unless DO is on, too */
+ if (!edns0_do)
+ ad = false;
+
+ DNS_PACKET_HEADER(p)->id = id;
+
+ DNS_PACKET_HEADER(p)->flags = htobe16(DNS_PACKET_MAKE_FLAGS(
+ 1 /* qr */,
+ 0 /* opcode */,
+ 0 /* aa */,
+ 0 /* tc */,
+ 1 /* rd */,
+ 1 /* ra */,
+ ad /* ad */,
+ 0 /* cd */,
+ rcode));
if (add_opt) {
r = dns_packet_append_opt(p, ADVERTISE_DATAGRAM_SIZE_MAX, edns0_do, rcode, NULL);
@@ -100,9 +126,6 @@ static int dns_stub_make_reply_packet(
return r;
}
- *ret = p;
- p = NULL;
-
return 0;
}
@@ -148,14 +171,18 @@ static int dns_stub_send(Manager *m, DnsStream *s, DnsPacket *p, DnsPacket *repl
return 0;
}
-static int dns_stub_send_failure(Manager *m, DnsStream *s, DnsPacket *p, int rcode) {
+static int dns_stub_send_failure(Manager *m, DnsStream *s, DnsPacket *p, int rcode, bool authenticated) {
_cleanup_(dns_packet_unrefp) DnsPacket *reply = NULL;
int r;
assert(m);
assert(p);
- r = dns_stub_make_reply_packet(DNS_PACKET_ID(p), rcode, p->question, NULL, !!p->opt, DNS_PACKET_DO(p), false, &reply);
+ r = dns_stub_make_reply_packet(&reply, p->question, NULL);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to make failure packet: %m");
+
+ r = dns_stub_finish_reply_packet(reply, DNS_PACKET_ID(p), rcode, !!p->opt, DNS_PACKET_DO(p), authenticated);
if (r < 0)
return log_debug_errno(r, "Failed to build failure packet: %m");
@@ -170,33 +197,47 @@ static void dns_stub_query_complete(DnsQuery *q) {
switch (q->state) {
- case DNS_TRANSACTION_SUCCESS: {
- _cleanup_(dns_packet_unrefp) DnsPacket *reply = NULL;
+ case DNS_TRANSACTION_SUCCESS:
+
+ r = dns_stub_make_reply_packet(&q->reply_dns_packet, q->question_idna, q->answer);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to build reply packet: %m");
+ break;
+ }
- r = dns_stub_make_reply_packet(
+ r = dns_query_process_cname(q);
+ if (r == -ELOOP) {
+ (void) dns_stub_send_failure(q->manager, q->request_dns_stream, q->request_dns_packet, DNS_RCODE_SERVFAIL, false);
+ break;
+ }
+ if (r < 0) {
+ log_debug_errno(r, "Failed to process CNAME: %m");
+ break;
+ }
+ if (r == DNS_QUERY_RESTARTED)
+ return;
+
+ r = dns_stub_finish_reply_packet(
+ q->reply_dns_packet,
DNS_PACKET_ID(q->request_dns_packet),
q->answer_rcode,
- q->question_idna,
- q->answer,
!!q->request_dns_packet->opt,
DNS_PACKET_DO(q->request_dns_packet),
- DNS_PACKET_DO(q->request_dns_packet) && q->answer_authenticated,
- &reply);
+ dns_query_fully_authenticated(q));
if (r < 0) {
- log_debug_errno(r, "Failed to build reply packet: %m");
+ log_debug_errno(r, "Failed to finish reply packet: %m");
break;
}
- (void) dns_stub_send(q->manager, q->request_dns_stream, q->request_dns_packet, reply);
+ (void) dns_stub_send(q->manager, q->request_dns_stream, q->request_dns_packet, q->reply_dns_packet);
break;
- }
case DNS_TRANSACTION_RCODE_FAILURE:
- (void) dns_stub_send_failure(q->manager, q->request_dns_stream, q->request_dns_packet, q->answer_rcode);
+ (void) dns_stub_send_failure(q->manager, q->request_dns_stream, q->request_dns_packet, q->answer_rcode, dns_query_fully_authenticated(q));
break;
case DNS_TRANSACTION_NOT_FOUND:
- (void) dns_stub_send_failure(q->manager, q->request_dns_stream, q->request_dns_packet, DNS_RCODE_NXDOMAIN);
+ (void) dns_stub_send_failure(q->manager, q->request_dns_stream, q->request_dns_packet, DNS_RCODE_NXDOMAIN, dns_query_fully_authenticated(q));
break;
case DNS_TRANSACTION_TIMEOUT:
@@ -212,7 +253,7 @@ static void dns_stub_query_complete(DnsQuery *q) {
case DNS_TRANSACTION_NO_TRUST_ANCHOR:
case DNS_TRANSACTION_RR_TYPE_UNSUPPORTED:
case DNS_TRANSACTION_NETWORK_DOWN:
- (void) dns_stub_send_failure(q->manager, q->request_dns_stream, q->request_dns_packet, DNS_RCODE_SERVFAIL);
+ (void) dns_stub_send_failure(q->manager, q->request_dns_stream, q->request_dns_packet, DNS_RCODE_SERVFAIL, false);
break;
case DNS_TRANSACTION_NULL:
@@ -259,52 +300,52 @@ static void dns_stub_process_query(Manager *m, DnsStream *s, DnsPacket *p) {
if (in_addr_is_localhost(p->family, &p->sender) <= 0 ||
in_addr_is_localhost(p->family, &p->destination) <= 0) {
log_error("Got packet on unexpected IP range, refusing.");
- dns_stub_send_failure(m, s, p, DNS_RCODE_SERVFAIL);
+ dns_stub_send_failure(m, s, p, DNS_RCODE_SERVFAIL, false);
goto fail;
}
r = dns_packet_extract(p);
if (r < 0) {
log_debug_errno(r, "Failed to extract resources from incoming packet, ignoring packet: %m");
- dns_stub_send_failure(m, s, p, DNS_RCODE_FORMERR);
+ dns_stub_send_failure(m, s, p, DNS_RCODE_FORMERR, false);
goto fail;
}
if (!DNS_PACKET_VERSION_SUPPORTED(p)) {
log_debug("Got EDNS OPT field with unsupported version number.");
- dns_stub_send_failure(m, s, p, DNS_RCODE_BADVERS);
+ dns_stub_send_failure(m, s, p, DNS_RCODE_BADVERS, false);
goto fail;
}
if (dns_type_is_obsolete(p->question->keys[0]->type)) {
log_debug("Got message with obsolete key type, refusing.");
- dns_stub_send_failure(m, s, p, DNS_RCODE_NOTIMP);
+ dns_stub_send_failure(m, s, p, DNS_RCODE_NOTIMP, false);
goto fail;
}
if (dns_type_is_zone_transer(p->question->keys[0]->type)) {
log_debug("Got request for zone transfer, refusing.");
- dns_stub_send_failure(m, s, p, DNS_RCODE_NOTIMP);
+ dns_stub_send_failure(m, s, p, DNS_RCODE_NOTIMP, false);
goto fail;
}
if (!DNS_PACKET_RD(p)) {
/* If the "rd" bit is off (i.e. recursion was not requested), then refuse operation */
log_debug("Got request with recursion disabled, refusing.");
- dns_stub_send_failure(m, s, p, DNS_RCODE_REFUSED);
+ dns_stub_send_failure(m, s, p, DNS_RCODE_REFUSED, false);
goto fail;
}
if (DNS_PACKET_DO(p) && DNS_PACKET_CD(p)) {
log_debug("Got request with DNSSEC CD bit set, refusing.");
- dns_stub_send_failure(m, s, p, DNS_RCODE_NOTIMP);
+ dns_stub_send_failure(m, s, p, DNS_RCODE_NOTIMP, false);
goto fail;
}
- r = dns_query_new(m, &q, p->question, p->question, 0, SD_RESOLVED_PROTOCOLS_ALL|SD_RESOLVED_NO_SEARCH|SD_RESOLVED_NO_CNAME);
+ r = dns_query_new(m, &q, p->question, p->question, 0, SD_RESOLVED_PROTOCOLS_ALL|SD_RESOLVED_NO_SEARCH);
if (r < 0) {
log_error_errno(r, "Failed to generate query object: %m");
- dns_stub_send_failure(m, s, p, DNS_RCODE_SERVFAIL);
+ dns_stub_send_failure(m, s, p, DNS_RCODE_SERVFAIL, false);
goto fail;
}
@@ -324,11 +365,11 @@ static void dns_stub_process_query(Manager *m, DnsStream *s, DnsPacket *p) {
r = dns_query_go(q);
if (r < 0) {
log_error_errno(r, "Failed to start query: %m");
- dns_stub_send_failure(m, s, p, DNS_RCODE_SERVFAIL);
+ dns_stub_send_failure(m, s, p, DNS_RCODE_SERVFAIL, false);
goto fail;
}
- log_info("Processing query...");
+ log_debug("Processing query...");
return;
fail:
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
index 2fce44ec8b..ff2ad9c1de 100644
--- a/src/resolve/resolved-dns-transaction.c
+++ b/src/resolve/resolved-dns-transaction.c
@@ -31,6 +31,7 @@
#include "string-table.h"
#define TRANSACTIONS_MAX 4096
+#define TRANSACTION_TCP_TIMEOUT_USEC (10U*USEC_PER_SEC)
static void dns_transaction_reset_answer(DnsTransaction *t) {
assert(t);
@@ -318,7 +319,7 @@ void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
dns_resource_key_to_string(t->key, key_str, sizeof key_str);
log_struct(LOG_NOTICE,
- LOG_MESSAGE_ID(SD_MESSAGE_DNSSEC_FAILURE),
+ "MESSAGE_ID=" SD_MESSAGE_DNSSEC_FAILURE_STR,
LOG_MESSAGE("DNSSEC validation failed for question %s: %s", key_str, dnssec_result_to_string(t->answer_dnssec_result)),
"DNS_TRANSACTION=%" PRIu16, t->id,
"DNS_QUESTION=%s", key_str,
@@ -363,6 +364,8 @@ void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
SET_FOREACH_MOVE(z, t->notify_zone_items_done, t->notify_zone_items)
dns_zone_item_notify(z);
SWAP_TWO(t->notify_zone_items, t->notify_zone_items_done);
+ if (t->probing)
+ (void) dns_scope_announce(t->scope, false);
SET_FOREACH_MOVE(d, t->notify_transactions_done, t->notify_transactions)
dns_transaction_notify(d, t);
@@ -830,7 +833,7 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
* should hence not attempt to access the query or transaction
* after calling this function. */
- log_debug("Processing incoming packet on transaction %" PRIu16".", t->id);
+ log_debug("Processing incoming packet on transaction %" PRIu16". (rcode=%s)", t->id, dns_rcode_to_string(DNS_PACKET_RCODE(p)));
switch (t->scope->protocol) {
@@ -908,9 +911,13 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
/* Request failed, immediately try again with reduced features */
- if (t->current_feature_level <= DNS_SERVER_FEATURE_LEVEL_WORST) {
- /* This was already at the lowest possible feature level? If so, we can't downgrade
- * this transaction anymore, hence let's process the response, and accept the rcode. */
+ if (t->current_feature_level <= DNS_SERVER_FEATURE_LEVEL_UDP) {
+ /* This was already at UDP feature level? If so, it doesn't make sense to downgrade
+ * this transaction anymore, hence let's process the response, and accept the
+ * rcode. Note that we don't retry on TCP, since that's a suitable way to mitigate
+ * packet loss, but is not going to give us better rcodes should we actually have
+ * managed to get them already at UDP level. */
+
log_debug("Server returned error: %s", dns_rcode_to_string(DNS_PACKET_RCODE(p)));
break;
}
@@ -924,7 +931,16 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
dns_transaction_retry(t, false /* use the same server */);
return;
- } else if (DNS_PACKET_TC(p))
+ }
+
+ if (DNS_PACKET_RCODE(p) == DNS_RCODE_REFUSED) {
+ /* This server refused our request? If so, try again, use a different server */
+ log_debug("Server returned REFUSED, switching servers, and retrying.");
+ dns_transaction_retry(t, true /* pick a new server */);
+ return;
+ }
+
+ if (DNS_PACKET_TC(p))
dns_server_packet_truncated(t->server, t->current_feature_level);
break;
@@ -1003,15 +1019,20 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
if (r > 0) /* Transaction got restarted... */
return;
- if (IN_SET(t->scope->protocol, DNS_PROTOCOL_DNS, DNS_PROTOCOL_LLMNR)) {
+ if (IN_SET(t->scope->protocol, DNS_PROTOCOL_DNS, DNS_PROTOCOL_LLMNR, DNS_PROTOCOL_MDNS)) {
- /* Only consider responses with equivalent query section to the request */
- r = dns_packet_is_reply_for(p, t->key);
- if (r < 0)
- goto fail;
- if (r == 0) {
- dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
- return;
+ /* When dealing with protocols other than mDNS only consider responses with
+ * equivalent query section to the request. For mDNS this check doesn't make
+ * sense, because the section 6 of RFC6762 states that "Multicast DNS responses MUST NOT
+ * contain any questions in the Question Section". */
+ if (t->scope->protocol != DNS_PROTOCOL_MDNS) {
+ r = dns_packet_is_reply_for(p, t->key);
+ if (r < 0)
+ goto fail;
+ if (r == 0) {
+ dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
+ return;
+ }
}
/* Install the answer as answer to the transaction */
@@ -1119,7 +1140,7 @@ static int dns_transaction_emit_udp(DnsTransaction *t) {
return r;
if (t->current_feature_level < DNS_SERVER_FEATURE_LEVEL_UDP)
- return -EAGAIN;
+ return -EAGAIN; /* Sorry, can't do UDP, try TCP! */
if (!dns_server_dnssec_supported(t->server) && dns_type_is_dnssec(t->key->type))
return -EOPNOTSUPP;
@@ -1196,15 +1217,26 @@ static usec_t transaction_get_resend_timeout(DnsTransaction *t) {
assert(t);
assert(t->scope);
+
switch (t->scope->protocol) {
case DNS_PROTOCOL_DNS:
+
+ /* When we do TCP, grant a much longer timeout, as in this case there's no need for us to quickly
+ * resend, as the kernel does that anyway for us, and we really don't want to interrupt it in that
+ * needlessly. */
+ if (t->stream)
+ return TRANSACTION_TCP_TIMEOUT_USEC;
+
assert(t->server);
return t->server->resend_timeout;
case DNS_PROTOCOL_MDNS:
assert(t->n_attempts > 0);
- return (1 << (t->n_attempts - 1)) * USEC_PER_SEC;
+ if (t->probing)
+ return MDNS_PROBING_INTERVAL_USEC;
+ else
+ return (1 << (t->n_attempts - 1)) * USEC_PER_SEC;
case DNS_PROTOCOL_LLMNR:
return t->scope->resend_timeout;
@@ -1358,7 +1390,7 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
if (r < 0)
return r;
- r = dns_packet_append_key(p, t->key, NULL);
+ r = dns_packet_append_key(p, t->key, 0, NULL);
if (r < 0)
return r;
@@ -1390,7 +1422,7 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
if (qdcount >= UINT16_MAX)
break;
- r = dns_packet_append_key(p, other->key, NULL);
+ r = dns_packet_append_key(p, other->key, 0, NULL);
/*
* If we can't stuff more questions into the packet, just give up.
@@ -1417,7 +1449,7 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
if (r < 0)
return r;
- (void) sd_event_source_set_description(t->timeout_event_source, "dns-transaction-timeout");
+ (void) sd_event_source_set_description(other->timeout_event_source, "dns-transaction-timeout");
other->state = DNS_TRANSACTION_PENDING;
other->next_attempt_after = ts;
@@ -1459,7 +1491,7 @@ static int dns_transaction_make_packet(DnsTransaction *t) {
if (r < 0)
return r;
- r = dns_packet_append_key(p, t->key, NULL);
+ r = dns_packet_append_key(p, t->key, 0, NULL);
if (r < 0)
return r;
@@ -1560,7 +1592,7 @@ int dns_transaction_go(DnsTransaction *t) {
r = dns_transaction_emit_udp(t);
if (r == -EMSGSIZE)
log_debug("Sending query via TCP since it is too large.");
- if (r == -EAGAIN)
+ else if (r == -EAGAIN)
log_debug("Sending query via TCP since server doesn't support UDP.");
if (r == -EMSGSIZE || r == -EAGAIN)
r = dns_transaction_open_tcp(t);
@@ -1977,8 +2009,18 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
r = dns_resource_key_match_rr(t->key, rr, NULL);
if (r < 0)
return r;
- if (r == 0)
- continue;
+ if (r == 0) {
+ /* Hmm, so this SOA RR doesn't match our original question. In this case, maybe this is
+ * a negative reply, and we need the a SOA RR's TTL in order to cache a negative entry?
+ * If so, we need to validate it, too. */
+
+ r = dns_answer_match_key(t->answer, t->key, NULL);
+ if (r < 0)
+ return r;
+ if (r > 0) /* positive reply, we won't need the SOA and hence don't need to validate
+ * it. */
+ continue;
+ }
r = dnssec_has_rrsig(t->answer, rr->key);
if (r < 0)
@@ -2416,7 +2458,7 @@ static int dns_transaction_requires_nsec(DnsTransaction *t) {
if (r > 0) {
/* The lookup is from a TLD that is proven not to
* exist, and we are in downgrade mode, hence ignore
- * that fact that we didn't get any NSEC RRs.*/
+ * that fact that we didn't get any NSEC RRs. */
log_info("Detected a negative query %s in a private DNS zone, permitting unsigned response.",
dns_resource_key_to_string(t->key, key_str, sizeof key_str));
@@ -2721,7 +2763,7 @@ static int dnssec_validate_records(
const char *source;
/* This RRset validated, but as a wildcard. This means we need
- * to prove via NSEC/NSEC3 that no matching non-wildcard RR exists.*/
+ * to prove via NSEC/NSEC3 that no matching non-wildcard RR exists. */
/* First step, determine the source of synthesis */
r = dns_resource_record_source(rrsig, &source);
@@ -2756,7 +2798,7 @@ static int dnssec_validate_records(
return r;
if (r == 0) {
/* Data does not require signing. In that case, just copy it over,
- * but remember that this is by no means authenticated.*/
+ * but remember that this is by no means authenticated. */
r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0);
if (r < 0)
return r;
diff --git a/src/resolve/resolved-dns-transaction.h b/src/resolve/resolved-dns-transaction.h
index 5a1df70422..a8d97738ef 100644
--- a/src/resolve/resolved-dns-transaction.h
+++ b/src/resolve/resolved-dns-transaction.h
@@ -78,6 +78,8 @@ struct DnsTransaction {
bool clamp_ttl:1;
+ bool probing:1;
+
DnsPacket *sent, *received;
DnsAnswer *answer;
@@ -172,10 +174,20 @@ DnsTransactionSource dns_transaction_source_from_string(const char *s) _pure_;
#define MDNS_JITTER_MIN_USEC (20 * USEC_PER_MSEC)
#define MDNS_JITTER_RANGE_USEC (100 * USEC_PER_MSEC)
+/* mDNS probing interval, see RFC 6762 Section 8.1 */
+#define MDNS_PROBING_INTERVAL_USEC (250 * USEC_PER_MSEC)
+
/* Maximum attempts to send DNS requests, across all DNS servers */
-#define DNS_TRANSACTION_ATTEMPTS_MAX 16
+#define DNS_TRANSACTION_ATTEMPTS_MAX 24
/* Maximum attempts to send LLMNR requests, see RFC 4795 Section 2.7 */
#define LLMNR_TRANSACTION_ATTEMPTS_MAX 3
-#define TRANSACTION_ATTEMPTS_MAX(p) ((p) == DNS_PROTOCOL_LLMNR ? LLMNR_TRANSACTION_ATTEMPTS_MAX : DNS_TRANSACTION_ATTEMPTS_MAX)
+/* Maximum attempts to send MDNS requests, see RFC 6762 Section 8.1 */
+#define MDNS_TRANSACTION_ATTEMPTS_MAX 3
+
+#define TRANSACTION_ATTEMPTS_MAX(p) (((p) == DNS_PROTOCOL_LLMNR) ? \
+ LLMNR_TRANSACTION_ATTEMPTS_MAX : \
+ (((p) == DNS_PROTOCOL_MDNS) ? \
+ MDNS_TRANSACTION_ATTEMPTS_MAX : \
+ DNS_TRANSACTION_ATTEMPTS_MAX))
diff --git a/src/resolve/resolved-dns-trust-anchor.c b/src/resolve/resolved-dns-trust-anchor.c
index 9917b9e984..7e9f9e5a20 100644
--- a/src/resolve/resolved-dns-trust-anchor.c
+++ b/src/resolve/resolved-dns-trust-anchor.c
@@ -35,11 +35,16 @@
static const char trust_anchor_dirs[] = CONF_PATHS_NULSTR("dnssec-trust-anchors.d");
-/* The DS RR from https://data.iana.org/root-anchors/root-anchors.xml, retrieved December 2015 */
-static const uint8_t root_digest[] =
+/* The first DS RR from https://data.iana.org/root-anchors/root-anchors.xml, retrieved December 2015 */
+static const uint8_t root_digest1[] =
{ 0x49, 0xAA, 0xC1, 0x1D, 0x7B, 0x6F, 0x64, 0x46, 0x70, 0x2E, 0x54, 0xA1, 0x60, 0x73, 0x71, 0x60,
0x7A, 0x1A, 0x41, 0x85, 0x52, 0x00, 0xFD, 0x2C, 0xE1, 0xCD, 0xDE, 0x32, 0xF2, 0x4E, 0x8F, 0xB5 };
+/* The second DS RR from https://data.iana.org/root-anchors/root-anchors.xml, retrieved February 2017 */
+static const uint8_t root_digest2[] =
+ { 0xE0, 0x6D, 0x44, 0xB8, 0x0B, 0x8F, 0x1D, 0x39, 0xA9, 0x5C, 0x0B, 0x0D, 0x7C, 0x65, 0xD0, 0x84,
+ 0x58, 0xE8, 0x80, 0x40, 0x9B, 0xBC, 0x68, 0x34, 0x57, 0x10, 0x42, 0x37, 0xC7, 0xF8, 0xEC, 0x8D };
+
static bool dns_trust_anchor_knows_domain_positive(DnsTrustAnchor *d, const char *name) {
assert(d);
@@ -51,9 +56,40 @@ static bool dns_trust_anchor_knows_domain_positive(DnsTrustAnchor *d, const char
hashmap_contains(d->positive_by_key, &DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_DS, name));
}
-static int dns_trust_anchor_add_builtin_positive(DnsTrustAnchor *d) {
+static int add_root_ksk(
+ DnsAnswer *answer,
+ DnsResourceKey *key,
+ uint16_t key_tag,
+ uint8_t algorithm,
+ uint8_t digest_type,
+ const void *digest,
+ size_t digest_size) {
+
_cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
+ int r;
+
+ rr = dns_resource_record_new(key);
+ if (!rr)
+ return -ENOMEM;
+
+ rr->ds.key_tag = key_tag;
+ rr->ds.algorithm = algorithm;
+ rr->ds.digest_type = digest_type;
+ rr->ds.digest_size = digest_size;
+ rr->ds.digest = memdup(digest, rr->ds.digest_size);
+ if (!rr->ds.digest)
+ return -ENOMEM;
+
+ r = dns_answer_add(answer, rr, 0, DNS_ANSWER_AUTHENTICATED);
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+
+static int dns_trust_anchor_add_builtin_positive(DnsTrustAnchor *d) {
_cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
+ _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
int r;
assert(d);
@@ -62,35 +98,29 @@ static int dns_trust_anchor_add_builtin_positive(DnsTrustAnchor *d) {
if (r < 0)
return r;
- /* Only add the built-in trust anchor if there's neither a DS
- * nor a DNSKEY defined for the root domain. That way users
- * have an easy way to override the root domain DS/DNSKEY
- * data. */
+ /* Only add the built-in trust anchor if there's neither a DS nor a DNSKEY defined for the root domain. That
+ * way users have an easy way to override the root domain DS/DNSKEY data. */
if (dns_trust_anchor_knows_domain_positive(d, "."))
return 0;
- /* Add the RR from https://data.iana.org/root-anchors/root-anchors.xml */
- rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DS, "");
- if (!rr)
+ key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_DS, "");
+ if (!key)
return -ENOMEM;
- rr->ds.key_tag = 19036;
- rr->ds.algorithm = DNSSEC_ALGORITHM_RSASHA256;
- rr->ds.digest_type = DNSSEC_DIGEST_SHA256;
- rr->ds.digest_size = sizeof(root_digest);
- rr->ds.digest = memdup(root_digest, rr->ds.digest_size);
- if (!rr->ds.digest)
- return -ENOMEM;
-
- answer = dns_answer_new(1);
+ answer = dns_answer_new(2);
if (!answer)
return -ENOMEM;
- r = dns_answer_add(answer, rr, 0, DNS_ANSWER_AUTHENTICATED);
+ /* Add the two RRs from https://data.iana.org/root-anchors/root-anchors.xml */
+ r = add_root_ksk(answer, key, 19036, DNSSEC_ALGORITHM_RSASHA256, DNSSEC_DIGEST_SHA256, root_digest1, sizeof(root_digest1));
if (r < 0)
return r;
- r = hashmap_put(d->positive_by_key, rr->key, answer);
+ r = add_root_ksk(answer, key, 20326, DNSSEC_ALGORITHM_RSASHA256, DNSSEC_DIGEST_SHA256, root_digest2, sizeof(root_digest2));
+ if (r < 0)
+ return r;
+
+ r = hashmap_put(d->positive_by_key, key, answer);
if (r < 0)
return r;
@@ -547,10 +577,33 @@ int dns_trust_anchor_lookup_positive(DnsTrustAnchor *d, const DnsResourceKey *ke
}
int dns_trust_anchor_lookup_negative(DnsTrustAnchor *d, const char *name) {
+ int r;
+
assert(d);
assert(name);
- return set_contains(d->negative_by_name, name);
+ for (;;) {
+ /* If the domain is listed as-is in the NTA database, then that counts */
+ if (set_contains(d->negative_by_name, name))
+ return true;
+
+ /* If the domain isn't listed as NTA, but is listed as positive trust anchor, then that counts. See RFC
+ * 7646, section 1.1 */
+ if (hashmap_contains(d->positive_by_key, &DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_DS, name)))
+ return false;
+
+ if (hashmap_contains(d->positive_by_key, &DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_KEY, name)))
+ return false;
+
+ /* And now, let's look at the parent, and check that too */
+ r = dns_name_parent(&name);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+ }
+
+ return false;
}
static int dns_trust_anchor_revoked_put(DnsTrustAnchor *d, DnsResourceRecord *rr) {
@@ -594,7 +647,7 @@ static int dns_trust_anchor_remove_revoked(DnsTrustAnchor *d, DnsResourceRecord
/* We found the key! Warn the user */
log_struct(LOG_WARNING,
- LOG_MESSAGE_ID(SD_MESSAGE_DNSSEC_TRUST_ANCHOR_REVOKED),
+ "MESSAGE_ID=" SD_MESSAGE_DNSSEC_TRUST_ANCHOR_REVOKED_STR,
LOG_MESSAGE("DNSSEC Trust anchor %s has been revoked. Please update the trust anchor, or upgrade your operating system."), strna(dns_resource_record_to_string(rr)),
"TRUST_ANCHOR=%s", dns_resource_record_to_string(rr),
NULL);
diff --git a/src/resolve/resolved-dns-zone.c b/src/resolve/resolved-dns-zone.c
index 746a979f47..ad024b54f5 100644
--- a/src/resolve/resolved-dns-zone.c
+++ b/src/resolve/resolved-dns-zone.c
@@ -196,6 +196,7 @@ static int dns_zone_item_probe_start(DnsZoneItem *i) {
goto gc;
i->probe_transaction = t;
+ t->probing = true;
if (t->state == DNS_TRANSACTION_NULL) {
diff --git a/src/resolve/resolved-dns-zone.h b/src/resolve/resolved-dns-zone.h
index a41df37e6b..545ec958fb 100644
--- a/src/resolve/resolved-dns-zone.h
+++ b/src/resolve/resolved-dns-zone.h
@@ -37,6 +37,9 @@ typedef enum DnsZoneItemState DnsZoneItemState;
/* RFC 4795 Section 2.8. suggests a TTL of 30s by default */
#define LLMNR_DEFAULT_TTL (30)
+/* RFC 6762 Section 10. suggests a TTL of 120s by default */
+#define MDNS_DEFAULT_TTL (120)
+
enum DnsZoneItemState {
DNS_ZONE_ITEM_PROBING,
DNS_ZONE_ITEM_ESTABLISHED,
diff --git a/src/resolve/resolved-etc-hosts.c b/src/resolve/resolved-etc-hosts.c
index 40d650949d..0a284825a1 100644
--- a/src/resolve/resolved-etc-hosts.c
+++ b/src/resolve/resolved-etc-hosts.c
@@ -431,8 +431,8 @@ int manager_etc_hosts_lookup(Manager *m, DnsQuestion* q, DnsAnswer **answer) {
for (i = 0; i < bn->n_items; i++) {
_cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
- if ((found_a && bn->items[i]->family != AF_INET) &&
- (found_aaaa && bn->items[i]->family != AF_INET6))
+ if ((!found_a && bn->items[i]->family == AF_INET) ||
+ (!found_aaaa && bn->items[i]->family == AF_INET6))
continue;
r = dns_resource_record_new_address(&rr, bn->items[i]->family, &bn->items[i]->address, bn->name);
@@ -444,5 +444,5 @@ int manager_etc_hosts_lookup(Manager *m, DnsQuestion* q, DnsAnswer **answer) {
return r;
}
- return 1;
+ return found_a || found_aaaa;
}
diff --git a/src/resolve/resolved-gperf.gperf b/src/resolve/resolved-gperf.gperf
index 446f85cdf4..5153563b99 100644
--- a/src/resolve/resolved-gperf.gperf
+++ b/src/resolve/resolved-gperf.gperf
@@ -18,6 +18,7 @@ Resolve.DNS, config_parse_dns_servers, DNS_SERVER_SYSTEM,
Resolve.FallbackDNS, config_parse_dns_servers, DNS_SERVER_FALLBACK, 0
Resolve.Domains, config_parse_search_domains, 0, 0
Resolve.LLMNR, config_parse_resolve_support, 0, offsetof(Manager, llmnr_support)
+Resolve.MulticastDNS, config_parse_resolve_support, 0, offsetof(Manager, mdns_support)
Resolve.DNSSEC, config_parse_dnssec_mode, 0, offsetof(Manager, dnssec_mode)
Resolve.Cache, config_parse_bool, 0, offsetof(Manager, enable_cache)
Resolve.DNSStubListener, config_parse_dns_stub_listener_mode, 0, offsetof(Manager, dns_stub_listener_mode)
diff --git a/src/resolve/resolved-link-bus.c b/src/resolve/resolved-link-bus.c
index 364812250f..59cd6cf1cb 100644
--- a/src/resolve/resolved-link-bus.c
+++ b/src/resolve/resolved-link-bus.c
@@ -462,7 +462,7 @@ int bus_link_method_set_dnssec(sd_bus_message *message, void *userdata, sd_bus_e
int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_set_free_free_ Set *ns = NULL;
- _cleanup_free_ char **ntas = NULL;
+ _cleanup_strv_free_ char **ntas = NULL;
Link *l = userdata;
int r;
char **i;
diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c
index 13e1f91192..d06096f3f2 100644
--- a/src/resolve/resolved-link.c
+++ b/src/resolve/resolved-link.c
@@ -28,6 +28,8 @@
#include "mkdir.h"
#include "parse-util.h"
#include "resolved-link.h"
+#include "resolved-llmnr.h"
+#include "resolved-mdns.h"
#include "string-util.h"
#include "strv.h"
@@ -85,6 +87,10 @@ Link *link_free(Link *l) {
if (!l)
return NULL;
+ /* Send goodbye messages. */
+ dns_scope_announce(l->mdns_ipv4_scope, true);
+ dns_scope_announce(l->mdns_ipv6_scope, true);
+
link_flush_settings(l);
while (l->addresses)
@@ -519,10 +525,25 @@ static void link_read_settings(Link *l) {
}
int link_update(Link *l) {
+ int r;
+
assert(l);
link_read_settings(l);
link_load_user(l);
+
+ if (l->llmnr_support != RESOLVE_SUPPORT_NO) {
+ r = manager_llmnr_start(l->manager);
+ if (r < 0)
+ return r;
+ }
+
+ if (l->mdns_support != RESOLVE_SUPPORT_NO) {
+ r = manager_mdns_start(l->manager);
+ if (r < 0)
+ return r;
+ }
+
link_allocate_scopes(l);
link_add_rrs(l, false);
@@ -539,7 +560,7 @@ bool link_relevant(Link *l, int family, bool local_multicast) {
* beat, can do multicast and has at least one link-local (or better) IP address.
*
* A link is relevant for non-multicast traffic if it isn't a loopback device, has a link beat, and has at
- * least one routable address.*/
+ * least one routable address. */
if (l->flags & (IFF_LOOPBACK|IFF_DORMANT))
return false;
@@ -665,6 +686,7 @@ int link_address_new(Link *l, LinkAddress **ret, int family, const union in_addr
a->link = l;
LIST_PREPEND(addresses, l->addresses, a);
+ l->n_addresses++;
if (ret)
*ret = a;
@@ -679,6 +701,9 @@ LinkAddress *link_address_free(LinkAddress *a) {
if (a->link) {
LIST_REMOVE(addresses, a->link->addresses, a);
+ assert(a->link->n_addresses > 0);
+ a->link->n_addresses--;
+
if (a->llmnr_address_rr) {
if (a->family == AF_INET && a->link->llmnr_ipv4_scope)
dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_address_rr);
@@ -692,10 +717,26 @@ LinkAddress *link_address_free(LinkAddress *a) {
else if (a->family == AF_INET6 && a->link->llmnr_ipv6_scope)
dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_ptr_rr);
}
+
+ if (a->mdns_address_rr) {
+ if (a->family == AF_INET && a->link->mdns_ipv4_scope)
+ dns_zone_remove_rr(&a->link->mdns_ipv4_scope->zone, a->mdns_address_rr);
+ else if (a->family == AF_INET6 && a->link->mdns_ipv6_scope)
+ dns_zone_remove_rr(&a->link->mdns_ipv6_scope->zone, a->mdns_address_rr);
+ }
+
+ if (a->mdns_ptr_rr) {
+ if (a->family == AF_INET && a->link->mdns_ipv4_scope)
+ dns_zone_remove_rr(&a->link->mdns_ipv4_scope->zone, a->mdns_ptr_rr);
+ else if (a->family == AF_INET6 && a->link->mdns_ipv6_scope)
+ dns_zone_remove_rr(&a->link->mdns_ipv6_scope->zone, a->mdns_ptr_rr);
+ }
}
dns_resource_record_unref(a->llmnr_address_rr);
dns_resource_record_unref(a->llmnr_ptr_rr);
+ dns_resource_record_unref(a->mdns_address_rr);
+ dns_resource_record_unref(a->mdns_ptr_rr);
return mfree(a);
}
@@ -746,7 +787,7 @@ void link_address_add_rrs(LinkAddress *a, bool force_remove) {
r = dns_zone_put(&a->link->llmnr_ipv4_scope->zone, a->link->llmnr_ipv4_scope, a->llmnr_ptr_rr, false);
if (r < 0)
- log_warning_errno(r, "Failed to add IPv6 PTR record to LLMNR zone: %m");
+ log_warning_errno(r, "Failed to add IPv4 PTR record to LLMNR zone: %m");
} else {
if (a->llmnr_address_rr) {
if (a->link->llmnr_ipv4_scope)
@@ -760,6 +801,59 @@ void link_address_add_rrs(LinkAddress *a, bool force_remove) {
a->llmnr_ptr_rr = dns_resource_record_unref(a->llmnr_ptr_rr);
}
}
+
+ if (!force_remove &&
+ link_address_relevant(a, true) &&
+ a->link->mdns_ipv4_scope &&
+ a->link->mdns_support == RESOLVE_SUPPORT_YES &&
+ a->link->manager->mdns_support == RESOLVE_SUPPORT_YES) {
+ if (!a->link->manager->mdns_host_ipv4_key) {
+ a->link->manager->mdns_host_ipv4_key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, a->link->manager->mdns_hostname);
+ if (!a->link->manager->mdns_host_ipv4_key) {
+ r = -ENOMEM;
+ goto fail;
+ }
+ }
+
+ if (!a->mdns_address_rr) {
+ a->mdns_address_rr = dns_resource_record_new(a->link->manager->mdns_host_ipv4_key);
+ if (!a->mdns_address_rr) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
+ a->mdns_address_rr->a.in_addr = a->in_addr.in;
+ a->mdns_address_rr->ttl = MDNS_DEFAULT_TTL;
+ }
+
+ if (!a->mdns_ptr_rr) {
+ r = dns_resource_record_new_reverse(&a->mdns_ptr_rr, a->family, &a->in_addr, a->link->manager->mdns_hostname);
+ if (r < 0)
+ goto fail;
+
+ a->mdns_ptr_rr->ttl = MDNS_DEFAULT_TTL;
+ }
+
+ r = dns_zone_put(&a->link->mdns_ipv4_scope->zone, a->link->mdns_ipv4_scope, a->mdns_address_rr, true);
+ if (r < 0)
+ log_warning_errno(r, "Failed to add A record to MDNS zone: %m");
+
+ r = dns_zone_put(&a->link->mdns_ipv4_scope->zone, a->link->mdns_ipv4_scope, a->mdns_ptr_rr, false);
+ if (r < 0)
+ log_warning_errno(r, "Failed to add IPv4 PTR record to MDNS zone: %m");
+ } else {
+ if (a->mdns_address_rr) {
+ if (a->link->mdns_ipv4_scope)
+ dns_zone_remove_rr(&a->link->mdns_ipv4_scope->zone, a->mdns_address_rr);
+ a->mdns_address_rr = dns_resource_record_unref(a->mdns_address_rr);
+ }
+
+ if (a->mdns_ptr_rr) {
+ if (a->link->mdns_ipv4_scope)
+ dns_zone_remove_rr(&a->link->mdns_ipv4_scope->zone, a->mdns_ptr_rr);
+ a->mdns_ptr_rr = dns_resource_record_unref(a->mdns_ptr_rr);
+ }
+ }
}
if (a->family == AF_INET6) {
@@ -817,6 +911,60 @@ void link_address_add_rrs(LinkAddress *a, bool force_remove) {
a->llmnr_ptr_rr = dns_resource_record_unref(a->llmnr_ptr_rr);
}
}
+
+ if (!force_remove &&
+ link_address_relevant(a, true) &&
+ a->link->mdns_ipv6_scope &&
+ a->link->mdns_support == RESOLVE_SUPPORT_YES &&
+ a->link->manager->mdns_support == RESOLVE_SUPPORT_YES) {
+
+ if (!a->link->manager->mdns_host_ipv6_key) {
+ a->link->manager->mdns_host_ipv6_key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_AAAA, a->link->manager->mdns_hostname);
+ if (!a->link->manager->mdns_host_ipv6_key) {
+ r = -ENOMEM;
+ goto fail;
+ }
+ }
+
+ if (!a->mdns_address_rr) {
+ a->mdns_address_rr = dns_resource_record_new(a->link->manager->mdns_host_ipv6_key);
+ if (!a->mdns_address_rr) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
+ a->mdns_address_rr->aaaa.in6_addr = a->in_addr.in6;
+ a->mdns_address_rr->ttl = MDNS_DEFAULT_TTL;
+ }
+
+ if (!a->mdns_ptr_rr) {
+ r = dns_resource_record_new_reverse(&a->mdns_ptr_rr, a->family, &a->in_addr, a->link->manager->mdns_hostname);
+ if (r < 0)
+ goto fail;
+
+ a->mdns_ptr_rr->ttl = MDNS_DEFAULT_TTL;
+ }
+
+ r = dns_zone_put(&a->link->mdns_ipv6_scope->zone, a->link->mdns_ipv6_scope, a->mdns_address_rr, true);
+ if (r < 0)
+ log_warning_errno(r, "Failed to add AAAA record to MDNS zone: %m");
+
+ r = dns_zone_put(&a->link->mdns_ipv6_scope->zone, a->link->mdns_ipv6_scope, a->mdns_ptr_rr, false);
+ if (r < 0)
+ log_warning_errno(r, "Failed to add IPv6 PTR record to MDNS zone: %m");
+ } else {
+ if (a->mdns_address_rr) {
+ if (a->link->mdns_ipv6_scope)
+ dns_zone_remove_rr(&a->link->mdns_ipv6_scope->zone, a->mdns_address_rr);
+ a->mdns_address_rr = dns_resource_record_unref(a->mdns_address_rr);
+ }
+
+ if (a->mdns_ptr_rr) {
+ if (a->link->mdns_ipv6_scope)
+ dns_zone_remove_rr(&a->link->mdns_ipv6_scope->zone, a->mdns_ptr_rr);
+ a->mdns_ptr_rr = dns_resource_record_unref(a->mdns_ptr_rr);
+ }
+ }
}
return;
@@ -997,6 +1145,7 @@ int link_load_user(Link *l) {
*ntas = NULL;
ResolveSupport s;
+ const char *p;
int r;
assert(l);
@@ -1037,48 +1186,40 @@ int link_load_user(Link *l) {
/* If we can't recognize the DNSSEC setting, then set it to invalid, so that the daemon default is used. */
l->dnssec_mode = dnssec_mode_from_string(dnssec);
- if (servers) {
- const char *p = servers;
+ for (p = servers;;) {
+ _cleanup_free_ char *word = NULL;
- for (;;) {
- _cleanup_free_ char *word = NULL;
-
- r = extract_first_word(&p, &word, NULL, 0);
- if (r < 0)
- goto fail;
- if (r == 0)
- break;
+ r = extract_first_word(&p, &word, NULL, 0);
+ if (r < 0)
+ goto fail;
+ if (r == 0)
+ break;
- r = link_update_dns_server_one(l, word);
- if (r < 0) {
- log_debug_errno(r, "Failed to load DNS server '%s', ignoring: %m", word);
- continue;
- }
+ r = link_update_dns_server_one(l, word);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to load DNS server '%s', ignoring: %m", word);
+ continue;
}
}
- if (domains) {
- const char *p = domains;
-
- for (;;) {
- _cleanup_free_ char *word = NULL;
- const char *n;
- bool is_route;
+ for (p = domains;;) {
+ _cleanup_free_ char *word = NULL;
+ const char *n;
+ bool is_route;
- r = extract_first_word(&p, &word, NULL, 0);
- if (r < 0)
- goto fail;
- if (r == 0)
- break;
+ r = extract_first_word(&p, &word, NULL, 0);
+ if (r < 0)
+ goto fail;
+ if (r == 0)
+ break;
- is_route = word[0] == '~';
- n = is_route ? word + 1 : word;
+ is_route = word[0] == '~';
+ n = is_route ? word + 1 : word;
- r = link_update_search_domain_one(l, n, is_route);
- if (r < 0) {
- log_debug_errno(r, "Failed to load search domain '%s', ignoring: %m", word);
- continue;
- }
+ r = link_update_search_domain_one(l, n, is_route);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to load search domain '%s', ignoring: %m", word);
+ continue;
}
}
diff --git a/src/resolve/resolved-link.h b/src/resolve/resolved-link.h
index c9b2a58c34..55a56b7906 100644
--- a/src/resolve/resolved-link.h
+++ b/src/resolve/resolved-link.h
@@ -47,6 +47,8 @@ struct LinkAddress {
DnsResourceRecord *llmnr_address_rr;
DnsResourceRecord *llmnr_ptr_rr;
+ DnsResourceRecord *mdns_address_rr;
+ DnsResourceRecord *mdns_ptr_rr;
LIST_FIELDS(LinkAddress, addresses);
};
@@ -58,6 +60,7 @@ struct Link {
unsigned flags;
LIST_HEAD(LinkAddress, addresses);
+ unsigned n_addresses;
LIST_HEAD(DnsServer, dns_servers);
DnsServer *current_dns_server;
diff --git a/src/resolve/resolved-llmnr.c b/src/resolve/resolved-llmnr.c
index 3516af58ee..29396e9973 100644
--- a/src/resolve/resolved-llmnr.c
+++ b/src/resolve/resolved-llmnr.c
@@ -77,7 +77,7 @@ int manager_llmnr_start(Manager *m) {
return 0;
eaddrinuse:
- log_warning("There appears to be another LLMNR responder running. Turning off LLMNR support.");
+ log_warning("Another LLMNR responder prohibits binding the socket to the same port. Turning off LLMNR support.");
m->llmnr_support = RESOLVE_SUPPORT_NO;
manager_llmnr_stop(m);
@@ -136,56 +136,75 @@ int manager_llmnr_ipv4_udp_fd(Manager *m) {
m->llmnr_ipv4_udp_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (m->llmnr_ipv4_udp_fd < 0)
- return -errno;
+ return log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to create socket: %m");
/* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to set IP_TTL: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to set IP_MULTICAST_TTL: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &one, sizeof(one));
if (r < 0) {
- r = -errno;
- goto fail;
- }
-
- r = setsockopt(m->llmnr_ipv4_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
- if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to set IP_MULTICAST_LOOP: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to set IP_PKTINFO: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to set IP_RECVTTL: %m");
goto fail;
}
/* Disable Don't-Fragment bit in the IP header */
r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to set IP_MTU_DISCOVER: %m");
goto fail;
}
+ /* first try to bind without SO_REUSEADDR to detect another LLMNR responder */
r = bind(m->llmnr_ipv4_udp_fd, &sa.sa, sizeof(sa.in));
if (r < 0) {
- r = -errno;
- goto fail;
+ if (errno != EADDRINUSE) {
+ r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to bind socket: %m");
+ goto fail;
+ }
+
+ log_warning("LLMNR-IPv4(UDP): There appears to be another LLMNR responder running, or previously systemd-resolved crashed with some outstanding transfers.");
+
+ /* try again with SO_REUSEADDR */
+ r = setsockopt(m->llmnr_ipv4_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
+
+ r = bind(m->llmnr_ipv4_udp_fd, &sa.sa, sizeof(sa.in));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to bind socket: %m");
+ goto fail;
+ }
+ } else {
+ /* enable SO_REUSEADDR for the case that the user really wants multiple LLMNR responders */
+ r = setsockopt(m->llmnr_ipv4_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
}
r = sd_event_add_io(m->event, &m->llmnr_ipv4_udp_event_source, m->llmnr_ipv4_udp_fd, EPOLLIN, on_llmnr_packet, m);
@@ -216,55 +235,74 @@ int manager_llmnr_ipv6_udp_fd(Manager *m) {
m->llmnr_ipv6_udp_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (m->llmnr_ipv6_udp_fd < 0)
- return -errno;
+ return log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to create socket: %m");
r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to set IPV6_UNICAST_HOPS: %m");
goto fail;
}
/* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to set IPV6_MULTICAST_HOPS: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to set IPV6_MULTICAST_LOOP: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
if (r < 0) {
- r = -errno;
- goto fail;
- }
-
- r = setsockopt(m->llmnr_ipv6_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
- if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to set IPV6_V6ONLY: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to set IPV6_RECVPKTINFO: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to set IPV6_RECVHOPLIMIT: %m");
goto fail;
}
+ /* first try to bind without SO_REUSEADDR to detect another LLMNR responder */
r = bind(m->llmnr_ipv6_udp_fd, &sa.sa, sizeof(sa.in6));
if (r < 0) {
- r = -errno;
- goto fail;
+ if (errno != EADDRINUSE) {
+ r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to bind socket: %m");
+ goto fail;
+ }
+
+ log_warning("LLMNR-IPv6(UDP): There appears to be another LLMNR responder running, or previously systemd-resolved crashed with some outstanding transfers.");
+
+ /* try again with SO_REUSEADDR */
+ r = setsockopt(m->llmnr_ipv6_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
+
+ r = bind(m->llmnr_ipv6_udp_fd, &sa.sa, sizeof(sa.in6));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to bind socket: %m");
+ goto fail;
+ }
+ } else {
+ /* enable SO_REUSEADDR for the case that the user really wants multiple LLMNR responders */
+ r = setsockopt(m->llmnr_ipv6_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
}
r = sd_event_add_io(m->event, &m->llmnr_ipv6_udp_event_source, m->llmnr_ipv6_udp_fd, EPOLLIN, on_llmnr_packet, m);
@@ -338,49 +376,68 @@ int manager_llmnr_ipv4_tcp_fd(Manager *m) {
m->llmnr_ipv4_tcp_fd = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (m->llmnr_ipv4_tcp_fd < 0)
- return -errno;
+ return log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to create socket: %m");
/* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_TTL, &one, sizeof(one));
if (r < 0) {
- r = -errno;
- goto fail;
- }
-
- r = setsockopt(m->llmnr_ipv4_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
- if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to set IP_TTL: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to set IP_PKTINFO: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to set IP_RECVTTL: %m");
goto fail;
}
/* Disable Don't-Fragment bit in the IP header */
r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to set IP_MTU_DISCOVER: %m");
goto fail;
}
+ /* first try to bind without SO_REUSEADDR to detect another LLMNR responder */
r = bind(m->llmnr_ipv4_tcp_fd, &sa.sa, sizeof(sa.in));
if (r < 0) {
- r = -errno;
- goto fail;
+ if (errno != EADDRINUSE) {
+ r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to bind socket: %m");
+ goto fail;
+ }
+
+ log_warning("LLMNR-IPv4(TCP): There appears to be another LLMNR responder running, or previously systemd-resolved crashed with some outstanding transfers.");
+
+ /* try again with SO_REUSEADDR */
+ r = setsockopt(m->llmnr_ipv4_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
+
+ r = bind(m->llmnr_ipv4_tcp_fd, &sa.sa, sizeof(sa.in));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to bind socket: %m");
+ goto fail;
+ }
+ } else {
+ /* enable SO_REUSEADDR for the case that the user really wants multiple LLMNR responders */
+ r = setsockopt(m->llmnr_ipv4_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
}
r = listen(m->llmnr_ipv4_tcp_fd, SOMAXCONN);
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to listen the stream: %m");
goto fail;
}
@@ -412,48 +469,67 @@ int manager_llmnr_ipv6_tcp_fd(Manager *m) {
m->llmnr_ipv6_tcp_fd = socket(AF_INET6, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (m->llmnr_ipv6_tcp_fd < 0)
- return -errno;
+ return log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to create socket: %m");
/* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to set IPV6_UNICAST_HOPS: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
if (r < 0) {
- r = -errno;
- goto fail;
- }
-
- r = setsockopt(m->llmnr_ipv6_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
- if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to set IPV6_V6ONLY: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to set IPV6_RECVPKTINFO: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to set IPV6_RECVHOPLIMIT: %m");
goto fail;
}
+ /* first try to bind without SO_REUSEADDR to detect another LLMNR responder */
r = bind(m->llmnr_ipv6_tcp_fd, &sa.sa, sizeof(sa.in6));
if (r < 0) {
- r = -errno;
- goto fail;
+ if (errno != EADDRINUSE) {
+ r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to bind socket: %m");
+ goto fail;
+ }
+
+ log_warning("LLMNR-IPv6(TCP): There appears to be another LLMNR responder running, or previously systemd-resolved crashed with some outstanding transfers.");
+
+ /* try again with SO_REUSEADDR */
+ r = setsockopt(m->llmnr_ipv6_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
+
+ r = bind(m->llmnr_ipv6_tcp_fd, &sa.sa, sizeof(sa.in6));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to bind socket: %m");
+ goto fail;
+ }
+ } else {
+ /* enable SO_REUSEADDR for the case that the user really wants multiple LLMNR responders */
+ r = setsockopt(m->llmnr_ipv6_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
}
r = listen(m->llmnr_ipv6_tcp_fd, SOMAXCONN);
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to listen the stream: %m");
goto fail;
}
diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c
index 6630585d13..bcfe3d3811 100644
--- a/src/resolve/resolved-manager.c
+++ b/src/resolve/resolved-manager.c
@@ -322,28 +322,28 @@ static int manager_network_monitor_listen(Manager *m) {
return 0;
}
-static int determine_hostname(char **llmnr_hostname, char **mdns_hostname) {
+static int determine_hostname(char **full_hostname, char **llmnr_hostname, char **mdns_hostname) {
_cleanup_free_ char *h = NULL, *n = NULL;
char label[DNS_LABEL_MAX];
const char *p;
int r, k;
+ assert(full_hostname);
assert(llmnr_hostname);
assert(mdns_hostname);
- /* Extract and normalize the first label of the locally
- * configured hostname, and check it's not "localhost". */
+ /* Extract and normalize the first label of the locally configured hostname, and check it's not "localhost". */
- h = gethostname_malloc();
- if (!h)
- return log_oom();
+ r = gethostname_strict(&h);
+ if (r < 0)
+ return log_debug_errno(r, "Can't determine system hostname: %m");
p = h;
r = dns_label_unescape(&p, label, sizeof(label));
if (r < 0)
return log_error_errno(r, "Failed to unescape host name: %m");
if (r == 0) {
- log_error("Couldn't find a single label in hosntame.");
+ log_error("Couldn't find a single label in hostname.");
return -EINVAL;
}
@@ -374,32 +374,84 @@ static int determine_hostname(char **llmnr_hostname, char **mdns_hostname) {
*llmnr_hostname = n;
n = NULL;
+ *full_hostname = h;
+ h = NULL;
+
+ return 0;
+}
+
+static const char *fallback_hostname(void) {
+
+ /* Determine the fall back hostname. For exposing this system to the outside world, we cannot have it to be
+ * "localhost" even if that's the compiled in hostname. In this case, let's revert to "gnu-linux" instead. */
+
+ if (is_localhost(FALLBACK_HOSTNAME))
+ return "gnu-linux";
+
+ return FALLBACK_HOSTNAME;
+}
+
+static int make_fallback_hostnames(char **full_hostname, char **llmnr_hostname, char **mdns_hostname) {
+ _cleanup_free_ char *n = NULL, *m = NULL;
+ char label[DNS_LABEL_MAX], *h;
+ const char *p;
+ int r;
+
+ assert(full_hostname);
+ assert(llmnr_hostname);
+ assert(mdns_hostname);
+
+ p = fallback_hostname();
+ r = dns_label_unescape(&p, label, sizeof(label));
+ if (r < 0)
+ return log_error_errno(r, "Failed to unescape fallback host name: %m");
+
+ assert(r > 0); /* The fallback hostname must have at least one label */
+
+ r = dns_label_escape_new(label, r, &n);
+ if (r < 0)
+ return log_error_errno(r, "Failed to escape fallback hostname: %m");
+
+ r = dns_name_concat(n, "local", &m);
+ if (r < 0)
+ return log_error_errno(r, "Failed to concatenate mDNS hostname: %m");
+
+ h = strdup(fallback_hostname());
+ if (!h)
+ return log_oom();
+
+ *llmnr_hostname = n;
+ n = NULL;
+
+ *mdns_hostname = m;
+ m = NULL;
+
+ *full_hostname = h;
+
return 0;
}
static int on_hostname_change(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
- _cleanup_free_ char *llmnr_hostname = NULL, *mdns_hostname = NULL;
+ _cleanup_free_ char *full_hostname = NULL, *llmnr_hostname = NULL, *mdns_hostname = NULL;
Manager *m = userdata;
int r;
assert(m);
- r = determine_hostname(&llmnr_hostname, &mdns_hostname);
+ r = determine_hostname(&full_hostname, &llmnr_hostname, &mdns_hostname);
if (r < 0)
return 0; /* ignore invalid hostnames */
- if (streq(llmnr_hostname, m->llmnr_hostname) && streq(mdns_hostname, m->mdns_hostname))
+ if (streq(full_hostname, m->full_hostname) &&
+ streq(llmnr_hostname, m->llmnr_hostname) &&
+ streq(mdns_hostname, m->mdns_hostname))
return 0;
- log_info("System hostname changed to '%s'.", llmnr_hostname);
+ log_info("System hostname changed to '%s'.", full_hostname);
- free(m->llmnr_hostname);
- free(m->mdns_hostname);
-
- m->llmnr_hostname = llmnr_hostname;
- m->mdns_hostname = mdns_hostname;
-
- llmnr_hostname = mdns_hostname = NULL;
+ free_and_replace(m->full_hostname, full_hostname);
+ free_and_replace(m->llmnr_hostname, llmnr_hostname);
+ free_and_replace(m->mdns_hostname, mdns_hostname);
manager_refresh_rrs(m);
@@ -428,18 +480,15 @@ static int manager_watch_hostname(Manager *m) {
(void) sd_event_source_set_description(m->hostname_event_source, "hostname");
- r = determine_hostname(&m->llmnr_hostname, &m->mdns_hostname);
+ r = determine_hostname(&m->full_hostname, &m->llmnr_hostname, &m->mdns_hostname);
if (r < 0) {
- log_info("Defaulting to hostname 'gnu-linux'.");
- m->llmnr_hostname = strdup("gnu-linux");
- if (!m->llmnr_hostname)
- return log_oom();
-
- m->mdns_hostname = strdup("gnu-linux.local");
- if (!m->mdns_hostname)
- return log_oom();
+ log_info("Defaulting to hostname '%s'.", fallback_hostname());
+
+ r = make_fallback_hostnames(&m->full_hostname, &m->llmnr_hostname, &m->mdns_hostname);
+ if (r < 0)
+ return r;
} else
- log_info("Using system hostname '%s'.", m->llmnr_hostname);
+ log_info("Using system hostname '%s'.", m->full_hostname);
return 0;
}
@@ -498,7 +547,7 @@ int manager_new(Manager **ret) {
m->hostname_fd = -1;
m->llmnr_support = RESOLVE_SUPPORT_YES;
- m->mdns_support = RESOLVE_SUPPORT_NO;
+ m->mdns_support = RESOLVE_SUPPORT_YES;
m->dnssec_mode = DEFAULT_DNSSEC_MODE;
m->enable_cache = true;
m->dns_stub_listener_mode = DNS_STUB_LISTENER_UDP;
@@ -563,14 +612,6 @@ int manager_start(Manager *m) {
if (r < 0)
return r;
- r = manager_llmnr_start(m);
- if (r < 0)
- return r;
-
- r = manager_mdns_start(m);
- if (r < 0)
- return r;
-
return 0;
}
@@ -621,9 +662,13 @@ Manager *manager_free(Manager *m) {
dns_resource_key_unref(m->llmnr_host_ipv4_key);
dns_resource_key_unref(m->llmnr_host_ipv6_key);
+ dns_resource_key_unref(m->mdns_host_ipv4_key);
+ dns_resource_key_unref(m->mdns_host_ipv6_key);
sd_event_source_unref(m->hostname_event_source);
safe_close(m->hostname_fd);
+
+ free(m->full_hostname);
free(m->llmnr_hostname);
free(m->mdns_hostname);
@@ -1007,6 +1052,8 @@ void manager_refresh_rrs(Manager *m) {
m->llmnr_host_ipv4_key = dns_resource_key_unref(m->llmnr_host_ipv4_key);
m->llmnr_host_ipv6_key = dns_resource_key_unref(m->llmnr_host_ipv6_key);
+ m->mdns_host_ipv4_key = dns_resource_key_unref(m->mdns_host_ipv4_key);
+ m->mdns_host_ipv6_key = dns_resource_key_unref(m->mdns_host_ipv6_key);
HASHMAP_FOREACH(l, m->links, i) {
link_add_rrs(l, true);
@@ -1146,8 +1193,14 @@ int manager_is_own_hostname(Manager *m, const char *name) {
return r;
}
- if (m->mdns_hostname)
- return dns_name_equal(name, m->mdns_hostname);
+ if (m->mdns_hostname) {
+ r = dns_name_equal(name, m->mdns_hostname);
+ if (r != 0)
+ return r;
+ }
+
+ if (m->full_hostname)
+ return dns_name_equal(name, m->full_hostname);
return 0;
}
@@ -1349,7 +1402,7 @@ void manager_cleanup_saved_user(Manager *m) {
if (!IN_SET(de->d_type, DT_UNKNOWN, DT_REG))
continue;
- if (STR_IN_SET(de->d_name, ".", ".."))
+ if (dot_or_dot_dot(de->d_name))
continue;
r = parse_ifindex(de->d_name, &ifindex);
diff --git a/src/resolve/resolved-manager.h b/src/resolve/resolved-manager.h
index 6b2208ed94..97c52b7729 100644
--- a/src/resolve/resolved-manager.h
+++ b/src/resolve/resolved-manager.h
@@ -109,10 +109,13 @@ struct Manager {
sd_event_source *bus_retry_event_source;
/* The hostname we publish on LLMNR and mDNS */
+ char *full_hostname;
char *llmnr_hostname;
char *mdns_hostname;
DnsResourceKey *llmnr_host_ipv4_key;
DnsResourceKey *llmnr_host_ipv6_key;
+ DnsResourceKey *mdns_host_ipv4_key;
+ DnsResourceKey *mdns_host_ipv6_key;
/* Watch the system hostname */
int hostname_fd;
diff --git a/src/resolve/resolved-mdns.c b/src/resolve/resolved-mdns.c
index b13b1d0144..415dc1a532 100644
--- a/src/resolve/resolved-mdns.c
+++ b/src/resolve/resolved-mdns.c
@@ -60,13 +60,57 @@ int manager_mdns_start(Manager *m) {
return 0;
eaddrinuse:
- log_warning("There appears to be another mDNS responder running. Turning off mDNS support.");
+ log_warning("Another mDNS responder prohibits binding the socket to the same port. Turning off mDNS support.");
m->mdns_support = RESOLVE_SUPPORT_NO;
manager_mdns_stop(m);
return 0;
}
+static int mdns_scope_process_query(DnsScope *s, DnsPacket *p) {
+ _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL, *soa = NULL;
+ _cleanup_(dns_packet_unrefp) DnsPacket *reply = NULL;
+ DnsResourceKey *key = NULL;
+ bool tentative = false;
+ int r;
+
+ assert(s);
+ assert(p);
+
+ r = dns_packet_extract(p);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to extract resource records from incoming packet: %m");
+
+ /* TODO: there might be more than one question in mDNS queries. */
+ assert_return((dns_question_size(p->question) > 0), -EINVAL);
+ key = p->question->keys[0];
+
+ r = dns_zone_lookup(&s->zone, key, 0, &answer, &soa, &tentative);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to lookup key: %m");
+ return r;
+ }
+ if (r == 0)
+ return 0;
+
+ r = dns_scope_make_reply_packet(s, DNS_PACKET_ID(p), DNS_RCODE_SUCCESS, NULL, answer, NULL, false, &reply);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to build reply packet: %m");
+ return r;
+ }
+
+ if (!ratelimit_test(&s->ratelimit))
+ return 0;
+
+ r = dns_scope_emit_udp(s, -1, reply);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to send reply packet: %m");
+ return r;
+ }
+
+ return 0;
+}
+
static int on_mdns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
_cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
Manager *m = userdata;
@@ -77,6 +121,9 @@ static int on_mdns_packet(sd_event_source *s, int fd, uint32_t revents, void *us
if (r <= 0)
return r;
+ if (manager_our_packet(m, p))
+ return 0;
+
scope = manager_find_scope(m, p);
if (!scope) {
log_warning("Got mDNS UDP packet on unknown scope. Ignoring.");
@@ -115,9 +162,28 @@ static int on_mdns_packet(sd_event_source *s, int fd, uint32_t revents, void *us
dns_name_endswith(name, "local") > 0))
return 0;
+ if (rr->ttl == 0) {
+ log_debug("Got a goodbye packet");
+ /* See the section 10.1 of RFC6762 */
+ rr->ttl = 1;
+ }
+
t = dns_scope_find_transaction(scope, rr->key, false);
if (t)
dns_transaction_process_reply(t, p);
+
+ /* Also look for the various types of ANY transactions */
+ t = dns_scope_find_transaction(scope, &DNS_RESOURCE_KEY_CONST(rr->key->class, DNS_TYPE_ANY, dns_resource_key_name(rr->key)), false);
+ if (t)
+ dns_transaction_process_reply(t, p);
+
+ t = dns_scope_find_transaction(scope, &DNS_RESOURCE_KEY_CONST(DNS_CLASS_ANY, rr->key->type, dns_resource_key_name(rr->key)), false);
+ if (t)
+ dns_transaction_process_reply(t, p);
+
+ t = dns_scope_find_transaction(scope, &DNS_RESOURCE_KEY_CONST(DNS_CLASS_ANY, DNS_TYPE_ANY, dns_resource_key_name(rr->key)), false);
+ if (t)
+ dns_transaction_process_reply(t, p);
}
dns_cache_put(&scope->cache, NULL, DNS_PACKET_RCODE(p), p->answer, false, (uint32_t) -1, 0, p->family, &p->sender);
@@ -125,7 +191,11 @@ static int on_mdns_packet(sd_event_source *s, int fd, uint32_t revents, void *us
} else if (dns_packet_validate_query(p) > 0) {
log_debug("Got mDNS query packet for id %u", DNS_PACKET_ID(p));
- dns_scope_process_query(scope, NULL, p);
+ r = mdns_scope_process_query(scope, p);
+ if (r < 0) {
+ log_debug_errno(r, "mDNS query processing failed: %m");
+ return 0;
+ }
} else
log_debug("Invalid mDNS UDP packet.");
@@ -147,55 +217,75 @@ int manager_mdns_ipv4_fd(Manager *m) {
m->mdns_ipv4_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (m->mdns_ipv4_fd < 0)
- return -errno;
+ return log_error_errno(errno, "mDNS-IPv4: Failed to create socket: %m");
r = setsockopt(m->mdns_ipv4_fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv4: Failed to set IP_TTL: %m");
goto fail;
}
r = setsockopt(m->mdns_ipv4_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv4: Failed to set IP_MULTICAST_TTL: %m");
goto fail;
}
r = setsockopt(m->mdns_ipv4_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &one, sizeof(one));
if (r < 0) {
- r = -errno;
- goto fail;
- }
-
- r = setsockopt(m->mdns_ipv4_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
- if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv4: Failed to set IP_MULTICAST_LOOP: %m");
goto fail;
}
r = setsockopt(m->mdns_ipv4_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv4: Failed to set IP_PKTINFO: %m");
goto fail;
}
r = setsockopt(m->mdns_ipv4_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv4: Failed to set IP_RECVTTL: %m");
goto fail;
}
/* Disable Don't-Fragment bit in the IP header */
r = setsockopt(m->mdns_ipv4_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv4: Failed to set IP_MTU_DISCOVER: %m");
goto fail;
}
+ /* See the section 15.1 of RFC6762 */
+ /* first try to bind without SO_REUSEADDR to detect another mDNS responder */
r = bind(m->mdns_ipv4_fd, &sa.sa, sizeof(sa.in));
if (r < 0) {
- r = -errno;
- goto fail;
+ if (errno != EADDRINUSE) {
+ r = log_error_errno(errno, "mDNS-IPv4: Failed to bind socket: %m");
+ goto fail;
+ }
+
+ log_warning("mDNS-IPv4: There appears to be another mDNS responder running, or previously systemd-resolved crashed with some outstanding transfers.");
+
+ /* try again with SO_REUSEADDR */
+ r = setsockopt(m->mdns_ipv4_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "mDNS-IPv4: Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
+
+ r = bind(m->mdns_ipv4_fd, &sa.sa, sizeof(sa.in));
+ if (r < 0) {
+ r = log_error_errno(errno, "mDNS-IPv4: Failed to bind socket: %m");
+ goto fail;
+ }
+ } else {
+ /* enable SO_REUSEADDR for the case that the user really wants multiple mDNS responders */
+ r = setsockopt(m->mdns_ipv4_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "mDNS-IPv4: Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
}
r = sd_event_add_io(m->event, &m->mdns_ipv4_event_source, m->mdns_ipv4_fd, EPOLLIN, on_mdns_packet, m);
@@ -224,55 +314,75 @@ int manager_mdns_ipv6_fd(Manager *m) {
m->mdns_ipv6_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (m->mdns_ipv6_fd < 0)
- return -errno;
+ return log_error_errno(errno, "mDNS-IPv6: Failed to create socket: %m");
r = setsockopt(m->mdns_ipv6_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv6: Failed to set IPV6_UNICAST_HOPS: %m");
goto fail;
}
/* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
r = setsockopt(m->mdns_ipv6_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv6: Failed to set IPV6_MULTICAST_HOPS: %m");
goto fail;
}
r = setsockopt(m->mdns_ipv6_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv6: Failed to set IPV6_MULTICAST_LOOP: %m");
goto fail;
}
r = setsockopt(m->mdns_ipv6_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
if (r < 0) {
- r = -errno;
- goto fail;
- }
-
- r = setsockopt(m->mdns_ipv6_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
- if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv6: Failed to set IPV6_V6ONLY: %m");
goto fail;
}
r = setsockopt(m->mdns_ipv6_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv6: Failed to set IPV6_RECVPKTINFO: %m");
goto fail;
}
r = setsockopt(m->mdns_ipv6_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv6: Failed to set IPV6_RECVHOPLIMIT: %m");
goto fail;
}
+ /* See the section 15.1 of RFC6762 */
+ /* first try to bind without SO_REUSEADDR to detect another mDNS responder */
r = bind(m->mdns_ipv6_fd, &sa.sa, sizeof(sa.in6));
if (r < 0) {
- r = -errno;
- goto fail;
+ if (errno != EADDRINUSE) {
+ r = log_error_errno(errno, "mDNS-IPv6: Failed to bind socket: %m");
+ goto fail;
+ }
+
+ log_warning("mDNS-IPv6: There appears to be another mDNS responder running, or previously systemd-resolved crashed with some outstanding transfers.");
+
+ /* try again with SO_REUSEADDR */
+ r = setsockopt(m->mdns_ipv6_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "mDNS-IPv6: Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
+
+ r = bind(m->mdns_ipv6_fd, &sa.sa, sizeof(sa.in6));
+ if (r < 0) {
+ r = log_error_errno(errno, "mDNS-IPv6: Failed to bind socket: %m");
+ goto fail;
+ }
+ } else {
+ /* enable SO_REUSEADDR for the case that the user really wants multiple mDNS responders */
+ r = setsockopt(m->mdns_ipv6_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "mDNS-IPv6: Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
}
r = sd_event_add_io(m->event, &m->mdns_ipv6_event_source, m->mdns_ipv6_fd, EPOLLIN, on_mdns_packet, m);
diff --git a/src/resolve/resolved-mdns.h b/src/resolve/resolved-mdns.h
index 5d274648f4..06bd3296be 100644
--- a/src/resolve/resolved-mdns.h
+++ b/src/resolve/resolved-mdns.h
@@ -22,6 +22,7 @@
#include "resolved-manager.h"
#define MDNS_PORT 5353
+#define MDNS_ANNOUNCE_DELAY (1 * USEC_PER_SEC)
int manager_mdns_ipv4_fd(Manager *m);
int manager_mdns_ipv6_fd(Manager *m);
diff --git a/src/resolve/resolved-resolv-conf.c b/src/resolve/resolved-resolv-conf.c
index 801014caf5..3c62550872 100644
--- a/src/resolve/resolved-resolv-conf.c
+++ b/src/resolve/resolved-resolv-conf.c
@@ -60,7 +60,7 @@ int manager_read_resolv_conf(Manager *m) {
return 0;
/* Is it symlinked to our own file? */
- if (stat("/run/systemd/resolve/resolv.conf", &own) >= 0 &&
+ if (stat(PRIVATE_RESOLV_CONF, &own) >= 0 &&
st.st_dev == own.st_dev &&
st.st_ino == own.st_ino)
return 0;
@@ -203,13 +203,13 @@ static void write_resolv_conf_search(
static int write_resolv_conf_contents(FILE *f, OrderedSet *dns, OrderedSet *domains) {
Iterator i;
- fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
+ fputs("# This file is managed by man:systemd-resolved(8). Do not edit.\n#\n"
"# This is a dynamic resolv.conf file for connecting local clients directly to\n"
"# all known DNS servers.\n#\n"
"# Third party programs must not access this file directly, but only through the\n"
- "# symlink at /etc/resolv.conf. To manage resolv.conf(5) in a different way,\n"
+ "# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,\n"
"# replace this symlink by a static file or a different symlink.\n#\n"
- "# See systemd-resolved.service(8) for details about the supported modes of\n"
+ "# See man:systemd-resolved.service(8) for details about the supported modes of\n"
"# operation for /etc/resolv.conf.\n\n", f);
if (ordered_set_isempty(dns))
diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c
index deb75f9ae5..74603f9311 100644
--- a/src/resolve/resolved.c
+++ b/src/resolve/resolved.c
@@ -112,6 +112,10 @@ int main(int argc, char *argv[]) {
sd_event_get_exit_code(m->event, &r);
finish:
+ /* systemd-nspawn checks for private resolv.conf to decide whether
+ or not to mount it into the container. So just delete it. */
+ (void) unlink(PRIVATE_RESOLV_CONF);
+
sd_notify(false,
"STOPPING=1\n"
"STATUS=Shutting down...");
diff --git a/src/resolve/resolved.conf.in b/src/resolve/resolved.conf.in
index 60afa151e3..e6b20620e2 100644
--- a/src/resolve/resolved.conf.in
+++ b/src/resolve/resolved.conf.in
@@ -16,6 +16,7 @@
#FallbackDNS=@DNS_SERVERS@
#Domains=
#LLMNR=yes
+#MulticastDNS=yes
#DNSSEC=@DEFAULT_DNSSEC_MODE@
#Cache=yes
#DNSStubListener=udp
diff --git a/src/resolve/test-dns-packet.c b/src/resolve/test-dns-packet.c
index 956b155872..8cbe492526 100644
--- a/src/resolve/test-dns-packet.c
+++ b/src/resolve/test-dns-packet.c
@@ -29,6 +29,7 @@
#include "resolved-dns-rr.h"
#include "string-util.h"
#include "strv.h"
+#include "tests.h"
#include "unaligned.h"
#define HASH_KEY SD_ID128_MAKE(d3,1e,48,90,4b,fa,4c,fe,af,9d,d5,a1,d7,2e,8a,b1)
@@ -115,7 +116,7 @@ int main(int argc, char **argv) {
N = argc - 1;
fnames = argv + 1;
} else {
- assert_se(glob(RESOLVE_TEST_DIR "/*.pkts", GLOB_NOSORT, NULL, &g) == 0);
+ assert_se(glob(get_testdata_dir("/test-resolve/*.pkts"), GLOB_NOSORT, NULL, &g) == 0);
N = g.gl_pathc;
fnames = g.gl_pathv;
}
diff --git a/src/resolve/test-dnssec-complex.c b/src/resolve/test-dnssec-complex.c
index 58c089eb40..3d7074af11 100644
--- a/src/resolve/test-dnssec-complex.c
+++ b/src/resolve/test-dnssec-complex.c
@@ -42,7 +42,7 @@ static void prefix_random(const char *name, char **ret) {
char *x;
assert_se(asprintf(&b, "x%" PRIu64 "x", random_u64()));
- x = strjoin(b, ".", name, NULL);
+ x = strjoin(b, ".", name);
assert_se(x);
free(m);
diff --git a/src/resolve/test-resolved-packet.c b/src/resolve/test-resolved-packet.c
new file mode 100644
index 0000000000..8b7da1408d
--- /dev/null
+++ b/src/resolve/test-resolved-packet.c
@@ -0,0 +1,45 @@
+/***
+ This file is part of systemd
+
+ Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "log.h"
+#include "resolved-dns-packet.h"
+
+static void test_dns_packet_new(void) {
+ size_t i;
+
+ for (i = 0; i < DNS_PACKET_SIZE_MAX + 2; i++) {
+ _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
+
+ assert_se(dns_packet_new(&p, DNS_PROTOCOL_DNS, i) == 0);
+
+ log_debug("dns_packet_new: %zu → %zu", i, p->allocated);
+ assert_se(p->allocated >= MIN(DNS_PACKET_SIZE_MAX, i));
+ }
+}
+
+int main(int argc, char **argv) {
+
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+ log_open();
+
+ test_dns_packet_new();
+
+ return 0;
+}
diff --git a/src/rfkill/rfkill.c b/src/rfkill/rfkill.c
index 0acdf229ed..c0f138b4f4 100644
--- a/src/rfkill/rfkill.c
+++ b/src/rfkill/rfkill.c
@@ -184,9 +184,9 @@ static int determine_state_file(
if (!escaped_path_id)
return log_oom();
- state_file = strjoin("/var/lib/systemd/rfkill/", escaped_path_id, ":", type, NULL);
+ state_file = strjoin("/var/lib/systemd/rfkill/", escaped_path_id, ":", type);
} else
- state_file = strjoin("/var/lib/systemd/rfkill/", type, NULL);
+ state_file = strjoin("/var/lib/systemd/rfkill/", type);
if (!state_file)
return log_oom();
diff --git a/src/run/run.c b/src/run/run.c
index 81b53fdfab..2e6765aa18 100644
--- a/src/run/run.c
+++ b/src/run/run.c
@@ -30,7 +30,7 @@
#include "calendarspec.h"
#include "env-util.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "parse-util.h"
#include "path-util.h"
#include "process-util.h"
@@ -403,6 +403,11 @@ static int parse_argv(int argc, char *argv[]) {
return -EINVAL;
}
+ if (arg_pty && arg_no_block) {
+ log_error("--pty is not compatible with --no-block.");
+ return -EINVAL;
+ }
+
if (arg_scope && with_timer()) {
log_error("Timer options are not supported in --scope mode.");
return -EINVAL;
@@ -492,7 +497,7 @@ static int transient_service_set_properties(sd_bus_message *m, char **argv, cons
if (r < 0)
return r;
- if (arg_wait) {
+ if (arg_wait || arg_pty) {
r = sd_bus_message_append(m, "(sv)", "AddRef", "b", 1);
if (r < 0)
return r;
@@ -747,7 +752,7 @@ static int make_unit_name(sd_bus *bus, UnitType t, char **ret) {
return -EINVAL;
}
- p = strjoin("run-u", id, ".", unit_type_to_string(t), NULL);
+ p = strjoin("run-u", id, ".", unit_type_to_string(t));
if (!p)
return log_oom();
@@ -784,21 +789,23 @@ static void run_context_free(RunContext *c) {
}
static void run_context_check_done(RunContext *c) {
- bool done = true;
+ bool done;
assert(c);
if (c->match)
- done = done && (c->active_state && STR_IN_SET(c->active_state, "inactive", "failed"));
+ done = STRPTR_IN_SET(c->active_state, "inactive", "failed");
+ else
+ done = true;
- if (c->forward)
- done = done && pty_forward_is_done(c->forward);
+ if (c->forward && done) /* If the service is gone, it's time to drain the output */
+ done = pty_forward_drain(c->forward);
if (done)
sd_event_exit(c->event, EXIT_SUCCESS);
}
-static int on_properties_changed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
+static int run_context_update(RunContext *c, const char *path) {
static const struct bus_properties_map map[] = {
{ "ActiveState", "s", NULL, offsetof(RunContext, active_state) },
@@ -811,23 +818,33 @@ static int on_properties_changed(sd_bus_message *m, void *userdata, sd_bus_error
{}
};
- RunContext *c = userdata;
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
int r;
r = bus_map_all_properties(c->bus,
"org.freedesktop.systemd1",
- sd_bus_message_get_path(m),
+ path,
map,
+ &error,
c);
if (r < 0) {
sd_event_exit(c->event, EXIT_FAILURE);
- return log_error_errno(r, "Failed to query unit state: %m");
+ return log_error_errno(r, "Failed to query unit state: %s", bus_error_message(&error, r));
}
run_context_check_done(c);
return 0;
}
+static int on_properties_changed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
+ RunContext *c = userdata;
+
+ assert(m);
+ assert(c);
+
+ return run_context_update(c, sd_bus_message_get_path(m));
+}
+
static int pty_forward_handler(PTYForward *f, int rcode, void *userdata) {
RunContext *c = userdata;
@@ -985,6 +1002,8 @@ static int start_transient_service(
if (arg_wait || master >= 0) {
_cleanup_(run_context_free) RunContext c = {};
+ _cleanup_free_ char *path = NULL;
+ const char *mt;
c.bus = sd_bus_ref(bus);
@@ -1007,27 +1026,26 @@ static int start_transient_service(
pty_forward_set_handler(c.forward, pty_forward_handler, &c);
}
- if (arg_wait) {
- _cleanup_free_ char *path = NULL;
- const char *mt;
+ path = unit_dbus_path_from_name(service);
+ if (!path)
+ return log_oom();
- path = unit_dbus_path_from_name(service);
- if (!path)
- return log_oom();
+ mt = strjoina("type='signal',"
+ "sender='org.freedesktop.systemd1',"
+ "path='", path, "',"
+ "interface='org.freedesktop.DBus.Properties',"
+ "member='PropertiesChanged'");
+ r = sd_bus_add_match(bus, &c.match, mt, on_properties_changed, &c);
+ if (r < 0)
+ return log_error_errno(r, "Failed to add properties changed signal.");
- mt = strjoina("type='signal',"
- "sender='org.freedesktop.systemd1',"
- "path='", path, "',"
- "interface='org.freedesktop.DBus.Properties',"
- "member='PropertiesChanged'");
- r = sd_bus_add_match(bus, &c.match, mt, on_properties_changed, &c);
- if (r < 0)
- return log_error_errno(r, "Failed to add properties changed signal.");
+ r = sd_bus_attach_event(bus, c.event, 0);
+ if (r < 0)
+ return log_error_errno(r, "Failed to attach bus to event loop.");
- r = sd_bus_attach_event(bus, c.event, 0);
- if (r < 0)
- return log_error_errno(r, "Failed to attach bus to event loop.");
- }
+ r = run_context_update(&c, path);
+ if (r < 0)
+ return r;
r = sd_event_loop(c.event);
if (r < 0)
@@ -1041,7 +1059,13 @@ static int start_transient_service(
fputc('\n', stdout);
}
- if (!arg_quiet) {
+ if (arg_wait && !arg_quiet) {
+
+ /* Explicitly destroy the PTY forwarder, so that the PTY device is usable again, in its
+ * original settings (i.e. proper line breaks), so that we can show the summary in a pretty
+ * way. */
+ c.forward = pty_forward_free(c.forward);
+
if (!isempty(c.result))
log_info("Finished with result: %s", strna(c.result));
@@ -1416,7 +1440,7 @@ int main(int argc, char* argv[]) {
/* If --wait is used connect via the bus, unconditionally, as ref/unref is not supported via the limited direct
* connection */
- if (arg_wait)
+ if (arg_wait || arg_pty)
r = bus_connect_transport(arg_transport, arg_host, arg_user, &bus);
else
r = bus_connect_transport_systemd(arg_transport, arg_host, arg_user, &bus);
diff --git a/src/shared/acl-util.c b/src/shared/acl-util.c
index 2aa951fce9..79a3b9591d 100644
--- a/src/shared/acl-util.c
+++ b/src/shared/acl-util.c
@@ -162,7 +162,7 @@ int add_base_acls_if_needed(acl_t *acl_p, const char *path) {
int acl_search_groups(const char *path, char ***ret_groups) {
_cleanup_strv_free_ char **g = NULL;
- _cleanup_(acl_free) acl_t acl = NULL;
+ _cleanup_(acl_freep) acl_t acl = NULL;
bool ret = false;
acl_entry_t entry;
int r;
diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c
index 2597cfc648..e3b29e390c 100644
--- a/src/shared/ask-password-api.c
+++ b/src/shared/ask-password-api.c
@@ -43,7 +43,7 @@
#include "ask-password-api.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "io-util.h"
#include "log.h"
#include "macro.h"
@@ -95,7 +95,7 @@ static int retrieve_key(key_serial_t serial, char ***ret) {
if (n < m)
break;
- memory_erase(p, n);
+ explicit_bzero(p, n);
free(p);
m *= 2;
}
@@ -104,7 +104,7 @@ static int retrieve_key(key_serial_t serial, char ***ret) {
if (!l)
return -ENOMEM;
- memory_erase(p, n);
+ explicit_bzero(p, n);
*ret = l;
return 0;
@@ -140,7 +140,7 @@ static int add_to_keyring(const char *keyname, AskPasswordFlags flags, char **pa
return r;
serial = add_key("user", keyname, p, n, KEY_SPEC_USER_KEYRING);
- memory_erase(p, n);
+ explicit_bzero(p, n);
if (serial == -1)
return -errno;
@@ -390,7 +390,7 @@ int ask_password_tty(
}
x = strndup(passphrase, p);
- memory_erase(passphrase, p);
+ explicit_bzero(passphrase, p);
if (!x) {
r = -ENOMEM;
goto finish;
@@ -647,7 +647,7 @@ int ask_password_agent(
l = strv_new("", NULL);
else
l = strv_parse_nulstr(passphrase+1, n-1);
- memory_erase(passphrase, n);
+ explicit_bzero(passphrase, n);
if (!l) {
r = -ENOMEM;
goto finish;
diff --git a/src/shared/base-filesystem.c b/src/shared/base-filesystem.c
index 59a34a9d11..127cbe44e3 100644
--- a/src/shared/base-filesystem.c
+++ b/src/shared/base-filesystem.c
@@ -82,7 +82,7 @@ int base_filesystem_create(const char *root, uid_t uid, gid_t gid) {
if (table[i].exists) {
_cleanup_free_ char *p = NULL;
- p = strjoin(s, "/", table[i].exists, NULL);
+ p = strjoin(s, "/", table[i].exists);
if (!p)
return log_oom();
@@ -101,7 +101,7 @@ int base_filesystem_create(const char *root, uid_t uid, gid_t gid) {
if (r < 0 && errno != EEXIST)
return log_error_errno(errno, "Failed to create symlink at %s/%s: %m", root, table[i].dir);
- if (uid != UID_INVALID || gid != UID_INVALID) {
+ if (uid_is_valid(uid) || gid_is_valid(gid)) {
if (fchownat(fd, table[i].dir, uid, gid, AT_SYMLINK_NOFOLLOW) < 0)
return log_error_errno(errno, "Failed to chown symlink at %s/%s: %m", root, table[i].dir);
}
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
index f639e0e832..aae69f6da5 100644
--- a/src/shared/bus-unit-util.c
+++ b/src/shared/bus-unit-util.c
@@ -27,6 +27,8 @@
#include "hashmap.h"
#include "list.h"
#include "locale-util.h"
+#include "mount-util.h"
+#include "nsflags.h"
#include "parse-util.h"
#include "path-util.h"
#include "process-util.h"
@@ -61,6 +63,7 @@ int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u) {
int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignment) {
const char *eq, *field;
+ UnitDependency dep;
int r, rl;
assert(m);
@@ -205,7 +208,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
"PrivateTmp", "PrivateDevices", "PrivateNetwork", "PrivateUsers", "NoNewPrivileges",
"SyslogLevelPrefix", "Delegate", "RemainAfterElapse", "MemoryDenyWriteExecute",
"RestrictRealtime", "DynamicUser", "RemoveIPC", "ProtectKernelTunables",
- "ProtectKernelModules", "ProtectControlGroups")) {
+ "ProtectKernelModules", "ProtectControlGroups", "MountAPIVFS")) {
r = parse_boolean(eq);
if (r < 0)
@@ -263,7 +266,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
"StandardInput", "StandardOutput", "StandardError",
"Description", "Slice", "Type", "WorkingDirectory",
"RootDirectory", "SyslogIdentifier", "ProtectSystem",
- "ProtectHome", "SELinuxContext"))
+ "ProtectHome", "SELinuxContext", "Restart", "RootImage"))
r = sd_bus_message_append(m, "v", "s", eq);
else if (streq(field, "SyslogLevel")) {
@@ -397,9 +400,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
if (r < 0)
return bus_log_create_error(r);
- p = eq;
-
- for (;;) {
+ for (p = eq;;) {
_cleanup_free_ char *word = NULL;
r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE);
@@ -481,11 +482,9 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
if (r < 0)
return bus_log_create_error(r);
- p = eq;
-
- for (;;) {
+ for (p = eq;;) {
_cleanup_free_ char *word = NULL;
- int offset;
+ size_t offset;
r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
if (r < 0) {
@@ -501,6 +500,8 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
}
offset = word[0] == '-';
+ offset += word[offset] == '+';
+
if (!path_is_absolute(word + offset)) {
log_error("Failed to parse %s value %s", field, eq);
return -EINVAL;
@@ -530,9 +531,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
if (r < 0)
return bus_log_create_error(r);
- p = eq;
-
- for (;;) {
+ for (p = eq;;) {
_cleanup_free_ char *word = NULL;
r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
@@ -553,6 +552,110 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
r = sd_bus_message_close_container(m);
+ } else if (streq(field, "RestrictNamespaces")) {
+ bool invert = false;
+ unsigned long flags = 0;
+
+ if (eq[0] == '~') {
+ invert = true;
+ eq++;
+ }
+
+ r = parse_boolean(eq);
+ if (r > 0)
+ flags = 0;
+ else if (r == 0)
+ flags = NAMESPACE_FLAGS_ALL;
+ else {
+ r = namespace_flag_from_string_many(eq, &flags);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse %s value %s.", field, eq);
+ }
+
+ if (invert)
+ flags = (~flags) & NAMESPACE_FLAGS_ALL;
+
+ r = sd_bus_message_append(m, "v", "t", (uint64_t) flags);
+ } else if ((dep = unit_dependency_from_string(field)) >= 0)
+ r = sd_bus_message_append(m, "v", "as", 1, eq);
+ else if (streq(field, "MountFlags")) {
+ unsigned long f;
+
+ r = mount_propagation_flags_from_string(eq, &f);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse mount propagation flags: %s", eq);
+
+ r = sd_bus_message_append(m, "v", "t", (uint64_t) f);
+ } else if (STR_IN_SET(field, "BindPaths", "BindReadOnlyPaths")) {
+ const char *p = eq;
+
+ r = sd_bus_message_open_container(m, 'v', "a(ssbt)");
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_open_container(m, 'a', "(ssbt)");
+ if (r < 0)
+ return r;
+
+ for (;;) {
+ _cleanup_free_ char *source = NULL, *destination = NULL;
+ char *s = NULL, *d = NULL;
+ bool ignore_enoent = false;
+ uint64_t flags = MS_REC;
+
+ r = extract_first_word(&p, &source, ":" WHITESPACE, EXTRACT_QUOTES|EXTRACT_DONT_COALESCE_SEPARATORS);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse argument: %m");
+ if (r == 0)
+ break;
+
+ s = source;
+ if (s[0] == '-') {
+ ignore_enoent = true;
+ s++;
+ }
+
+ if (p && p[-1] == ':') {
+ r = extract_first_word(&p, &destination, ":" WHITESPACE, EXTRACT_QUOTES|EXTRACT_DONT_COALESCE_SEPARATORS);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse argument: %m");
+ if (r == 0) {
+ log_error("Missing argument after ':': %s", eq);
+ return -EINVAL;
+ }
+
+ d = destination;
+
+ if (p && p[-1] == ':') {
+ _cleanup_free_ char *options = NULL;
+
+ r = extract_first_word(&p, &options, NULL, EXTRACT_QUOTES);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse argument: %m");
+
+ if (isempty(options) || streq(options, "rbind"))
+ flags = MS_REC;
+ else if (streq(options, "norbind"))
+ flags = 0;
+ else {
+ log_error("Unknown options: %s", eq);
+ return -EINVAL;
+ }
+ }
+ } else
+ d = s;
+
+
+ r = sd_bus_message_append(m, "(ssbt)", s, d, ignore_enoent, flags);
+ if (r < 0)
+ return r;
+ }
+
+ r = sd_bus_message_close_container(m);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_close_container(m);
} else {
log_error("Unknown assignment %s.", assignment);
return -EINVAL;
@@ -742,6 +845,7 @@ static const struct {
const char *result, *explanation;
} explanations [] = {
{ "resources", "of unavailable resources or another system error" },
+ { "protocol", "the service did not take the steps required by its unit configuration" },
{ "timeout", "a timeout was exceeded" },
{ "exit-code", "the control process exited with error code" },
{ "signal", "a fatal signal was delivered to the control process" },
@@ -758,7 +862,7 @@ static void log_job_error_with_service_result(const char* service, const char *r
service_shell_quoted = shell_maybe_quote(service);
- if (extra_args && extra_args[1]) {
+ if (extra_args) {
_cleanup_free_ char *t;
t = strv_join((char**) extra_args, " ");
@@ -819,6 +923,8 @@ static int check_wait_response(BusWaitForJobs *d, bool quiet, const char* const*
log_error("Assertion failed on job for %s.", strna(d->name));
else if (streq(d->result, "unsupported"))
log_error("Operation on or unit type of %s not supported on this system.", strna(d->name));
+ else if (streq(d->result, "collected"))
+ log_error("Queued job for %s was garbage collected.", strna(d->name));
else if (!streq(d->result, "done") && !streq(d->result, "skipped")) {
if (d->name) {
int q;
@@ -834,7 +940,7 @@ static int check_wait_response(BusWaitForJobs *d, bool quiet, const char* const*
}
}
- if (streq(d->result, "canceled"))
+ if (STR_IN_SET(d->result, "canceled", "collected"))
r = -ECANCELED;
else if (streq(d->result, "timeout"))
r = -ETIME;
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
index bb90c89cc2..8ddfb584ea 100644
--- a/src/shared/bus-util.c
+++ b/src/shared/bus-util.c
@@ -43,6 +43,7 @@
#include "escape.h"
#include "fd-util.h"
#include "missing.h"
+#include "nsflags.h"
#include "parse-util.h"
#include "proc-cmdline.h"
#include "rlimit-util.h"
@@ -676,7 +677,7 @@ int bus_connect_user_systemd(sd_bus **_bus) {
if (r < 0)
return r;
- bus->address = strjoin("unix:path=", ee, "/systemd/private", NULL);
+ bus->address = strjoin("unix:path=", ee, "/systemd/private");
if (!bus->address)
return -ENOMEM;
@@ -769,6 +770,23 @@ int bus_print_property(const char *name, sd_bus_message *property, bool value, b
char timespan[FORMAT_TIMESPAN_MAX];
print_property(name, "%s", format_timespan(timespan, sizeof(timespan), u, 0));
+ } else if (streq(name, "RestrictNamespaces")) {
+ _cleanup_free_ char *s = NULL;
+ const char *result = NULL;
+
+ if ((u & NAMESPACE_FLAGS_ALL) == 0)
+ result = "yes";
+ else if ((u & NAMESPACE_FLAGS_ALL) == NAMESPACE_FLAGS_ALL)
+ result = "no";
+ else {
+ r = namespace_flag_to_string_many(u, &s);
+ if (r < 0)
+ return r;
+
+ result = s;
+ }
+
+ print_property(name, "%s", result);
} else
print_property(name, "%"PRIu64, u);
@@ -1098,9 +1116,9 @@ static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_
int bus_message_map_all_properties(
sd_bus_message *m,
const struct bus_properties_map *map,
+ sd_bus_error *error,
void *userdata) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
int r;
assert(m);
@@ -1138,9 +1156,9 @@ int bus_message_map_all_properties(
v = (uint8_t *)userdata + prop->offset;
if (map[i].set)
- r = prop->set(sd_bus_message_get_bus(m), member, m, &error, v);
+ r = prop->set(sd_bus_message_get_bus(m), member, m, error, v);
else
- r = map_basic(sd_bus_message_get_bus(m), member, m, &error, v);
+ r = map_basic(sd_bus_message_get_bus(m), member, m, error, v);
if (r < 0)
return r;
@@ -1166,6 +1184,7 @@ int bus_message_map_all_properties(
int bus_message_map_properties_changed(
sd_bus_message *m,
const struct bus_properties_map *map,
+ sd_bus_error *error,
void *userdata) {
const char *member;
@@ -1174,7 +1193,7 @@ int bus_message_map_properties_changed(
assert(m);
assert(map);
- r = bus_message_map_all_properties(m, map, userdata);
+ r = bus_message_map_all_properties(m, map, error, userdata);
if (r < 0)
return r;
@@ -1204,10 +1223,10 @@ int bus_map_all_properties(
const char *destination,
const char *path,
const struct bus_properties_map *map,
+ sd_bus_error *error,
void *userdata) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
int r;
assert(bus);
@@ -1221,13 +1240,13 @@ int bus_map_all_properties(
path,
"org.freedesktop.DBus.Properties",
"GetAll",
- &error,
+ error,
&m,
"s", "");
if (r < 0)
return r;
- return bus_message_map_all_properties(m, map, userdata);
+ return bus_message_map_all_properties(m, map, error, userdata);
}
int bus_connect_transport(BusTransport transport, const char *host, bool user, sd_bus **ret) {
@@ -1460,7 +1479,7 @@ int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id,
if (!external_label)
return -ENOMEM;
- p = strjoin(prefix, "/", sender_label, "/", external_label, NULL);
+ p = strjoin(prefix, "/", sender_label, "/", external_label);
if (!p)
return -ENOMEM;
@@ -1565,3 +1584,22 @@ int bus_property_get_rlimit(
return sd_bus_message_append(reply, "t", u);
}
+
+int bus_track_add_name_many(sd_bus_track *t, char **l) {
+ int r = 0;
+ char **i;
+
+ assert(t);
+
+ /* Continues adding after failure, and returns the first failure. */
+
+ STRV_FOREACH(i, l) {
+ int k;
+
+ k = sd_bus_track_add_name(t, *i);
+ if (k < 0 && r >= 0)
+ r = k;
+ }
+
+ return r;
+}
diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h
index 934e0b5b77..d9ce4263bb 100644
--- a/src/shared/bus-util.h
+++ b/src/shared/bus-util.h
@@ -50,9 +50,9 @@ struct bus_properties_map {
int bus_map_id128(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata);
-int bus_message_map_all_properties(sd_bus_message *m, const struct bus_properties_map *map, void *userdata);
-int bus_message_map_properties_changed(sd_bus_message *m, const struct bus_properties_map *map, void *userdata);
-int bus_map_all_properties(sd_bus *bus, const char *destination, const char *path, const struct bus_properties_map *map, void *userdata);
+int bus_message_map_all_properties(sd_bus_message *m, const struct bus_properties_map *map, sd_bus_error *error, void *userdata);
+int bus_message_map_properties_changed(sd_bus_message *m, const struct bus_properties_map *map, sd_bus_error *error, void *userdata);
+int bus_map_all_properties(sd_bus *bus, const char *destination, const char *path, const struct bus_properties_map *map, sd_bus_error *error, void *userdata);
int bus_async_unregister_and_exit(sd_event *e, sd_bus *bus, const char *name);
@@ -159,3 +159,5 @@ int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id,
int bus_path_decode_unique(const char *path, const char *prefix, char **ret_sender, char **ret_external);
int bus_property_get_rlimit(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
+
+int bus_track_add_name_many(sd_bus_track *t, char **l);
diff --git a/src/shared/cgroup-show.c b/src/shared/cgroup-show.c
index 3e451db715..8765cf2f49 100644
--- a/src/shared/cgroup-show.c
+++ b/src/shared/cgroup-show.c
@@ -24,11 +24,16 @@
#include <stdlib.h>
#include <string.h>
+#include <systemd/sd-bus.h>
+
#include "alloc-util.h"
+#include "bus-error.h"
+#include "bus-util.h"
#include "cgroup-show.h"
#include "cgroup-util.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "fileio.h"
+#include "format-util.h"
#include "locale-util.h"
#include "macro.h"
#include "output-mode.h"
@@ -36,6 +41,7 @@
#include "process-util.h"
#include "string-util.h"
#include "terminal-util.h"
+#include "unit-name.h"
static void show_pid_array(
pid_t pids[],
@@ -73,7 +79,7 @@ static void show_pid_array(
for (i = 0; i < n_pids; i++) {
_cleanup_free_ char *t = NULL;
- get_process_cmdline(pids[i], n_columns, true, &t);
+ (void) get_process_cmdline(pids[i], n_columns, true, &t);
if (extra)
printf("%s%s ", prefix, special_glyph(TRIANGULAR_BULLET));
@@ -158,7 +164,7 @@ int show_cgroup_by_path(
while ((r = cg_read_subgroup(d, &gn)) > 0) {
_cleanup_free_ char *k = NULL;
- k = strjoin(fn, "/", gn, NULL);
+ k = strjoin(fn, "/", gn);
free(gn);
if (!k)
return -ENOMEM;
@@ -310,3 +316,81 @@ int show_cgroup_and_extra_by_spec(
return show_cgroup_and_extra(controller, path, prefix, n_columns, extra_pids, n_extra_pids, flags);
}
+
+int show_cgroup_get_unit_path_and_warn(
+ sd_bus *bus,
+ const char *unit,
+ char **ret) {
+
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_free_ char *path = NULL;
+ int r;
+
+ path = unit_dbus_path_from_name(unit);
+ if (!path)
+ return log_oom();
+
+ r = sd_bus_get_property_string(
+ bus,
+ "org.freedesktop.systemd1",
+ path,
+ unit_dbus_interface_from_name(unit),
+ "ControlGroup",
+ &error,
+ ret);
+ if (r < 0)
+ return log_error_errno(r, "Failed to query unit control group path: %s",
+ bus_error_message(&error, r));
+
+ return 0;
+}
+
+int show_cgroup_get_path_and_warn(
+ const char *machine,
+ const char *prefix,
+ char **ret) {
+
+ int r;
+ _cleanup_free_ char *root = NULL;
+
+ if (machine) {
+ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+ _cleanup_free_ char *unit = NULL;
+ const char *m;
+
+ m = strjoina("/run/systemd/machines/", machine);
+ r = parse_env_file(m, NEWLINE, "SCOPE", &unit, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to load machine data: %m");
+
+ r = bus_connect_transport_systemd(BUS_TRANSPORT_LOCAL, NULL, false, &bus);
+ if (r < 0)
+ return log_error_errno(r, "Failed to create bus connection: %m");
+
+ r = show_cgroup_get_unit_path_and_warn(bus, unit, &root);
+ if (r < 0)
+ return r;
+ } else {
+ r = cg_get_root_path(&root);
+ if (r == -ENOMEDIUM)
+ return log_error_errno(r, "Failed to get root control group path.\n"
+ "No cgroup filesystem mounted on /sys/fs/cgroup");
+ else if (r < 0)
+ return log_error_errno(r, "Failed to get root control group path: %m");
+ }
+
+ if (prefix) {
+ char *t;
+
+ t = strjoin(root, prefix);
+ if (!t)
+ return log_oom();
+
+ *ret = t;
+ } else {
+ *ret = root;
+ root = NULL;
+ }
+
+ return 0;
+}
diff --git a/src/shared/cgroup-show.h b/src/shared/cgroup-show.h
index 5c1d6e6d98..736f0f34c8 100644
--- a/src/shared/cgroup-show.h
+++ b/src/shared/cgroup-show.h
@@ -22,6 +22,8 @@
#include <stdbool.h>
#include <sys/types.h>
+#include <systemd/sd-bus.h>
+
#include "logs-show.h"
#include "output-mode.h"
@@ -30,3 +32,12 @@ int show_cgroup(const char *controller, const char *path, const char *prefix, un
int show_cgroup_and_extra_by_spec(const char *spec, const char *prefix, unsigned n_columns, const pid_t extra_pids[], unsigned n_extra_pids, OutputFlags flags);
int show_cgroup_and_extra(const char *controller, const char *path, const char *prefix, unsigned n_columns, const pid_t extra_pids[], unsigned n_extra_pids, OutputFlags flags);
+
+int show_cgroup_get_unit_path_and_warn(
+ sd_bus *bus,
+ const char *unit,
+ char **ret);
+int show_cgroup_get_path_and_warn(
+ const char *machine,
+ const char *prefix,
+ char **ret);
diff --git a/src/shared/clean-ipc.c b/src/shared/clean-ipc.c
index d5db604f03..f59f6f23ae 100644
--- a/src/shared/clean-ipc.c
+++ b/src/shared/clean-ipc.c
@@ -36,7 +36,7 @@
#include "dirent-util.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "log.h"
#include "macro.h"
#include "string-util.h"
@@ -225,7 +225,7 @@ static int clean_posix_shm_internal(DIR *dir, uid_t uid, gid_t gid) {
FOREACH_DIRENT_ALL(de, dir, goto fail) {
struct stat st;
- if (STR_IN_SET(de->d_name, "..", "."))
+ if (dot_or_dot_dot(de->d_name))
continue;
if (fstatat(dirfd(dir), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
@@ -310,7 +310,7 @@ static int clean_posix_mq(uid_t uid, gid_t gid) {
struct stat st;
char fn[1+strlen(de->d_name)+1];
- if (STR_IN_SET(de->d_name, "..", "."))
+ if (dot_or_dot_dot(de->d_name))
continue;
if (fstatat(dirfd(dir), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
diff --git a/src/shared/condition.c b/src/shared/condition.c
index 8bd6a51a99..0b77d2c22d 100644
--- a/src/shared/condition.c
+++ b/src/shared/condition.c
@@ -111,9 +111,8 @@ static int condition_test_kernel_command_line(Condition *c) {
return r;
equal = !!strchr(c->parameter, '=');
- p = line;
- for (;;) {
+ for (p = line;;) {
_cleanup_free_ char *word = NULL;
bool found;
@@ -400,7 +399,7 @@ static int condition_test_path_is_mount_point(Condition *c) {
assert(c->parameter);
assert(c->type == CONDITION_PATH_IS_MOUNT_POINT);
- return path_is_mount_point(c->parameter, AT_SYMLINK_FOLLOW) > 0;
+ return path_is_mount_point(c->parameter, NULL, AT_SYMLINK_FOLLOW) > 0;
}
static int condition_test_path_is_read_write(Condition *c) {
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
index 2ec0155b71..863034d18a 100644
--- a/src/shared/conf-parser.c
+++ b/src/shared/conf-parser.c
@@ -101,7 +101,7 @@ int config_item_perf_lookup(
else {
char *key;
- key = strjoin(section, ".", lvalue, NULL);
+ key = strjoin(section, ".", lvalue);
if (!key)
return -ENOMEM;
@@ -781,7 +781,7 @@ int config_parse_strv(const char *unit,
for (;;) {
char *word = NULL;
- r = extract_first_word(&rvalue, &word, WHITESPACE, EXTRACT_QUOTES|EXTRACT_RETAIN_ESCAPE);
+ r = extract_first_word(&rvalue, &word, NULL, EXTRACT_QUOTES|EXTRACT_RETAIN_ESCAPE);
if (r == 0)
break;
if (r == -ENOMEM)
@@ -792,7 +792,7 @@ int config_parse_strv(const char *unit,
}
if (!utf8_is_valid(word)) {
- log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue);
+ log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, word);
free(word);
continue;
}
diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c
new file mode 100644
index 0000000000..39e724c51a
--- /dev/null
+++ b/src/shared/dissect-image.c
@@ -0,0 +1,1177 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#ifdef HAVE_LIBCRYPTSETUP
+#include <libcryptsetup.h>
+#endif
+#include <linux/dm-ioctl.h>
+#include <sys/mount.h>
+
+#include "architecture.h"
+#include "ask-password-api.h"
+#include "blkid-util.h"
+#include "dissect-image.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "fs-util.h"
+#include "gpt.h"
+#include "hexdecoct.h"
+#include "mount-util.h"
+#include "path-util.h"
+#include "stat-util.h"
+#include "stdio-util.h"
+#include "string-table.h"
+#include "string-util.h"
+#include "strv.h"
+#include "udev-util.h"
+#include "xattr-util.h"
+
+static int probe_filesystem(const char *node, char **ret_fstype) {
+#ifdef HAVE_BLKID
+ _cleanup_blkid_free_probe_ blkid_probe b = NULL;
+ const char *fstype;
+ int r;
+
+ b = blkid_new_probe_from_filename(node);
+ if (!b)
+ return -ENOMEM;
+
+ blkid_probe_enable_superblocks(b, 1);
+ blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
+
+ errno = 0;
+ r = blkid_do_safeprobe(b);
+ if (r == -2 || r == 1) {
+ log_debug("Failed to identify any partition type on partition %s", node);
+ goto not_found;
+ }
+ if (r != 0)
+ return -errno ?: -EIO;
+
+ (void) blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);
+
+ if (fstype) {
+ char *t;
+
+ t = strdup(fstype);
+ if (!t)
+ return -ENOMEM;
+
+ *ret_fstype = t;
+ return 1;
+ }
+
+not_found:
+ *ret_fstype = NULL;
+ return 0;
+#else
+ return -EOPNOTSUPP;
+#endif
+}
+
+int dissect_image(int fd, const void *root_hash, size_t root_hash_size, DissectImageFlags flags, DissectedImage **ret) {
+
+#ifdef HAVE_BLKID
+ sd_id128_t root_uuid = SD_ID128_NULL, verity_uuid = SD_ID128_NULL;
+ _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
+ bool is_gpt, is_mbr, generic_rw, multiple_generic = false;
+ _cleanup_udev_device_unref_ struct udev_device *d = NULL;
+ _cleanup_(dissected_image_unrefp) DissectedImage *m = NULL;
+ _cleanup_blkid_free_probe_ blkid_probe b = NULL;
+ _cleanup_udev_unref_ struct udev *udev = NULL;
+ _cleanup_free_ char *generic_node = NULL;
+ sd_id128_t generic_uuid = SD_ID128_NULL;
+ const char *pttype = NULL;
+ struct udev_list_entry *first, *item;
+ blkid_partlist pl;
+ int r, generic_nr;
+ struct stat st;
+ unsigned i;
+
+ assert(fd >= 0);
+ assert(ret);
+ assert(root_hash || root_hash_size == 0);
+
+ /* Probes a disk image, and returns information about what it found in *ret.
+ *
+ * Returns -ENOPKG if no suitable partition table or file system could be found.
+ * Returns -EADDRNOTAVAIL if a root hash was specified but no matching root/verity partitions found. */
+
+ if (root_hash) {
+ /* If a root hash is supplied, then we use the root partition that has a UUID that match the first
+ * 128bit of the root hash. And we use the verity partition that has a UUID that match the final
+ * 128bit. */
+
+ if (root_hash_size < sizeof(sd_id128_t))
+ return -EINVAL;
+
+ memcpy(&root_uuid, root_hash, sizeof(sd_id128_t));
+ memcpy(&verity_uuid, (const uint8_t*) root_hash + root_hash_size - sizeof(sd_id128_t), sizeof(sd_id128_t));
+
+ if (sd_id128_is_null(root_uuid))
+ return -EINVAL;
+ if (sd_id128_is_null(verity_uuid))
+ return -EINVAL;
+ }
+
+ if (fstat(fd, &st) < 0)
+ return -errno;
+
+ if (!S_ISBLK(st.st_mode))
+ return -ENOTBLK;
+
+ b = blkid_new_probe();
+ if (!b)
+ return -ENOMEM;
+
+ errno = 0;
+ r = blkid_probe_set_device(b, fd, 0, 0);
+ if (r != 0)
+ return -errno ?: -ENOMEM;
+
+ if ((flags & DISSECT_IMAGE_GPT_ONLY) == 0) {
+ /* Look for file system superblocks, unless we only shall look for GPT partition tables */
+ blkid_probe_enable_superblocks(b, 1);
+ blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE|BLKID_SUBLKS_USAGE);
+ }
+
+ blkid_probe_enable_partitions(b, 1);
+ blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
+
+ errno = 0;
+ r = blkid_do_safeprobe(b);
+ if (r == -2 || r == 1) {
+ log_debug("Failed to identify any partition table.");
+ return -ENOPKG;
+ }
+ if (r != 0)
+ return -errno ?: -EIO;
+
+ m = new0(DissectedImage, 1);
+ if (!m)
+ return -ENOMEM;
+
+ if (!(flags & DISSECT_IMAGE_GPT_ONLY) &&
+ (flags & DISSECT_IMAGE_REQUIRE_ROOT)) {
+ const char *usage = NULL;
+
+ (void) blkid_probe_lookup_value(b, "USAGE", &usage, NULL);
+ if (STRPTR_IN_SET(usage, "filesystem", "crypto")) {
+ _cleanup_free_ char *t = NULL, *n = NULL;
+ const char *fstype = NULL;
+
+ /* OK, we have found a file system, that's our root partition then. */
+ (void) blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);
+
+ if (fstype) {
+ t = strdup(fstype);
+ if (!t)
+ return -ENOMEM;
+ }
+
+ if (asprintf(&n, "/dev/block/%u:%u", major(st.st_rdev), minor(st.st_rdev)) < 0)
+ return -ENOMEM;
+
+ m->partitions[PARTITION_ROOT] = (DissectedPartition) {
+ .found = true,
+ .rw = true,
+ .partno = -1,
+ .architecture = _ARCHITECTURE_INVALID,
+ .fstype = t,
+ .node = n,
+ };
+
+ t = n = NULL;
+
+ m->encrypted = streq(fstype, "crypto_LUKS");
+
+ *ret = m;
+ m = NULL;
+
+ return 0;
+ }
+ }
+
+ (void) blkid_probe_lookup_value(b, "PTTYPE", &pttype, NULL);
+ if (!pttype)
+ return -ENOPKG;
+
+ is_gpt = streq_ptr(pttype, "gpt");
+ is_mbr = streq_ptr(pttype, "dos");
+
+ if (!is_gpt && ((flags & DISSECT_IMAGE_GPT_ONLY) || !is_mbr))
+ return -ENOPKG;
+
+ errno = 0;
+ pl = blkid_probe_get_partitions(b);
+ if (!pl)
+ return -errno ?: -ENOMEM;
+
+ udev = udev_new();
+ if (!udev)
+ return -errno;
+
+ d = udev_device_new_from_devnum(udev, 'b', st.st_rdev);
+ if (!d)
+ return -ENOMEM;
+
+ for (i = 0;; i++) {
+ int n, z;
+
+ if (i >= 10) {
+ log_debug("Kernel partitions never appeared.");
+ return -ENXIO;
+ }
+
+ e = udev_enumerate_new(udev);
+ if (!e)
+ return -errno;
+
+ r = udev_enumerate_add_match_parent(e, d);
+ if (r < 0)
+ return r;
+
+ r = udev_enumerate_scan_devices(e);
+ if (r < 0)
+ return r;
+
+ /* Count the partitions enumerated by the kernel */
+ n = 0;
+ first = udev_enumerate_get_list_entry(e);
+ udev_list_entry_foreach(item, first)
+ n++;
+
+ /* Count the partitions enumerated by blkid */
+ z = blkid_partlist_numof_partitions(pl);
+ if (n == z + 1)
+ break;
+ if (n > z + 1) {
+ log_debug("blkid and kernel partition list do not match.");
+ return -EIO;
+ }
+ if (n < z + 1) {
+ unsigned j;
+
+ /* The kernel has probed fewer partitions than blkid? Maybe the kernel prober is still running
+ * or it got EBUSY because udev already opened the device. Let's reprobe the device, which is a
+ * synchronous call that waits until probing is complete. */
+
+ for (j = 0; j < 20; j++) {
+
+ r = ioctl(fd, BLKRRPART, 0);
+ if (r < 0)
+ r = -errno;
+ if (r >= 0 || r != -EBUSY)
+ break;
+
+ /* If something else has the device open, such as an udev rule, the ioctl will return
+ * EBUSY. Since there's no way to wait until it isn't busy anymore, let's just wait a
+ * bit, and try again.
+ *
+ * This is really something they should fix in the kernel! */
+
+ usleep(50 * USEC_PER_MSEC);
+ }
+
+ if (r < 0)
+ return r;
+ }
+
+ e = udev_enumerate_unref(e);
+ }
+
+ first = udev_enumerate_get_list_entry(e);
+ udev_list_entry_foreach(item, first) {
+ _cleanup_udev_device_unref_ struct udev_device *q;
+ unsigned long long pflags;
+ blkid_partition pp;
+ const char *node;
+ dev_t qn;
+ int nr;
+
+ q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
+ if (!q)
+ return -errno;
+
+ qn = udev_device_get_devnum(q);
+ if (major(qn) == 0)
+ continue;
+
+ if (st.st_rdev == qn)
+ continue;
+
+ node = udev_device_get_devnode(q);
+ if (!node)
+ continue;
+
+ pp = blkid_partlist_devno_to_partition(pl, qn);
+ if (!pp)
+ continue;
+
+ pflags = blkid_partition_get_flags(pp);
+
+ nr = blkid_partition_get_partno(pp);
+ if (nr < 0)
+ continue;
+
+ if (is_gpt) {
+ int designator = _PARTITION_DESIGNATOR_INVALID, architecture = _ARCHITECTURE_INVALID;
+ const char *stype, *sid, *fstype = NULL;
+ sd_id128_t type_id, id;
+ bool rw = true;
+
+ sid = blkid_partition_get_uuid(pp);
+ if (!sid)
+ continue;
+ if (sd_id128_from_string(sid, &id) < 0)
+ continue;
+
+ stype = blkid_partition_get_type_string(pp);
+ if (!stype)
+ continue;
+ if (sd_id128_from_string(stype, &type_id) < 0)
+ continue;
+
+ if (sd_id128_equal(type_id, GPT_HOME)) {
+
+ if (pflags & GPT_FLAG_NO_AUTO)
+ continue;
+
+ designator = PARTITION_HOME;
+ rw = !(pflags & GPT_FLAG_READ_ONLY);
+ } else if (sd_id128_equal(type_id, GPT_SRV)) {
+
+ if (pflags & GPT_FLAG_NO_AUTO)
+ continue;
+
+ designator = PARTITION_SRV;
+ rw = !(pflags & GPT_FLAG_READ_ONLY);
+ } else if (sd_id128_equal(type_id, GPT_ESP)) {
+
+ /* Note that we don't check the GPT_FLAG_NO_AUTO flag for the ESP, as it is not defined
+ * there. We instead check the GPT_FLAG_NO_BLOCK_IO_PROTOCOL, as recommended by the
+ * UEFI spec (See "12.3.3 Number and Location of System Partitions"). */
+
+ if (pflags & GPT_FLAG_NO_BLOCK_IO_PROTOCOL)
+ continue;
+
+ designator = PARTITION_ESP;
+ fstype = "vfat";
+ }
+#ifdef GPT_ROOT_NATIVE
+ else if (sd_id128_equal(type_id, GPT_ROOT_NATIVE)) {
+
+ if (pflags & GPT_FLAG_NO_AUTO)
+ continue;
+
+ /* If a root ID is specified, ignore everything but the root id */
+ if (!sd_id128_is_null(root_uuid) && !sd_id128_equal(root_uuid, id))
+ continue;
+
+ designator = PARTITION_ROOT;
+ architecture = native_architecture();
+ rw = !(pflags & GPT_FLAG_READ_ONLY);
+ } else if (sd_id128_equal(type_id, GPT_ROOT_NATIVE_VERITY)) {
+
+ if (pflags & GPT_FLAG_NO_AUTO)
+ continue;
+
+ m->can_verity = true;
+
+ /* Ignore verity unless a root hash is specified */
+ if (sd_id128_is_null(verity_uuid) || !sd_id128_equal(verity_uuid, id))
+ continue;
+
+ designator = PARTITION_ROOT_VERITY;
+ fstype = "DM_verity_hash";
+ architecture = native_architecture();
+ rw = false;
+ }
+#endif
+#ifdef GPT_ROOT_SECONDARY
+ else if (sd_id128_equal(type_id, GPT_ROOT_SECONDARY)) {
+
+ if (pflags & GPT_FLAG_NO_AUTO)
+ continue;
+
+ /* If a root ID is specified, ignore everything but the root id */
+ if (!sd_id128_is_null(root_uuid) && !sd_id128_equal(root_uuid, id))
+ continue;
+
+ designator = PARTITION_ROOT_SECONDARY;
+ architecture = SECONDARY_ARCHITECTURE;
+ rw = !(pflags & GPT_FLAG_READ_ONLY);
+ } else if (sd_id128_equal(type_id, GPT_ROOT_SECONDARY_VERITY)) {
+
+ if (pflags & GPT_FLAG_NO_AUTO)
+ continue;
+
+ m->can_verity = true;
+
+ /* Ignore verity unless root has is specified */
+ if (sd_id128_is_null(verity_uuid) || !sd_id128_equal(verity_uuid, id))
+ continue;
+
+ designator = PARTITION_ROOT_SECONDARY_VERITY;
+ fstype = "DM_verity_hash";
+ architecture = SECONDARY_ARCHITECTURE;
+ rw = false;
+ }
+#endif
+ else if (sd_id128_equal(type_id, GPT_SWAP)) {
+
+ if (pflags & GPT_FLAG_NO_AUTO)
+ continue;
+
+ designator = PARTITION_SWAP;
+ fstype = "swap";
+ } else if (sd_id128_equal(type_id, GPT_LINUX_GENERIC)) {
+
+ if (pflags & GPT_FLAG_NO_AUTO)
+ continue;
+
+ if (generic_node)
+ multiple_generic = true;
+ else {
+ generic_nr = nr;
+ generic_rw = !(pflags & GPT_FLAG_READ_ONLY);
+ generic_uuid = id;
+ generic_node = strdup(node);
+ if (!generic_node)
+ return -ENOMEM;
+ }
+ }
+
+ if (designator != _PARTITION_DESIGNATOR_INVALID) {
+ _cleanup_free_ char *t = NULL, *n = NULL;
+
+ /* First one wins */
+ if (m->partitions[designator].found)
+ continue;
+
+ if (fstype) {
+ t = strdup(fstype);
+ if (!t)
+ return -ENOMEM;
+ }
+
+ n = strdup(node);
+ if (!n)
+ return -ENOMEM;
+
+ m->partitions[designator] = (DissectedPartition) {
+ .found = true,
+ .partno = nr,
+ .rw = rw,
+ .architecture = architecture,
+ .node = n,
+ .fstype = t,
+ .uuid = id,
+ };
+
+ n = t = NULL;
+ }
+
+ } else if (is_mbr) {
+
+ if (pflags != 0x80) /* Bootable flag */
+ continue;
+
+ if (blkid_partition_get_type(pp) != 0x83) /* Linux partition */
+ continue;
+
+ if (generic_node)
+ multiple_generic = true;
+ else {
+ generic_nr = nr;
+ generic_rw = true;
+ generic_node = strdup(node);
+ if (!generic_node)
+ return -ENOMEM;
+ }
+ }
+ }
+
+ if (!m->partitions[PARTITION_ROOT].found) {
+ /* No root partition found? Then let's see if ther's one for the secondary architecture. And if not
+ * either, then check if there's a single generic one, and use that. */
+
+ if (m->partitions[PARTITION_ROOT_VERITY].found)
+ return -EADDRNOTAVAIL;
+
+ if (m->partitions[PARTITION_ROOT_SECONDARY].found) {
+ m->partitions[PARTITION_ROOT] = m->partitions[PARTITION_ROOT_SECONDARY];
+ zero(m->partitions[PARTITION_ROOT_SECONDARY]);
+
+ m->partitions[PARTITION_ROOT_VERITY] = m->partitions[PARTITION_ROOT_SECONDARY_VERITY];
+ zero(m->partitions[PARTITION_ROOT_SECONDARY_VERITY]);
+
+ } else if (flags & DISSECT_IMAGE_REQUIRE_ROOT) {
+
+ /* If the root has was set, then we won't fallback to a generic node, because the root hash
+ * decides */
+ if (root_hash)
+ return -EADDRNOTAVAIL;
+
+ /* If we didn't find a generic node, then we can't fix this up either */
+ if (!generic_node)
+ return -ENXIO;
+
+ /* If we didn't find a properly marked root partition, but we did find a single suitable
+ * generic Linux partition, then use this as root partition, if the caller asked for it. */
+ if (multiple_generic)
+ return -ENOTUNIQ;
+
+ m->partitions[PARTITION_ROOT] = (DissectedPartition) {
+ .found = true,
+ .rw = generic_rw,
+ .partno = generic_nr,
+ .architecture = _ARCHITECTURE_INVALID,
+ .node = generic_node,
+ .uuid = generic_uuid,
+ };
+
+ generic_node = NULL;
+ }
+ }
+
+ if (root_hash) {
+ if (!m->partitions[PARTITION_ROOT_VERITY].found || !m->partitions[PARTITION_ROOT].found)
+ return -EADDRNOTAVAIL;
+
+ /* If we found the primary root with the hash, then we definitely want to suppress any secondary root
+ * (which would be weird, after all the root hash should only be assigned to one pair of
+ * partitions... */
+ m->partitions[PARTITION_ROOT_SECONDARY].found = false;
+ m->partitions[PARTITION_ROOT_SECONDARY_VERITY].found = false;
+
+ /* If we found a verity setup, then the root partition is necessarily read-only. */
+ m->partitions[PARTITION_ROOT].rw = false;
+
+ m->verity = true;
+ }
+
+ blkid_free_probe(b);
+ b = NULL;
+
+ /* Fill in file system types if we don't know them yet. */
+ for (i = 0; i < _PARTITION_DESIGNATOR_MAX; i++) {
+ DissectedPartition *p = m->partitions + i;
+
+ if (!p->found)
+ continue;
+
+ if (!p->fstype && p->node) {
+ r = probe_filesystem(p->node, &p->fstype);
+ if (r < 0)
+ return r;
+ }
+
+ if (streq_ptr(p->fstype, "crypto_LUKS"))
+ m->encrypted = true;
+ }
+
+ *ret = m;
+ m = NULL;
+
+ return 0;
+#else
+ return -EOPNOTSUPP;
+#endif
+}
+
+DissectedImage* dissected_image_unref(DissectedImage *m) {
+ unsigned i;
+
+ if (!m)
+ return NULL;
+
+ for (i = 0; i < _PARTITION_DESIGNATOR_MAX; i++) {
+ free(m->partitions[i].fstype);
+ free(m->partitions[i].node);
+ free(m->partitions[i].decrypted_fstype);
+ free(m->partitions[i].decrypted_node);
+ }
+
+ free(m);
+ return NULL;
+}
+
+static int is_loop_device(const char *path) {
+ char s[strlen("/sys/dev/block/") + DECIMAL_STR_MAX(dev_t) + 1 + DECIMAL_STR_MAX(dev_t) + strlen("/../loop/")];
+ struct stat st;
+
+ assert(path);
+
+ if (stat(path, &st) < 0)
+ return -errno;
+
+ if (!S_ISBLK(st.st_mode))
+ return -ENOTBLK;
+
+ xsprintf(s, "/sys/dev/block/%u:%u/loop/", major(st.st_rdev), minor(st.st_rdev));
+ if (access(s, F_OK) < 0) {
+ if (errno != ENOENT)
+ return -errno;
+
+ /* The device itself isn't a loop device, but maybe it's a partition and its parent is? */
+ xsprintf(s, "/sys/dev/block/%u:%u/../loop/", major(st.st_rdev), minor(st.st_rdev));
+ if (access(s, F_OK) < 0)
+ return errno == ENOENT ? false : -errno;
+ }
+
+ return true;
+}
+
+static int mount_partition(
+ DissectedPartition *m,
+ const char *where,
+ const char *directory,
+ DissectImageFlags flags) {
+
+ const char *p, *options = NULL, *node, *fstype;
+ _cleanup_free_ char *chased = NULL;
+ bool rw;
+ int r;
+
+ assert(m);
+ assert(where);
+
+ node = m->decrypted_node ?: m->node;
+ fstype = m->decrypted_fstype ?: m->fstype;
+
+ if (!m->found || !node || !fstype)
+ return 0;
+
+ /* Stacked encryption? Yuck */
+ if (streq_ptr(fstype, "crypto_LUKS"))
+ return -ELOOP;
+
+ rw = m->rw && !(flags & DISSECT_IMAGE_READ_ONLY);
+
+ if (directory) {
+ r = chase_symlinks(directory, where, CHASE_PREFIX_ROOT, &chased);
+ if (r < 0)
+ return r;
+
+ p = chased;
+ } else
+ p = where;
+
+ /* If requested, turn on discard support. */
+ if (STR_IN_SET(fstype, "btrfs", "ext4", "vfat", "xfs") &&
+ ((flags & DISSECT_IMAGE_DISCARD) ||
+ ((flags & DISSECT_IMAGE_DISCARD_ON_LOOP) && is_loop_device(m->node))))
+ options = "discard";
+
+ return mount_verbose(LOG_DEBUG, node, p, fstype, MS_NODEV|(rw ? 0 : MS_RDONLY), options);
+}
+
+int dissected_image_mount(DissectedImage *m, const char *where, DissectImageFlags flags) {
+ int r;
+
+ assert(m);
+ assert(where);
+
+ if (!m->partitions[PARTITION_ROOT].found)
+ return -ENXIO;
+
+ r = mount_partition(m->partitions + PARTITION_ROOT, where, NULL, flags);
+ if (r < 0)
+ return r;
+
+ r = mount_partition(m->partitions + PARTITION_HOME, where, "/home", flags);
+ if (r < 0)
+ return r;
+
+ r = mount_partition(m->partitions + PARTITION_SRV, where, "/srv", flags);
+ if (r < 0)
+ return r;
+
+ if (m->partitions[PARTITION_ESP].found) {
+ const char *mp;
+
+ /* Mount the ESP to /efi if it exists and is empty. If it doesn't exist, use /boot instead. */
+
+ FOREACH_STRING(mp, "/efi", "/boot") {
+ _cleanup_free_ char *p = NULL;
+
+ r = chase_symlinks(mp, where, CHASE_PREFIX_ROOT, &p);
+ if (r < 0)
+ continue;
+
+ r = dir_is_empty(p);
+ if (r > 0) {
+ r = mount_partition(m->partitions + PARTITION_ESP, where, mp, flags);
+ if (r < 0)
+ return r;
+ }
+ }
+ }
+
+ return 0;
+}
+
+#ifdef HAVE_LIBCRYPTSETUP
+typedef struct DecryptedPartition {
+ struct crypt_device *device;
+ char *name;
+ bool relinquished;
+} DecryptedPartition;
+
+struct DecryptedImage {
+ DecryptedPartition *decrypted;
+ size_t n_decrypted;
+ size_t n_allocated;
+};
+#endif
+
+DecryptedImage* decrypted_image_unref(DecryptedImage* d) {
+#ifdef HAVE_LIBCRYPTSETUP
+ size_t i;
+ int r;
+
+ if (!d)
+ return NULL;
+
+ for (i = 0; i < d->n_decrypted; i++) {
+ DecryptedPartition *p = d->decrypted + i;
+
+ if (p->device && p->name && !p->relinquished) {
+ r = crypt_deactivate(p->device, p->name);
+ if (r < 0)
+ log_debug_errno(r, "Failed to deactivate encrypted partition %s", p->name);
+ }
+
+ if (p->device)
+ crypt_free(p->device);
+ free(p->name);
+ }
+
+ free(d);
+#endif
+ return NULL;
+}
+
+#ifdef HAVE_LIBCRYPTSETUP
+
+static int make_dm_name_and_node(const void *original_node, const char *suffix, char **ret_name, char **ret_node) {
+ _cleanup_free_ char *name = NULL, *node = NULL;
+ const char *base;
+
+ assert(original_node);
+ assert(suffix);
+ assert(ret_name);
+ assert(ret_node);
+
+ base = strrchr(original_node, '/');
+ if (!base)
+ return -EINVAL;
+ base++;
+ if (isempty(base))
+ return -EINVAL;
+
+ name = strjoin(base, suffix);
+ if (!name)
+ return -ENOMEM;
+ if (!filename_is_valid(name))
+ return -EINVAL;
+
+ node = strjoin(crypt_get_dir(), "/", name);
+ if (!node)
+ return -ENOMEM;
+
+ *ret_name = name;
+ *ret_node = node;
+
+ name = node = NULL;
+ return 0;
+}
+
+static int decrypt_partition(
+ DissectedPartition *m,
+ const char *passphrase,
+ DissectImageFlags flags,
+ DecryptedImage *d) {
+
+ _cleanup_free_ char *node = NULL, *name = NULL;
+ struct crypt_device *cd;
+ int r;
+
+ assert(m);
+ assert(d);
+
+ if (!m->found || !m->node || !m->fstype)
+ return 0;
+
+ if (!streq(m->fstype, "crypto_LUKS"))
+ return 0;
+
+ r = make_dm_name_and_node(m->node, "-decrypted", &name, &node);
+ if (r < 0)
+ return r;
+
+ if (!GREEDY_REALLOC0(d->decrypted, d->n_allocated, d->n_decrypted + 1))
+ return -ENOMEM;
+
+ r = crypt_init(&cd, m->node);
+ if (r < 0)
+ return r;
+
+ r = crypt_load(cd, CRYPT_LUKS1, NULL);
+ if (r < 0)
+ goto fail;
+
+ r = crypt_activate_by_passphrase(cd, name, CRYPT_ANY_SLOT, passphrase, strlen(passphrase),
+ ((flags & DISSECT_IMAGE_READ_ONLY) ? CRYPT_ACTIVATE_READONLY : 0) |
+ ((flags & DISSECT_IMAGE_DISCARD_ON_CRYPTO) ? CRYPT_ACTIVATE_ALLOW_DISCARDS : 0));
+ if (r == -EPERM) {
+ r = -EKEYREJECTED;
+ goto fail;
+ }
+ if (r < 0)
+ goto fail;
+
+ d->decrypted[d->n_decrypted].name = name;
+ name = NULL;
+
+ d->decrypted[d->n_decrypted].device = cd;
+ d->n_decrypted++;
+
+ m->decrypted_node = node;
+ node = NULL;
+
+ return 0;
+
+fail:
+ crypt_free(cd);
+ return r;
+}
+
+static int verity_partition(
+ DissectedPartition *m,
+ DissectedPartition *v,
+ const void *root_hash,
+ size_t root_hash_size,
+ DissectImageFlags flags,
+ DecryptedImage *d) {
+
+ _cleanup_free_ char *node = NULL, *name = NULL;
+ struct crypt_device *cd;
+ int r;
+
+ assert(m);
+ assert(v);
+
+ if (!root_hash)
+ return 0;
+
+ if (!m->found || !m->node || !m->fstype)
+ return 0;
+ if (!v->found || !v->node || !v->fstype)
+ return 0;
+
+ if (!streq(v->fstype, "DM_verity_hash"))
+ return 0;
+
+ r = make_dm_name_and_node(m->node, "-verity", &name, &node);
+ if (r < 0)
+ return r;
+
+ if (!GREEDY_REALLOC0(d->decrypted, d->n_allocated, d->n_decrypted + 1))
+ return -ENOMEM;
+
+ r = crypt_init(&cd, v->node);
+ if (r < 0)
+ return r;
+
+ r = crypt_load(cd, CRYPT_VERITY, NULL);
+ if (r < 0)
+ goto fail;
+
+ r = crypt_set_data_device(cd, m->node);
+ if (r < 0)
+ goto fail;
+
+ r = crypt_activate_by_volume_key(cd, name, root_hash, root_hash_size, CRYPT_ACTIVATE_READONLY);
+ if (r < 0)
+ goto fail;
+
+ d->decrypted[d->n_decrypted].name = name;
+ name = NULL;
+
+ d->decrypted[d->n_decrypted].device = cd;
+ d->n_decrypted++;
+
+ m->decrypted_node = node;
+ node = NULL;
+
+ return 0;
+
+fail:
+ crypt_free(cd);
+ return r;
+}
+#endif
+
+int dissected_image_decrypt(
+ DissectedImage *m,
+ const char *passphrase,
+ const void *root_hash,
+ size_t root_hash_size,
+ DissectImageFlags flags,
+ DecryptedImage **ret) {
+
+ _cleanup_(decrypted_image_unrefp) DecryptedImage *d = NULL;
+#ifdef HAVE_LIBCRYPTSETUP
+ unsigned i;
+ int r;
+#endif
+
+ assert(m);
+ assert(root_hash || root_hash_size == 0);
+
+ /* Returns:
+ *
+ * = 0 → There was nothing to decrypt
+ * > 0 → Decrypted successfully
+ * -ENOKEY → There's some to decrypt but no key was supplied
+ * -EKEYREJECTED → Passed key was not correct
+ */
+
+ if (root_hash && root_hash_size < sizeof(sd_id128_t))
+ return -EINVAL;
+
+ if (!m->encrypted && !m->verity) {
+ *ret = NULL;
+ return 0;
+ }
+
+#ifdef HAVE_LIBCRYPTSETUP
+ if (m->encrypted && !passphrase)
+ return -ENOKEY;
+
+ d = new0(DecryptedImage, 1);
+ if (!d)
+ return -ENOMEM;
+
+ for (i = 0; i < _PARTITION_DESIGNATOR_MAX; i++) {
+ DissectedPartition *p = m->partitions + i;
+ int k;
+
+ if (!p->found)
+ continue;
+
+ r = decrypt_partition(p, passphrase, flags, d);
+ if (r < 0)
+ return r;
+
+ k = PARTITION_VERITY_OF(i);
+ if (k >= 0) {
+ r = verity_partition(p, m->partitions + k, root_hash, root_hash_size, flags, d);
+ if (r < 0)
+ return r;
+ }
+
+ if (!p->decrypted_fstype && p->decrypted_node) {
+ r = probe_filesystem(p->decrypted_node, &p->decrypted_fstype);
+ if (r < 0)
+ return r;
+ }
+ }
+
+ *ret = d;
+ d = NULL;
+
+ return 1;
+#else
+ return -EOPNOTSUPP;
+#endif
+}
+
+int dissected_image_decrypt_interactively(
+ DissectedImage *m,
+ const char *passphrase,
+ const void *root_hash,
+ size_t root_hash_size,
+ DissectImageFlags flags,
+ DecryptedImage **ret) {
+
+ _cleanup_strv_free_erase_ char **z = NULL;
+ int n = 3, r;
+
+ if (passphrase)
+ n--;
+
+ for (;;) {
+ r = dissected_image_decrypt(m, passphrase, root_hash, root_hash_size, flags, ret);
+ if (r >= 0)
+ return r;
+ if (r == -EKEYREJECTED)
+ log_error_errno(r, "Incorrect passphrase, try again!");
+ else if (r != -ENOKEY) {
+ log_error_errno(r, "Failed to decrypt image: %m");
+ return r;
+ }
+
+ if (--n < 0) {
+ log_error("Too many retries.");
+ return -EKEYREJECTED;
+ }
+
+ z = strv_free(z);
+
+ r = ask_password_auto("Please enter image passphrase!", NULL, "dissect", "dissect", USEC_INFINITY, 0, &z);
+ if (r < 0)
+ return log_error_errno(r, "Failed to query for passphrase: %m");
+
+ passphrase = z[0];
+ }
+}
+
+#ifdef HAVE_LIBCRYPTSETUP
+static int deferred_remove(DecryptedPartition *p) {
+
+ struct dm_ioctl dm = {
+ .version = {
+ DM_VERSION_MAJOR,
+ DM_VERSION_MINOR,
+ DM_VERSION_PATCHLEVEL
+ },
+ .data_size = sizeof(dm),
+ .flags = DM_DEFERRED_REMOVE,
+ };
+
+ _cleanup_close_ int fd = -1;
+
+ assert(p);
+
+ /* Unfortunately, libcryptsetup doesn't provide a proper API for this, hence call the ioctl() directly. */
+
+ fd = open("/dev/mapper/control", O_RDWR|O_CLOEXEC);
+ if (fd < 0)
+ return -errno;
+
+ strncpy(dm.name, p->name, sizeof(dm.name));
+
+ if (ioctl(fd, DM_DEV_REMOVE, &dm))
+ return -errno;
+
+ return 0;
+}
+#endif
+
+int decrypted_image_relinquish(DecryptedImage *d) {
+
+#ifdef HAVE_LIBCRYPTSETUP
+ size_t i;
+ int r;
+#endif
+
+ assert(d);
+
+ /* Turns on automatic removal after the last use ended for all DM devices of this image, and sets a boolean so
+ * that we don't clean it up ourselves either anymore */
+
+#ifdef HAVE_LIBCRYPTSETUP
+ for (i = 0; i < d->n_decrypted; i++) {
+ DecryptedPartition *p = d->decrypted + i;
+
+ if (p->relinquished)
+ continue;
+
+ r = deferred_remove(p);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to mark %s for auto-removal: %m", p->name);
+
+ p->relinquished = true;
+ }
+#endif
+
+ return 0;
+}
+
+int root_hash_load(const char *image, void **ret, size_t *ret_size) {
+ _cleanup_free_ char *text = NULL;
+ _cleanup_free_ void *k = NULL;
+ size_t l;
+ int r;
+
+ assert(image);
+ assert(ret);
+ assert(ret_size);
+
+ if (is_device_path(image)) {
+ /* If we are asked to load the root hash for a device node, exit early */
+ *ret = NULL;
+ *ret_size = 0;
+ return 0;
+ }
+
+ r = getxattr_malloc(image, "user.verity.roothash", &text, true);
+ if (r < 0) {
+ char *fn, *e, *n;
+
+ if (!IN_SET(r, -ENODATA, -EOPNOTSUPP, -ENOENT))
+ return r;
+
+ fn = newa(char, strlen(image) + strlen(".roothash") + 1);
+ n = stpcpy(fn, image);
+ e = endswith(fn, ".raw");
+ if (e)
+ n = e;
+
+ strcpy(n, ".roothash");
+
+ r = read_one_line_file(fn, &text);
+ if (r == -ENOENT) {
+ *ret = NULL;
+ *ret_size = 0;
+ return 0;
+ }
+ if (r < 0)
+ return r;
+ }
+
+ r = unhexmem(text, strlen(text), &k, &l);
+ if (r < 0)
+ return r;
+ if (l < sizeof(sd_id128_t))
+ return -EINVAL;
+
+ *ret = k;
+ *ret_size = l;
+
+ k = NULL;
+
+ return 1;
+}
+
+static const char *const partition_designator_table[] = {
+ [PARTITION_ROOT] = "root",
+ [PARTITION_ROOT_SECONDARY] = "root-secondary",
+ [PARTITION_HOME] = "home",
+ [PARTITION_SRV] = "srv",
+ [PARTITION_ESP] = "esp",
+ [PARTITION_SWAP] = "swap",
+ [PARTITION_ROOT_VERITY] = "root-verity",
+ [PARTITION_ROOT_SECONDARY_VERITY] = "root-secondary-verity",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(partition_designator, int);
diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h
new file mode 100644
index 0000000000..cdb083be6f
--- /dev/null
+++ b/src/shared/dissect-image.h
@@ -0,0 +1,98 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+
+#include "macro.h"
+
+typedef struct DissectedImage DissectedImage;
+typedef struct DissectedPartition DissectedPartition;
+typedef struct DecryptedImage DecryptedImage;
+
+struct DissectedPartition {
+ bool found:1;
+ bool rw:1;
+ int partno; /* -1 if there was no partition and the images contains a file system directly */
+ int architecture; /* Intended architecture: either native, secondary or unset (-1). */
+ sd_id128_t uuid; /* Partition entry UUID as reported by the GPT */
+ char *fstype;
+ char *node;
+ char *decrypted_node;
+ char *decrypted_fstype;
+};
+
+enum {
+ PARTITION_ROOT,
+ PARTITION_ROOT_SECONDARY, /* Secondary architecture */
+ PARTITION_HOME,
+ PARTITION_SRV,
+ PARTITION_ESP,
+ PARTITION_SWAP,
+ PARTITION_ROOT_VERITY, /* verity data for the PARTITION_ROOT partition */
+ PARTITION_ROOT_SECONDARY_VERITY, /* verity data for the PARTITION_ROOT_SECONDARY partition */
+ _PARTITION_DESIGNATOR_MAX,
+ _PARTITION_DESIGNATOR_INVALID = -1
+};
+
+static inline int PARTITION_VERITY_OF(int p) {
+ if (p == PARTITION_ROOT)
+ return PARTITION_ROOT_VERITY;
+ if (p == PARTITION_ROOT_SECONDARY)
+ return PARTITION_ROOT_SECONDARY_VERITY;
+ return _PARTITION_DESIGNATOR_INVALID;
+}
+
+typedef enum DissectImageFlags {
+ DISSECT_IMAGE_READ_ONLY = 1,
+ DISSECT_IMAGE_DISCARD_ON_LOOP = 2, /* Turn on "discard" if on a loop device and file system supports it */
+ DISSECT_IMAGE_DISCARD = 4, /* Turn on "discard" if file system supports it, on all block devices */
+ DISSECT_IMAGE_DISCARD_ON_CRYPTO = 8, /* Turn on "discard" also on crypto devices */
+ DISSECT_IMAGE_DISCARD_ANY = DISSECT_IMAGE_DISCARD_ON_LOOP |
+ DISSECT_IMAGE_DISCARD |
+ DISSECT_IMAGE_DISCARD_ON_CRYPTO,
+ DISSECT_IMAGE_GPT_ONLY = 16, /* Only recognize images with GPT partition tables */
+ DISSECT_IMAGE_REQUIRE_ROOT = 32, /* Don't accept disks without root partition */
+} DissectImageFlags;
+
+struct DissectedImage {
+ bool encrypted:1;
+ bool verity:1; /* verity available and usable */
+ bool can_verity:1; /* verity available, but not necessarily used */
+ DissectedPartition partitions[_PARTITION_DESIGNATOR_MAX];
+};
+
+int dissect_image(int fd, const void *root_hash, size_t root_hash_size, DissectImageFlags flags, DissectedImage **ret);
+
+DissectedImage* dissected_image_unref(DissectedImage *m);
+DEFINE_TRIVIAL_CLEANUP_FUNC(DissectedImage*, dissected_image_unref);
+
+int dissected_image_decrypt(DissectedImage *m, const char *passphrase, const void *root_hash, size_t root_hash_size, DissectImageFlags flags, DecryptedImage **ret);
+int dissected_image_decrypt_interactively(DissectedImage *m, const char *passphrase, const void *root_hash, size_t root_hash_size, DissectImageFlags flags, DecryptedImage **ret);
+int dissected_image_mount(DissectedImage *m, const char *dest, DissectImageFlags flags);
+
+DecryptedImage* decrypted_image_unref(DecryptedImage *p);
+DEFINE_TRIVIAL_CLEANUP_FUNC(DecryptedImage*, decrypted_image_unref);
+int decrypted_image_relinquish(DecryptedImage *d);
+
+const char* partition_designator_to_string(int i) _const_;
+int partition_designator_from_string(const char *name) _pure_;
+
+int root_hash_load(const char *image, void **ret, size_t *ret_size);
diff --git a/src/shared/dns-domain.c b/src/shared/dns-domain.c
index 892f0aadf5..33debadb15 100644
--- a/src/shared/dns-domain.c
+++ b/src/shared/dns-domain.c
@@ -1076,7 +1076,7 @@ int dns_service_split(const char *joined, char **_name, char **_type, char **_do
if (!name)
return -ENOMEM;
- type = strjoin(b, ".", c, NULL);
+ type = strjoin(b, ".", c);
if (!type)
return -ENOMEM;
@@ -1090,7 +1090,7 @@ int dns_service_split(const char *joined, char **_name, char **_type, char **_do
name = NULL;
- type = strjoin(a, ".", b, NULL);
+ type = strjoin(a, ".", b);
if (!type)
return -ENOMEM;
@@ -1324,3 +1324,15 @@ int dns_name_apply_idna(const char *name, char **ret) {
return (int) n;
}
+
+int dns_name_is_valid_or_address(const char *name) {
+ /* Returns > 0 if the specified name is either a valid IP address formatted as string or a valid DNS name */
+
+ if (isempty(name))
+ return 0;
+
+ if (in_addr_from_string_auto(name, NULL, NULL) >= 0)
+ return 1;
+
+ return dns_name_is_valid(name);
+}
diff --git a/src/shared/dns-domain.h b/src/shared/dns-domain.h
index af780f0b8b..03f160369c 100644
--- a/src/shared/dns-domain.h
+++ b/src/shared/dns-domain.h
@@ -107,3 +107,5 @@ int dns_name_equal_skip(const char *a, unsigned n_labels, const char *b);
int dns_name_common_suffix(const char *a, const char *b, const char **ret);
int dns_name_apply_idna(const char *name, char **ret);
+
+int dns_name_is_valid_or_address(const char *name);
diff --git a/src/shared/dropin.c b/src/shared/dropin.c
index b9cd952ac8..15ccd1b6ca 100644
--- a/src/shared/dropin.c
+++ b/src/shared/dropin.c
@@ -17,7 +17,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <dirent.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
@@ -25,10 +24,12 @@
#include "alloc-util.h"
#include "conf-files.h"
+#include "dirent-util.h"
#include "dropin.h"
#include "escape.h"
#include "fd-util.h"
#include "fileio-label.h"
+#include "fs-util.h"
#include "hashmap.h"
#include "log.h"
#include "macro.h"
@@ -42,11 +43,10 @@
int drop_in_file(const char *dir, const char *unit, unsigned level,
const char *name, char **_p, char **_q) {
+ char prefix[DECIMAL_STR_MAX(unsigned)];
_cleanup_free_ char *b = NULL;
char *p, *q;
- char prefix[DECIMAL_STR_MAX(unsigned)];
-
assert(unit);
assert(name);
assert(_p);
@@ -61,11 +61,11 @@ int drop_in_file(const char *dir, const char *unit, unsigned level,
if (!filename_is_valid(b))
return -EINVAL;
- p = strjoin(dir, "/", unit, ".d", NULL);
+ p = strjoin(dir, "/", unit, ".d");
if (!p)
return -ENOMEM;
- q = strjoin(p, "/", prefix, "-", b, ".conf", NULL);
+ q = strjoin(p, "/", prefix, "-", b, ".conf");
if (!q) {
free(p);
return -ENOMEM;
@@ -116,136 +116,99 @@ int write_drop_in_format(const char *dir, const char *unit, unsigned level,
return write_drop_in(dir, unit, level, name, p);
}
-static int iterate_dir(
+static int unit_file_find_dir(
+ const char *original_root,
const char *path,
- UnitDependency dependency,
- dependency_consumer_t consumer,
- void *arg,
- char ***strv) {
+ char ***dirs) {
- _cleanup_closedir_ DIR *d = NULL;
+ _cleanup_free_ char *chased = NULL;
int r;
assert(path);
- /* The config directories are special, since the order of the
- * drop-ins matters */
- if (dependency < 0) {
- r = strv_extend(strv, path);
- if (r < 0)
- return log_oom();
-
+ r = chase_symlinks(path, original_root, 0, &chased);
+ if (r == -ENOENT) /* Ignore -ENOENT, after all most units won't have a drop-in dir */
return 0;
- }
-
- assert(consumer);
-
- d = opendir(path);
- if (!d) {
- if (errno == ENOENT)
- return 0;
-
- return log_error_errno(errno, "Failed to open directory %s: %m", path);
- }
-
- for (;;) {
- struct dirent *de;
- _cleanup_free_ char *f = NULL;
-
- errno = 0;
- de = readdir(d);
- if (!de && errno > 0)
- return log_error_errno(errno, "Failed to read directory %s: %m", path);
-
- if (!de)
- break;
-
- if (hidden_or_backup_file(de->d_name))
- continue;
-
- f = strjoin(path, "/", de->d_name, NULL);
- if (!f)
- return log_oom();
+ if (r < 0)
+ return log_full_errno(LOG_WARNING, r, "Failed to canonicalize path %s: %m", path);
- r = consumer(dependency, de->d_name, f, arg);
- if (r < 0)
- return r;
- }
+ r = strv_push(dirs, chased);
+ if (r < 0)
+ return log_oom();
+ chased = NULL;
return 0;
}
-int unit_file_process_dir(
+static int unit_file_find_dirs(
+ const char *original_root,
Set *unit_path_cache,
const char *unit_path,
const char *name,
const char *suffix,
- UnitDependency dependency,
- dependency_consumer_t consumer,
- void *arg,
- char ***strv) {
+ char ***dirs) {
- _cleanup_free_ char *path = NULL;
+ char *path;
int r;
assert(unit_path);
assert(name);
assert(suffix);
- path = strjoin(unit_path, "/", name, suffix, NULL);
- if (!path)
- return log_oom();
+ path = strjoina(unit_path, "/", name, suffix);
- if (!unit_path_cache || set_get(unit_path_cache, path))
- (void) iterate_dir(path, dependency, consumer, arg, strv);
+ if (!unit_path_cache || set_get(unit_path_cache, path)) {
+ r = unit_file_find_dir(original_root, path, dirs);
+ if (r < 0)
+ return r;
+ }
if (unit_name_is_valid(name, UNIT_NAME_INSTANCE)) {
- _cleanup_free_ char *template = NULL, *p = NULL;
/* Also try the template dir */
+ _cleanup_free_ char *template = NULL;
+
r = unit_name_template(name, &template);
if (r < 0)
return log_error_errno(r, "Failed to generate template from unit name: %m");
- p = strjoin(unit_path, "/", template, suffix, NULL);
- if (!p)
- return log_oom();
-
- if (!unit_path_cache || set_get(unit_path_cache, p))
- (void) iterate_dir(p, dependency, consumer, arg, strv);
+ return unit_file_find_dirs(original_root, unit_path_cache, unit_path, template, suffix, dirs);
}
return 0;
}
int unit_file_find_dropin_paths(
+ const char *original_root,
char **lookup_path,
Set *unit_path_cache,
+ const char *dir_suffix,
+ const char *file_suffix,
Set *names,
- char ***paths) {
+ char ***ret) {
- _cleanup_strv_free_ char **strv = NULL, **ans = NULL;
+ _cleanup_strv_free_ char **dirs = NULL, **ans = NULL;
Iterator i;
- char *t;
+ char *t, **p;
int r;
- assert(paths);
-
- SET_FOREACH(t, names, i) {
- char **p;
+ assert(ret);
+ SET_FOREACH(t, names, i)
STRV_FOREACH(p, lookup_path)
- unit_file_process_dir(unit_path_cache, *p, t, ".d", _UNIT_DEPENDENCY_INVALID, NULL, NULL, &strv);
- }
+ unit_file_find_dirs(original_root, unit_path_cache, *p, t, dir_suffix, &dirs);
- if (strv_isempty(strv))
+ if (strv_isempty(dirs)) {
+ *ret = NULL;
return 0;
+ }
- r = conf_files_list_strv(&ans, ".conf", NULL, (const char**) strv);
+ r = conf_files_list_strv(&ans, file_suffix, NULL, (const char**) dirs);
if (r < 0)
- return log_warning_errno(r, "Failed to get list of configuration files: %m");
+ return log_warning_errno(r, "Failed to sort the list of configuration files: %m");
- *paths = ans;
+ *ret = ans;
ans = NULL;
+
return 1;
}
diff --git a/src/shared/dropin.h b/src/shared/dropin.h
index c1936f397b..a2b8cdce61 100644
--- a/src/shared/dropin.h
+++ b/src/shared/dropin.h
@@ -33,29 +33,24 @@ int write_drop_in(const char *dir, const char *unit, unsigned level,
int write_drop_in_format(const char *dir, const char *unit, unsigned level,
const char *name, const char *format, ...) _printf_(5, 6);
-/**
- * This callback will be called for each directory entry @entry,
- * with @filepath being the full path to the entry.
- *
- * If return value is negative, loop will be aborted.
- */
-typedef int (*dependency_consumer_t)(UnitDependency dependency,
- const char *entry,
- const char* filepath,
- void *arg);
-
-int unit_file_process_dir(
- Set * unit_path_cache,
- const char *unit_path,
- const char *name,
- const char *suffix,
- UnitDependency dependency,
- dependency_consumer_t consumer,
- void *arg,
- char ***strv);
-
int unit_file_find_dropin_paths(
+ const char *original_root,
char **lookup_path,
Set *unit_path_cache,
+ const char *dir_suffix,
+ const char *file_suffix,
Set *names,
char ***paths);
+
+static inline int unit_file_find_dropin_conf_paths(
+ const char *original_root,
+ char **lookup_path,
+ Set *unit_path_cache,
+ Set *names,
+ char ***paths) {
+ return unit_file_find_dropin_paths(original_root,
+ lookup_path,
+ unit_path_cache,
+ ".d", ".conf",
+ names, paths);
+}
diff --git a/src/shared/fdset.c b/src/shared/fdset.c
index 527f27bc67..090f3fdcdd 100644
--- a/src/shared/fdset.c
+++ b/src/shared/fdset.c
@@ -18,13 +18,13 @@
***/
#include <alloca.h>
-#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stddef.h>
#include "sd-daemon.h"
+#include "dirent-util.h"
#include "fd-util.h"
#include "fdset.h"
#include "log.h"
@@ -148,12 +148,9 @@ int fdset_new_fill(FDSet **_s) {
goto finish;
}
- while ((de = readdir(d))) {
+ FOREACH_DIRENT(de, d, return -errno) {
int fd = -1;
- if (hidden_or_backup_file(de->d_name))
- continue;
-
r = safe_atoi(de->d_name, &fd);
if (r < 0)
goto finish;
diff --git a/src/shared/firewall-util.c b/src/shared/firewall-util.c
index f73108eaa3..952fc48c45 100644
--- a/src/shared/firewall-util.c
+++ b/src/shared/firewall-util.c
@@ -17,8 +17,9 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#warning "Temporary work-around for broken glibc vs. linux kernel header definitions"
-#warning "This really should be removed sooner rather than later, when this is fixed upstream"
+/* Temporary work-around for broken glibc vs. linux kernel header definitions
+ * This is already fixed upstream, remove this when distributions have updated.
+ */
#define _NET_IF_H 1
#include <alloca.h>
@@ -75,8 +76,11 @@ static int entry_fill_basics(
}
if (out_interface) {
+ size_t l = strlen(out_interface);
+ assert(l < sizeof entry->ip.outiface && l < sizeof entry->ip.outiface_mask);
+
strcpy(entry->ip.outiface, out_interface);
- memset(entry->ip.outiface_mask, 0xFF, strlen(out_interface)+1);
+ memset(entry->ip.outiface_mask, 0xFF, l + 1);
}
if (destination) {
entry->ip.dst = destination->in;
diff --git a/src/shared/fstab-util.c b/src/shared/fstab-util.c
index a4e0cd3267..c3106f1ae9 100644
--- a/src/shared/fstab-util.c
+++ b/src/shared/fstab-util.c
@@ -38,7 +38,7 @@ bool fstab_is_mount_point(const char *mount) {
_cleanup_endmntent_ FILE *f = NULL;
struct mntent *m;
- f = setmntent("/etc/fstab", "r");
+ f = setmntent("/etc/fstab", "re");
if (!f)
return false;
@@ -213,7 +213,7 @@ static char *unquote(const char *s, const char* quotes) {
* trailing quotes if there is one. Doesn't care about
* escaping or anything.
*
- * DON'T USE THIS FOR NEW CODE ANYMORE!*/
+ * DON'T USE THIS FOR NEW CODE ANYMORE! */
l = strlen(s);
if (l < 2)
@@ -241,7 +241,7 @@ static char *tag_to_udev_node(const char *tagvalue, const char *by) {
if (encode_devnode_name(u, t, enc_len) < 0)
return NULL;
- return strjoin("/dev/disk/by-", by, "/", t, NULL);
+ return strjoin("/dev/disk/by-", by, "/", t);
}
char *fstab_node_to_udev_node(const char *p) {
diff --git a/src/shared/generator.c b/src/shared/generator.c
index 70afc6a285..9a069b2f97 100644
--- a/src/shared/generator.c
+++ b/src/shared/generator.c
@@ -65,7 +65,7 @@ static int write_fsck_sysroot_service(const char *dir, const char *what) {
"Description=File System Check on %2$s\n"
"DefaultDependencies=no\n"
"BindsTo=%3$s\n"
- "After=initrd-root-device.target local-fs-pre.target\n"
+ "After=initrd-root-device.target local-fs-pre.target %3$s\n"
"Before=shutdown.target\n"
"\n"
"[Service]\n"
diff --git a/src/shared/gpt.h b/src/shared/gpt.h
index 55b41bbcd8..cc752006fa 100644
--- a/src/shared/gpt.h
+++ b/src/shared/gpt.h
@@ -32,30 +32,47 @@
#define GPT_ROOT_ARM SD_ID128_MAKE(69,da,d7,10,2c,e4,4e,3c,b1,6c,21,a1,d4,9a,be,d3)
#define GPT_ROOT_ARM_64 SD_ID128_MAKE(b9,21,b0,45,1d,f0,41,c3,af,44,4c,6f,28,0d,3f,ae)
#define GPT_ROOT_IA64 SD_ID128_MAKE(99,3d,8d,3d,f8,0e,42,25,85,5a,9d,af,8e,d7,ea,97)
-
#define GPT_ESP SD_ID128_MAKE(c1,2a,73,28,f8,1f,11,d2,ba,4b,00,a0,c9,3e,c9,3b)
#define GPT_SWAP SD_ID128_MAKE(06,57,fd,6d,a4,ab,43,c4,84,e5,09,33,c8,4b,4f,4f)
#define GPT_HOME SD_ID128_MAKE(93,3a,c7,e1,2e,b4,4f,13,b8,44,0e,14,e2,ae,f9,15)
#define GPT_SRV SD_ID128_MAKE(3b,8f,84,25,20,e0,4f,3b,90,7f,1a,25,a7,6f,98,e8)
+/* Verity partitions for the root partitions above (we only define them for the root partitions, because only they are
+ * are commonly read-only and hence suitable for verity). */
+#define GPT_ROOT_X86_VERITY SD_ID128_MAKE(d1,3c,5d,3b,b5,d1,42,2a,b2,9f,94,54,fd,c8,9d,76)
+#define GPT_ROOT_X86_64_VERITY SD_ID128_MAKE(2c,73,57,ed,eb,d2,46,d9,ae,c1,23,d4,37,ec,2b,f5)
+#define GPT_ROOT_ARM_VERITY SD_ID128_MAKE(73,86,cd,f2,20,3c,47,a9,a4,98,f2,ec,ce,45,a2,d6)
+#define GPT_ROOT_ARM_64_VERITY SD_ID128_MAKE(df,33,00,ce,d6,9f,4c,92,97,8c,9b,fb,0f,38,d8,20)
+#define GPT_ROOT_IA64_VERITY SD_ID128_MAKE(86,ed,10,d5,b6,07,45,bb,89,57,d3,50,f2,3d,05,71)
+
+
#if defined(__x86_64__)
# define GPT_ROOT_NATIVE GPT_ROOT_X86_64
# define GPT_ROOT_SECONDARY GPT_ROOT_X86
+# define GPT_ROOT_NATIVE_VERITY GPT_ROOT_X86_64_VERITY
+# define GPT_ROOT_SECONDARY_VERITY GPT_ROOT_X86_VERITY
#elif defined(__i386__)
# define GPT_ROOT_NATIVE GPT_ROOT_X86
+# define GPT_ROOT_NATIVE_VERITY GPT_ROOT_X86_VERITY
#endif
#if defined(__ia64__)
# define GPT_ROOT_NATIVE GPT_ROOT_IA64
+# define GPT_ROOT_NATIVE_VERITY GPT_ROOT_IA64_VERITY
#endif
#if defined(__aarch64__) && (__BYTE_ORDER != __BIG_ENDIAN)
# define GPT_ROOT_NATIVE GPT_ROOT_ARM_64
# define GPT_ROOT_SECONDARY GPT_ROOT_ARM
+# define GPT_ROOT_NATIVE_VERITY GPT_ROOT_ARM_64_VERITY
+# define GPT_ROOT_SECONDARY_VERITY GPT_ROOT_ARM_VERITY
#elif defined(__arm__) && (__BYTE_ORDER != __BIG_ENDIAN)
# define GPT_ROOT_NATIVE GPT_ROOT_ARM
+# define GPT_ROOT_NATIVE_VERITY GPT_ROOT_ARM_VERITY
#endif
+#define GPT_FLAG_NO_BLOCK_IO_PROTOCOL (1ULL << 1)
+
/* Flags we recognize on the root, swap, home and srv partitions when
* doing auto-discovery. These happen to be identical to what
* Microsoft defines for its own Basic Data Partitions, but that's
diff --git a/src/shared/install-printf.c b/src/shared/install-printf.c
index cbdf66827f..c10ed3d311 100644
--- a/src/shared/install-printf.c
+++ b/src/shared/install-printf.c
@@ -22,7 +22,7 @@
#include <string.h>
#include <unistd.h>
-#include "formats-util.h"
+#include "format-util.h"
#include "install-printf.h"
#include "install.h"
#include "macro.h"
@@ -45,7 +45,7 @@ static int specifier_prefix_and_instance(char specifier, void *data, void *userd
if (endswith(prefix, "@") && i->default_instance) {
char *ans;
- ans = strjoin(prefix, i->default_instance, NULL);
+ ans = strjoin(prefix, i->default_instance);
if (!ans)
return -ENOMEM;
*ret = ans;
@@ -93,9 +93,9 @@ static int specifier_instance(char specifier, void *data, void *userdata, char *
return r;
if (isempty(instance)) {
- instance = strdup(i->default_instance ?: "");
- if (!instance)
- return -ENOMEM;
+ r = free_and_strdup(&instance, i->default_instance ?: "");
+ if (r < 0)
+ return r;
}
*ret = instance;
diff --git a/src/shared/install.c b/src/shared/install.c
index 96fba6e25b..58c8e852b2 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -208,7 +208,7 @@ static int path_is_control(const LookupPaths *p, const char *path) {
path_equal_ptr(parent, p->runtime_control);
}
-static int path_is_config(const LookupPaths *p, const char *path) {
+static int path_is_config(const LookupPaths *p, const char *path, bool check_parent) {
_cleanup_free_ char *parent = NULL;
assert(p);
@@ -217,15 +217,19 @@ static int path_is_config(const LookupPaths *p, const char *path) {
/* Note that we do *not* have generic checks for /etc or /run in place, since with
* them we couldn't discern configuration from transient or generated units */
- parent = dirname_malloc(path);
- if (!parent)
- return -ENOMEM;
+ if (check_parent) {
+ parent = dirname_malloc(path);
+ if (!parent)
+ return -ENOMEM;
+
+ path = parent;
+ }
- return path_equal_ptr(parent, p->persistent_config) ||
- path_equal_ptr(parent, p->runtime_config);
+ return path_equal_ptr(path, p->persistent_config) ||
+ path_equal_ptr(path, p->runtime_config);
}
-static int path_is_runtime(const LookupPaths *p, const char *path) {
+static int path_is_runtime(const LookupPaths *p, const char *path, bool check_parent) {
_cleanup_free_ char *parent = NULL;
const char *rpath;
@@ -239,16 +243,20 @@ static int path_is_runtime(const LookupPaths *p, const char *path) {
if (rpath && path_startswith(rpath, "/run"))
return true;
- parent = dirname_malloc(path);
- if (!parent)
- return -ENOMEM;
+ if (check_parent) {
+ parent = dirname_malloc(path);
+ if (!parent)
+ return -ENOMEM;
- return path_equal_ptr(parent, p->runtime_config) ||
- path_equal_ptr(parent, p->generator) ||
- path_equal_ptr(parent, p->generator_early) ||
- path_equal_ptr(parent, p->generator_late) ||
- path_equal_ptr(parent, p->transient) ||
- path_equal_ptr(parent, p->runtime_control);
+ path = parent;
+ }
+
+ return path_equal_ptr(path, p->runtime_config) ||
+ path_equal_ptr(path, p->generator) ||
+ path_equal_ptr(path, p->generator_early) ||
+ path_equal_ptr(path, p->generator_late) ||
+ path_equal_ptr(path, p->transient) ||
+ path_equal_ptr(path, p->runtime_control);
}
static int path_is_vendor(const LookupPaths *p, const char *path) {
@@ -381,6 +389,12 @@ void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *chang
verb, changes[i].path);
logged = true;
break;
+
+ case -ENOENT:
+ log_error_errno(changes[i].type, "Failed to %s unit, unit %s does not exist.", verb, changes[i].path);
+ logged = true;
+ break;
+
default:
assert(changes[i].type < 0);
log_error_errno(changes[i].type, "Failed to %s unit, file %s: %m.",
@@ -677,7 +691,6 @@ static int find_symlinks_fd(
int fd,
const char *path,
const char *config_path,
- const LookupPaths *lp,
bool *same_name_link) {
_cleanup_closedir_ DIR *d = NULL;
@@ -688,7 +701,6 @@ static int find_symlinks_fd(
assert(fd >= 0);
assert(path);
assert(config_path);
- assert(lp);
assert(same_name_link);
d = fdopendir(fd);
@@ -722,7 +734,7 @@ static int find_symlinks_fd(
}
/* This will close nfd, regardless whether it succeeds or not */
- q = find_symlinks_fd(root_dir, name, nfd, p, config_path, lp, same_name_link);
+ q = find_symlinks_fd(root_dir, name, nfd, p, config_path, same_name_link);
if (q > 0)
return 1;
if (r == 0)
@@ -800,7 +812,6 @@ static int find_symlinks(
const char *root_dir,
const char *name,
const char *config_path,
- const LookupPaths *lp,
bool *same_name_link) {
int fd;
@@ -817,44 +828,82 @@ static int find_symlinks(
}
/* This takes possession of fd and closes it */
- return find_symlinks_fd(root_dir, name, fd, config_path, config_path, lp, same_name_link);
+ return find_symlinks_fd(root_dir, name, fd, config_path, config_path, same_name_link);
}
static int find_symlinks_in_scope(
- UnitFileScope scope,
const LookupPaths *paths,
const char *name,
UnitFileState *state) {
- bool same_name_link_runtime = false, same_name_link = false;
+ bool same_name_link_runtime = false, same_name_link_config = false;
+ bool enabled_in_runtime = false, enabled_at_all = false;
+ char **p;
int r;
- assert(scope >= 0);
- assert(scope < _UNIT_FILE_SCOPE_MAX);
assert(paths);
assert(name);
- /* First look in the persistent config path */
- r = find_symlinks(paths->root_dir, name, paths->persistent_config, paths, &same_name_link);
- if (r < 0)
- return r;
- if (r > 0) {
- *state = UNIT_FILE_ENABLED;
- return r;
+ STRV_FOREACH(p, paths->search_path) {
+ bool same_name_link = false;
+
+ r = find_symlinks(paths->root_dir, name, *p, &same_name_link);
+ if (r < 0)
+ return r;
+ if (r > 0) {
+ /* We found symlinks in this dir? Yay! Let's see where precisely it is enabled. */
+
+ r = path_is_config(paths, *p, false);
+ if (r < 0)
+ return r;
+ if (r > 0) {
+ /* This is the best outcome, let's return it immediately. */
+ *state = UNIT_FILE_ENABLED;
+ return 1;
+ }
+
+ r = path_is_runtime(paths, *p, false);
+ if (r < 0)
+ return r;
+ if (r > 0)
+ enabled_in_runtime = true;
+ else
+ enabled_at_all = true;
+
+ } else if (same_name_link) {
+
+ r = path_is_config(paths, *p, false);
+ if (r < 0)
+ return r;
+ if (r > 0)
+ same_name_link_config = true;
+ else {
+ r = path_is_runtime(paths, *p, false);
+ if (r < 0)
+ return r;
+ if (r > 0)
+ same_name_link_runtime = true;
+ }
+ }
}
- /* Then look in runtime config path */
- r = find_symlinks(paths->root_dir, name, paths->runtime_config, paths, &same_name_link_runtime);
- if (r < 0)
- return r;
- if (r > 0) {
+ if (enabled_in_runtime) {
*state = UNIT_FILE_ENABLED_RUNTIME;
- return r;
+ return 1;
+ }
+
+ /* Here's a special rule: if the unit we are looking for is an instance, and it symlinked in the search path
+ * outside of runtime and configuration directory, then we consider it statically enabled. Note we do that only
+ * for instance, not for regular names, as those are merely aliases, while instances explicitly instantiate
+ * something, and hence are a much stronger concept. */
+ if (enabled_at_all && unit_name_is_valid(name, UNIT_NAME_INSTANCE)) {
+ *state = UNIT_FILE_STATIC;
+ return 1;
}
/* Hmm, we didn't find it, but maybe we found the same name
* link? */
- if (same_name_link) {
+ if (same_name_link_config) {
*state = UNIT_FILE_LINKED;
return 1;
}
@@ -1307,7 +1356,7 @@ static int unit_file_search(
STRV_FOREACH(p, paths->search_path) {
_cleanup_free_ char *path = NULL;
- path = strjoin(*p, "/", info->name, NULL);
+ path = strjoin(*p, "/", info->name);
if (!path)
return -ENOMEM;
@@ -1332,7 +1381,7 @@ static int unit_file_search(
STRV_FOREACH(p, paths->search_path) {
_cleanup_free_ char *path = NULL;
- path = strjoin(*p, "/", template, NULL);
+ path = strjoin(*p, "/", template);
if (!path)
return -ENOMEM;
@@ -1354,7 +1403,8 @@ static int install_info_follow(
InstallContext *c,
UnitFileInstallInfo *i,
const char *root_dir,
- SearchFlags flags) {
+ SearchFlags flags,
+ bool ignore_different_name) {
assert(c);
assert(i);
@@ -1367,7 +1417,7 @@ static int install_info_follow(
/* If the basename doesn't match, the caller should add a
* complete new entry for this. */
- if (!streq(basename(i->symlink_target), i->name))
+ if (!ignore_different_name && !streq(basename(i->symlink_target), i->name))
return -EXDEV;
free_and_replace(i->path, i->symlink_target);
@@ -1408,14 +1458,14 @@ static int install_info_traverse(
return -ELOOP;
if (!(flags & SEARCH_FOLLOW_CONFIG_SYMLINKS)) {
- r = path_is_config(paths, i->path);
+ r = path_is_config(paths, i->path, true);
if (r < 0)
return r;
if (r > 0)
return -ELOOP;
}
- r = install_info_follow(c, i, paths->root_dir, flags);
+ r = install_info_follow(c, i, paths->root_dir, flags, false);
if (r == -EXDEV) {
_cleanup_free_ char *buffer = NULL;
const char *bn;
@@ -1439,6 +1489,18 @@ static int install_info_traverse(
if (r < 0)
return r;
+ if (streq(buffer, i->name)) {
+
+ /* We filled in the instance, and the target stayed the same? If so, then let's
+ * honour the link as it is. */
+
+ r = install_info_follow(c, i, paths->root_dir, flags, true);
+ if (r < 0)
+ return r;
+
+ continue;
+ }
+
bn = buffer;
}
@@ -1567,18 +1629,12 @@ static int install_info_symlink_wants(
if (strv_isempty(list))
return 0;
- if (unit_name_is_valid(i->name, UNIT_NAME_TEMPLATE)) {
+ if (unit_name_is_valid(i->name, UNIT_NAME_TEMPLATE) && i->default_instance) {
UnitFileInstallInfo instance = {
.type = _UNIT_FILE_TYPE_INVALID,
};
_cleanup_free_ char *path = NULL;
- /* Don't install any symlink if there's no default
- * instance configured */
-
- if (!i->default_instance)
- return 0;
-
r = unit_name_replace_instance(i->name, i->default_instance, &buf);
if (r < 0)
return r;
@@ -1612,7 +1668,7 @@ static int install_info_symlink_wants(
continue;
}
- path = strjoin(config_path, "/", dst, suffix, n, NULL);
+ path = strjoin(config_path, "/", dst, suffix, n);
if (!path)
return -ENOMEM;
@@ -1646,7 +1702,7 @@ static int install_info_symlink_link(
if (r > 0)
return 0;
- path = strjoin(config_path, "/", i->name, NULL);
+ path = strjoin(config_path, "/", i->name);
if (!path)
return -ENOMEM;
@@ -1757,7 +1813,9 @@ static int install_context_mark_for_removal(
InstallContext *c,
const LookupPaths *paths,
Set **remove_symlinks_to,
- const char *config_path) {
+ const char *config_path,
+ UnitFileChange **changes,
+ unsigned *n_changes) {
UnitFileInstallInfo *i;
int r;
@@ -1783,19 +1841,26 @@ static int install_context_mark_for_removal(
r = install_info_traverse(scope, c, paths, i, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, NULL);
if (r == -ENOLINK) {
- log_debug_errno(r, "Name %s leads to a dangling symlink, ignoring.", i->name);
- continue;
- } else if (r == -ENOENT && i->auxiliary) {
- /* some unit specified in Also= or similar is missing */
- log_debug_errno(r, "Auxiliary unit %s not found, ignoring.", i->name);
- continue;
- } else if (r < 0)
- return log_debug_errno(r, "Failed to find unit %s: %m", i->name);
+ log_debug_errno(r, "Name %s leads to a dangling symlink, removing name.", i->name);
+ unit_file_changes_add(changes, n_changes, UNIT_FILE_IS_DANGLING, i->path ?: i->name, NULL);
+ } else if (r == -ENOENT) {
+
+ if (i->auxiliary) /* some unit specified in Also= or similar is missing */
+ log_debug_errno(r, "Auxiliary unit of %s not found, removing name.", i->name);
+ else {
+ log_debug_errno(r, "Unit %s not found, removing name.", i->name);
+ unit_file_changes_add(changes, n_changes, r, i->path ?: i->name, NULL);
+ }
- if (i->type != UNIT_FILE_TYPE_REGULAR) {
- log_debug("Unit %s has type %s, ignoring.",
- i->name,
- unit_file_type_to_string(i->type) ?: "invalid");
+ } else if (r < 0) {
+ log_debug_errno(r, "Failed to find unit %s, removing name: %m", i->name);
+ unit_file_changes_add(changes, n_changes, r, i->path ?: i->name, NULL);
+ } else if (i->type == UNIT_FILE_TYPE_MASKED) {
+ log_debug("Unit file %s is masked, ignoring.", i->name);
+ unit_file_changes_add(changes, n_changes, UNIT_FILE_IS_MASKED, i->path ?: i->name, NULL);
+ continue;
+ } else if (i->type != UNIT_FILE_TYPE_REGULAR) {
+ log_debug("Unit %s has type %s, ignoring.", i->name, unit_file_type_to_string(i->type) ?: "invalid");
continue;
}
@@ -1828,6 +1893,8 @@ int unit_file_mask(
return r;
config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
+ if (!config_path)
+ return -ENXIO;
STRV_FOREACH(i, files) {
_cleanup_free_ char *path = NULL;
@@ -1861,7 +1928,7 @@ int unit_file_unmask(
_cleanup_lookup_paths_free_ LookupPaths paths = {};
_cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
- _cleanup_free_ char **todo = NULL;
+ _cleanup_strv_free_ char **todo = NULL;
size_t n_todo = 0, n_allocated = 0;
const char *config_path;
char **i;
@@ -1876,6 +1943,9 @@ int unit_file_unmask(
return r;
config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
+ if (!config_path)
+ return -ENXIO;
+
dry_run = !!(flags & UNIT_FILE_DRY_RUN);
STRV_FOREACH(i, files) {
@@ -1899,7 +1969,11 @@ int unit_file_unmask(
if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2))
return -ENOMEM;
- todo[n_todo++] = *i;
+ todo[n_todo] = strdup(*i);
+ if (!todo[n_todo])
+ return -ENOMEM;
+
+ n_todo++;
}
strv_uniq(todo);
@@ -1947,7 +2021,7 @@ int unit_file_link(
unsigned *n_changes) {
_cleanup_lookup_paths_free_ LookupPaths paths = {};
- _cleanup_free_ char **todo = NULL;
+ _cleanup_strv_free_ char **todo = NULL;
size_t n_todo = 0, n_allocated = 0;
const char *config_path;
char **i;
@@ -1961,6 +2035,8 @@ int unit_file_link(
return r;
config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
+ if (!config_path)
+ return -ENXIO;
STRV_FOREACH(i, files) {
_cleanup_free_ char *full = NULL;
@@ -1996,7 +2072,11 @@ int unit_file_link(
if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2))
return -ENOMEM;
- todo[n_todo++] = *i;
+ todo[n_todo] = strdup(*i);
+ if (!todo[n_todo])
+ return -ENOMEM;
+
+ n_todo++;
}
strv_uniq(todo);
@@ -2025,7 +2105,7 @@ static int path_shall_revert(const LookupPaths *paths, const char *path) {
/* Checks whether the path is one where the drop-in directories shall be removed. */
- r = path_is_config(paths, path);
+ r = path_is_config(paths, path, true);
if (r != 0)
return r;
@@ -2133,7 +2213,7 @@ int unit_file_revert(
if (errno != ENOENT)
return -errno;
} else if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
- r = path_is_config(&paths, path);
+ r = path_is_config(&paths, path, true);
if (r < 0)
return r;
if (r > 0) {
@@ -2166,7 +2246,7 @@ int unit_file_revert(
STRV_FOREACH(j, fs) {
_cleanup_free_ char *t = NULL;
- t = strjoin(*i, "/", *j, NULL);
+ t = strjoin(*i, "/", *j);
if (!t)
return -ENOMEM;
@@ -2224,6 +2304,8 @@ int unit_file_add_dependency(
return r;
config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
+ if (!config_path)
+ return -ENXIO;
r = install_info_discover(scope, &c, &paths, target, SEARCH_FOLLOW_CONFIG_SYMLINKS,
&target_info, changes, n_changes);
@@ -2289,6 +2371,8 @@ int unit_file_enable(
return r;
config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
+ if (!config_path)
+ return -ENXIO;
STRV_FOREACH(f, files) {
r = install_info_discover(scope, &c, &paths, *f, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS,
@@ -2333,6 +2417,8 @@ int unit_file_disable(
return r;
config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
+ if (!config_path)
+ return -ENXIO;
STRV_FOREACH(i, files) {
if (!unit_name_is_valid(*i, UNIT_NAME_ANY))
@@ -2343,7 +2429,7 @@ int unit_file_disable(
return r;
}
- r = install_context_mark_for_removal(scope, &c, &paths, &remove_symlinks_to, config_path);
+ r = install_context_mark_for_removal(scope, &c, &paths, &remove_symlinks_to, config_path, changes, n_changes);
if (r < 0)
return r;
@@ -2479,7 +2565,7 @@ static int unit_file_lookup_state(
switch (i->type) {
case UNIT_FILE_TYPE_MASKED:
- r = path_is_runtime(paths, i->path);
+ r = path_is_runtime(paths, i->path, true);
if (r < 0)
return r;
@@ -2503,7 +2589,7 @@ static int unit_file_lookup_state(
break;
}
- r = find_symlinks_in_scope(scope, paths, i->name, &state);
+ r = find_symlinks_in_scope(paths, i->name, &state);
if (r < 0)
return r;
if (r == 0) {
@@ -2732,7 +2818,7 @@ static int execute_preset(
if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
_cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
- r = install_context_mark_for_removal(scope, minus, paths, &remove_symlinks_to, config_path);
+ r = install_context_mark_for_removal(scope, minus, paths, &remove_symlinks_to, config_path, changes, n_changes);
if (r < 0)
return r;
@@ -2827,6 +2913,8 @@ int unit_file_preset(
return r;
config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
+ if (!config_path)
+ return -ENXIO;
r = read_presets(scope, root_dir, &presets);
if (r < 0)
@@ -2865,6 +2953,8 @@ int unit_file_preset_all(
return r;
config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
+ if (!config_path)
+ return -ENXIO;
r = read_presets(scope, root_dir, &presets);
if (r < 0)
diff --git a/src/shared/journal-util.c b/src/shared/journal-util.c
new file mode 100644
index 0000000000..8479221a44
--- /dev/null
+++ b/src/shared/journal-util.c
@@ -0,0 +1,151 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2013 Zbigniew Jędrzejewski-Szmek
+ Copyright 2015 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "acl-util.h"
+#include "fs-util.h"
+#include "hashmap.h"
+#include "journal-internal.h"
+#include "journal-util.h"
+#include "log.h"
+#include "strv.h"
+#include "user-util.h"
+
+static int access_check_var_log_journal(sd_journal *j) {
+#ifdef HAVE_ACL
+ _cleanup_strv_free_ char **g = NULL;
+ const char* dir;
+#endif
+ int r;
+
+ assert(j);
+
+ /* If we are root, we should have access, don't warn. */
+ if (getuid() == 0)
+ return 0;
+
+ /* If we are in the 'systemd-journal' group, we should have
+ * access too. */
+ r = in_group("systemd-journal");
+ if (r < 0)
+ return log_error_errno(r, "Failed to check if we are in the 'systemd-journal' group: %m");
+ if (r > 0)
+ return 0;
+
+#ifdef HAVE_ACL
+ if (laccess("/run/log/journal", F_OK) >= 0)
+ dir = "/run/log/journal";
+ else
+ dir = "/var/log/journal";
+
+ /* If we are in any of the groups listed in the journal ACLs,
+ * then all is good, too. Let's enumerate all groups from the
+ * default ACL of the directory, which generally should allow
+ * access to most journal files too. */
+ r = acl_search_groups(dir, &g);
+ if (r < 0)
+ return log_error_errno(r, "Failed to search journal ACL: %m");
+ if (r > 0)
+ return 0;
+
+ /* Print a pretty list, if there were ACLs set. */
+ if (!strv_isempty(g)) {
+ _cleanup_free_ char *s = NULL;
+
+ /* Thre are groups in the ACL, let's list them */
+ r = strv_extend(&g, "systemd-journal");
+ if (r < 0)
+ return log_oom();
+
+ strv_sort(g);
+ strv_uniq(g);
+
+ s = strv_join(g, "', '");
+ if (!s)
+ return log_oom();
+
+ log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
+ " Users in groups '%s' can see all messages.\n"
+ " Pass -q to turn off this notice.", s);
+ return 1;
+ }
+#endif
+
+ /* If no ACLs were found, print a short version of the message. */
+ log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
+ " Users in the 'systemd-journal' group can see all messages. Pass -q to\n"
+ " turn off this notice.");
+
+ return 1;
+}
+
+int journal_access_check_and_warn(sd_journal *j, bool quiet) {
+ Iterator it;
+ void *code;
+ char *path;
+ int r = 0;
+
+ assert(j);
+
+ if (hashmap_isempty(j->errors)) {
+ if (ordered_hashmap_isempty(j->files) && !quiet)
+ log_notice("No journal files were found.");
+
+ return 0;
+ }
+
+ if (hashmap_contains(j->errors, INT_TO_PTR(-EACCES))) {
+ if (!quiet)
+ (void) access_check_var_log_journal(j);
+
+ if (ordered_hashmap_isempty(j->files))
+ r = log_error_errno(EACCES, "No journal files were opened due to insufficient permissions.");
+ }
+
+ HASHMAP_FOREACH_KEY(path, code, j->errors, it) {
+ int err;
+
+ err = abs(PTR_TO_INT(code));
+
+ switch (err) {
+ case EACCES:
+ continue;
+
+ case ENODATA:
+ log_warning_errno(err, "Journal file %s is truncated, ignoring file.", path);
+ break;
+
+ case EPROTONOSUPPORT:
+ log_warning_errno(err, "Journal file %1$s uses an unsupported feature, ignoring file.\n"
+ "Use SYSTEMD_LOG_LEVEL=debug journalctl --file=%1$s to see the details.",
+ path);
+ break;
+
+ case EBADMSG:
+ log_warning_errno(err, "Journal file %s corrupted, ignoring file.", path);
+ break;
+
+ default:
+ log_warning_errno(err, "An error was encountered while opening journal file or directory %s, ignoring file: %m", path);
+ break;
+ }
+ }
+
+ return r;
+}
diff --git a/src/shared/journal-util.h b/src/shared/journal-util.h
new file mode 100644
index 0000000000..499e6c62ec
--- /dev/null
+++ b/src/shared/journal-util.h
@@ -0,0 +1,25 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2013 Zbigniew Jędrzejewski-Szmek
+ Copyright 2015 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+
+#include "sd-journal.h"
+
+int journal_access_check_and_warn(sd_journal *j, bool quiet);
diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c
index f9d9c4ed62..b4c72215c4 100644
--- a/src/shared/logs-show.c
+++ b/src/shared/logs-show.c
@@ -33,7 +33,7 @@
#include "alloc-util.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "hashmap.h"
#include "hostname-util.h"
#include "io-util.h"
@@ -223,10 +223,7 @@ static int output_timestamp_monotonic(FILE *f, sd_journal *j, const char *monoto
if (r < 0)
return log_error_errno(r, "Failed to get monotonic timestamp: %m");
- fprintf(f, "[%5llu.%06llu]",
- (unsigned long long) (t / USEC_PER_SEC),
- (unsigned long long) (t % USEC_PER_SEC));
-
+ fprintf(f, "[%5"PRI_USEC".%06"PRI_USEC"]", t / USEC_PER_SEC, t % USEC_PER_SEC);
return 1 + 5 + 1 + 6 + 1;
}
@@ -249,6 +246,11 @@ static int output_timestamp_realtime(FILE *f, sd_journal *j, OutputMode mode, Ou
if (r < 0)
return log_error_errno(r, "Failed to get realtime timestamp: %m");
+ if (x > USEC_TIMESTAMP_FORMATTABLE_MAX) {
+ log_error("Timestamp cannot be printed");
+ return -EINVAL;
+ }
+
if (mode == OUTPUT_SHORT_FULL) {
const char *k;
@@ -268,7 +270,7 @@ static int output_timestamp_realtime(FILE *f, sd_journal *j, OutputMode mode, Ou
switch (mode) {
case OUTPUT_SHORT_UNIX:
- xsprintf(buf, "%10llu.%06llu", (unsigned long long) t, (unsigned long long) (x % USEC_PER_SEC));
+ xsprintf(buf, "%10"PRI_TIME".%06"PRIu64, t, x % USEC_PER_SEC);
break;
case OUTPUT_SHORT_ISO:
@@ -292,7 +294,7 @@ static int output_timestamp_realtime(FILE *f, sd_journal *j, OutputMode mode, Ou
assert(sizeof(buf) > strlen(buf));
k = sizeof(buf) - strlen(buf);
- r = snprintf(buf + strlen(buf), k, ".%06llu", (unsigned long long) (x % USEC_PER_SEC));
+ r = snprintf(buf + strlen(buf), k, ".%06"PRIu64, x % USEC_PER_SEC);
if (r <= 0 || (size_t) r >= k) { /* too long? */
log_error("Failed to format precise time");
return -EINVAL;
@@ -418,7 +420,7 @@ static int output_short(
if (flags & OUTPUT_NO_HOSTNAME) {
/* Suppress display of the hostname if this is requested. */
- hostname = NULL;
+ hostname = mfree(hostname);
hostname_len = 0;
}
@@ -471,6 +473,7 @@ static int output_verbose(
_cleanup_free_ char *cursor = NULL;
uint64_t realtime = 0;
char ts[FORMAT_TIMESTAMP_MAX + 7];
+ const char *timestamp;
int r;
assert(f);
@@ -506,10 +509,10 @@ static int output_verbose(
if (r < 0)
return log_error_errno(r, "Failed to get cursor: %m");
+ timestamp = flags & OUTPUT_UTC ? format_timestamp_us_utc(ts, sizeof ts, realtime)
+ : format_timestamp_us(ts, sizeof ts, realtime);
fprintf(f, "%s [%s]\n",
- flags & OUTPUT_UTC ?
- format_timestamp_us_utc(ts, sizeof(ts), realtime) :
- format_timestamp_us(ts, sizeof(ts), realtime),
+ timestamp ?: "(no timestamp)",
cursor);
JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) {
diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c
new file mode 100644
index 0000000000..047e213634
--- /dev/null
+++ b/src/shared/loop-util.c
@@ -0,0 +1,166 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <fcntl.h>
+#include <linux/loop.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+
+#include "alloc-util.h"
+#include "fd-util.h"
+#include "loop-util.h"
+
+int loop_device_make(int fd, int open_flags, LoopDevice **ret) {
+ const struct loop_info64 info = {
+ .lo_flags = LO_FLAGS_AUTOCLEAR|LO_FLAGS_PARTSCAN|(open_flags == O_RDONLY ? LO_FLAGS_READ_ONLY : 0),
+ };
+
+ _cleanup_close_ int control = -1, loop = -1;
+ _cleanup_free_ char *loopdev = NULL;
+ struct stat st;
+ LoopDevice *d;
+ int nr;
+
+ assert(fd >= 0);
+ assert(ret);
+ assert(IN_SET(open_flags, O_RDWR, O_RDONLY));
+
+ if (fstat(fd, &st) < 0)
+ return -errno;
+
+ if (S_ISBLK(st.st_mode)) {
+ int copy;
+
+ /* If this is already a block device, store a copy of the fd as it is */
+
+ copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
+ if (copy < 0)
+ return -errno;
+
+ d = new0(LoopDevice, 1);
+ if (!d)
+ return -ENOMEM;
+
+ *d = (LoopDevice) {
+ .fd = copy,
+ .nr = -1,
+ };
+
+ *ret = d;
+
+ return 0;
+ }
+
+ if (!S_ISREG(st.st_mode))
+ return -EINVAL;
+
+ control = open("/dev/loop-control", O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
+ if (control < 0)
+ return -errno;
+
+ nr = ioctl(control, LOOP_CTL_GET_FREE);
+ if (nr < 0)
+ return -errno;
+
+ if (asprintf(&loopdev, "/dev/loop%i", nr) < 0)
+ return -ENOMEM;
+
+ loop = open(loopdev, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|open_flags);
+ if (loop < 0)
+ return -errno;
+
+ if (ioctl(loop, LOOP_SET_FD, fd) < 0)
+ return -errno;
+
+ if (ioctl(loop, LOOP_SET_STATUS64, &info) < 0)
+ return -errno;
+
+ d = new(LoopDevice, 1);
+ if (!d)
+ return -ENOMEM;
+
+ *d = (LoopDevice) {
+ .fd = loop,
+ .node = loopdev,
+ .nr = nr,
+ };
+
+ loop = -1;
+ loopdev = NULL;
+
+ *ret = d;
+
+ return (*ret)->fd;
+}
+
+int loop_device_make_by_path(const char *path, int open_flags, LoopDevice **ret) {
+ _cleanup_close_ int fd = -1;
+
+ assert(path);
+ assert(ret);
+ assert(IN_SET(open_flags, O_RDWR, O_RDONLY));
+
+ fd = open(path, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|open_flags);
+ if (fd < 0)
+ return -errno;
+
+ return loop_device_make(fd, open_flags, ret);
+}
+
+LoopDevice* loop_device_unref(LoopDevice *d) {
+ if (!d)
+ return NULL;
+
+ if (d->fd >= 0) {
+
+ if (d->nr >= 0 && !d->relinquished) {
+ if (ioctl(d->fd, LOOP_CLR_FD) < 0)
+ log_debug_errno(errno, "Failed to clear loop device: %m");
+
+ }
+
+ safe_close(d->fd);
+ }
+
+ if (d->nr >= 0 && !d->relinquished) {
+ _cleanup_close_ int control = -1;
+
+ control = open("/dev/loop-control", O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
+ if (control < 0)
+ log_debug_errno(errno, "Failed to open loop control device: %m");
+ else {
+ if (ioctl(control, LOOP_CTL_REMOVE, d->nr) < 0)
+ log_debug_errno(errno, "Failed to remove loop device: %m");
+ }
+ }
+
+ free(d->node);
+ free(d);
+
+ return NULL;
+}
+
+void loop_device_relinquish(LoopDevice *d) {
+ assert(d);
+
+ /* Don't attempt to clean up the loop device anymore from this point on. Leave the clean-ing up to the kernel
+ * itself, using the loop device "auto-clear" logic we already turned on when creating the device. */
+
+ d->relinquished = true;
+}
diff --git a/src/shared/loop-util.h b/src/shared/loop-util.h
new file mode 100644
index 0000000000..45fead5f18
--- /dev/null
+++ b/src/shared/loop-util.h
@@ -0,0 +1,41 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "macro.h"
+
+typedef struct LoopDevice LoopDevice;
+
+/* Some helpers for setting up loopback block devices */
+
+struct LoopDevice {
+ int fd;
+ int nr;
+ char *node;
+ bool relinquished;
+};
+
+int loop_device_make(int fd, int open_flags, LoopDevice **ret);
+int loop_device_make_by_path(const char *path, int open_flags, LoopDevice **ret);
+
+LoopDevice* loop_device_unref(LoopDevice *d);
+DEFINE_TRIVIAL_CLEANUP_FUNC(LoopDevice*, loop_device_unref);
+
+void loop_device_relinquish(LoopDevice *d);
diff --git a/src/shared/machine-image.c b/src/shared/machine-image.c
index 060f8d50c7..32a4c67590 100644
--- a/src/shared/machine-image.c
+++ b/src/shared/machine-image.c
@@ -27,18 +27,20 @@
#include <sys/stat.h>
#include <unistd.h>
#include <linux/fs.h>
+
#include "alloc-util.h"
#include "btrfs-util.h"
#include "chattr-util.h"
#include "copy.h"
#include "dirent-util.h"
+#include "env-util.h"
#include "fd-util.h"
#include "fs-util.h"
#include "hashmap.h"
#include "lockfile-util.h"
#include "log.h"
-#include "macro.h"
#include "machine-image.h"
+#include "macro.h"
#include "mkdir.h"
#include "path-util.h"
#include "rm-rf.h"
@@ -97,6 +99,16 @@ static char **image_settings_path(Image *image) {
return ret;
}
+static char *image_roothash_path(Image *image) {
+ const char *fn;
+
+ assert(image);
+
+ fn = strjoina(image->name, ".roothash");
+
+ return file_in_same_dir(image->path, fn);
+}
+
static int image_new(
ImageType t,
const char *pretty,
@@ -131,7 +143,7 @@ static int image_new(
return -ENOMEM;
if (path)
- i->path = strjoin(path, "/", filename, NULL);
+ i->path = strjoin(path, "/", filename);
else
i->path = strdup(filename);
@@ -395,6 +407,7 @@ void image_hashmap_free(Hashmap *map) {
int image_remove(Image *i) {
_cleanup_release_lock_file_ LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT;
_cleanup_strv_free_ char **settings = NULL;
+ _cleanup_free_ char *roothash = NULL;
char **j;
int r;
@@ -407,6 +420,10 @@ int image_remove(Image *i) {
if (!settings)
return -ENOMEM;
+ roothash = image_roothash_path(i);
+ if (!roothash)
+ return -ENOMEM;
+
/* Make sure we don't interfere with a running nspawn */
r = image_path_lock(i->path, LOCK_EX|LOCK_NB, &global_lock, &local_lock);
if (r < 0)
@@ -443,14 +460,17 @@ int image_remove(Image *i) {
log_debug_errno(errno, "Failed to unlink %s, ignoring: %m", *j);
}
+ if (unlink(roothash) < 0 && errno != ENOENT)
+ log_debug_errno(errno, "Failed to unlink %s, ignoring: %m", roothash);
+
return 0;
}
-static int rename_settings_file(const char *path, const char *new_name) {
+static int rename_auxiliary_file(const char *path, const char *new_name, const char *suffix) {
_cleanup_free_ char *rs = NULL;
const char *fn;
- fn = strjoina(new_name, ".nspawn");
+ fn = strjoina(new_name, suffix);
rs = file_in_same_dir(path, fn);
if (!rs)
@@ -461,7 +481,7 @@ static int rename_settings_file(const char *path, const char *new_name) {
int image_rename(Image *i, const char *new_name) {
_cleanup_release_lock_file_ LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT, name_lock = LOCK_FILE_INIT;
- _cleanup_free_ char *new_path = NULL, *nn = NULL;
+ _cleanup_free_ char *new_path = NULL, *nn = NULL, *roothash = NULL;
_cleanup_strv_free_ char **settings = NULL;
unsigned file_attr = 0;
char **j;
@@ -479,6 +499,10 @@ int image_rename(Image *i, const char *new_name) {
if (!settings)
return -ENOMEM;
+ roothash = image_roothash_path(i);
+ if (!roothash)
+ return -ENOMEM;
+
/* Make sure we don't interfere with a running nspawn */
r = image_path_lock(i->path, LOCK_EX|LOCK_NB, &global_lock, &local_lock);
if (r < 0)
@@ -548,30 +572,35 @@ int image_rename(Image *i, const char *new_name) {
nn = NULL;
STRV_FOREACH(j, settings) {
- r = rename_settings_file(*j, new_name);
+ r = rename_auxiliary_file(*j, new_name, ".nspawn");
if (r < 0 && r != -ENOENT)
log_debug_errno(r, "Failed to rename settings file %s, ignoring: %m", *j);
}
+ r = rename_auxiliary_file(roothash, new_name, ".roothash");
+ if (r < 0 && r != -ENOENT)
+ log_debug_errno(r, "Failed to rename roothash file %s, ignoring: %m", roothash);
+
return 0;
}
-static int clone_settings_file(const char *path, const char *new_name) {
+static int clone_auxiliary_file(const char *path, const char *new_name, const char *suffix) {
_cleanup_free_ char *rs = NULL;
const char *fn;
- fn = strjoina(new_name, ".nspawn");
+ fn = strjoina(new_name, suffix);
rs = file_in_same_dir(path, fn);
if (!rs)
return -ENOMEM;
- return copy_file_atomic(path, rs, 0664, false, 0);
+ return copy_file_atomic(path, rs, 0664, 0, COPY_REFLINK);
}
int image_clone(Image *i, const char *new_name, bool read_only) {
_cleanup_release_lock_file_ LockFile name_lock = LOCK_FILE_INIT;
_cleanup_strv_free_ char **settings = NULL;
+ _cleanup_free_ char *roothash = NULL;
const char *new_path;
char **j;
int r;
@@ -585,6 +614,10 @@ int image_clone(Image *i, const char *new_name, bool read_only) {
if (!settings)
return -ENOMEM;
+ roothash = image_roothash_path(i);
+ if (!roothash)
+ return -ENOMEM;
+
/* Make sure nobody takes the new name, between the time we
* checked it is currently unused in all search paths, and the
* time we take possession of it */
@@ -603,18 +636,18 @@ int image_clone(Image *i, const char *new_name, bool read_only) {
case IMAGE_SUBVOLUME:
case IMAGE_DIRECTORY:
/* If we can we'll always try to create a new btrfs subvolume here, even if the source is a plain
- * directory.*/
+ * directory. */
new_path = strjoina("/var/lib/machines/", new_name);
- r = btrfs_subvol_snapshot(i->path, new_path, (read_only ? BTRFS_SNAPSHOT_READ_ONLY : 0) | BTRFS_SNAPSHOT_FALLBACK_COPY | BTRFS_SNAPSHOT_RECURSIVE | BTRFS_SNAPSHOT_QUOTA);
- if (r == -EOPNOTSUPP) {
- /* No btrfs snapshots supported, create a normal directory then. */
-
- r = copy_directory(i->path, new_path, false);
- if (r >= 0)
- (void) chattr_path(new_path, read_only ? FS_IMMUTABLE_FL : 0, FS_IMMUTABLE_FL);
- } else if (r >= 0)
+ r = btrfs_subvol_snapshot(i->path, new_path,
+ (read_only ? BTRFS_SNAPSHOT_READ_ONLY : 0) |
+ BTRFS_SNAPSHOT_FALLBACK_COPY |
+ BTRFS_SNAPSHOT_FALLBACK_DIRECTORY |
+ BTRFS_SNAPSHOT_FALLBACK_IMMUTABLE |
+ BTRFS_SNAPSHOT_RECURSIVE |
+ BTRFS_SNAPSHOT_QUOTA);
+ if (r >= 0)
/* Enable "subtree" quotas for the copy, if we didn't copy any quota from the source. */
(void) btrfs_subvol_auto_qgroup(new_path, 0, true);
@@ -623,7 +656,7 @@ int image_clone(Image *i, const char *new_name, bool read_only) {
case IMAGE_RAW:
new_path = strjoina("/var/lib/machines/", new_name, ".raw");
- r = copy_file_atomic(i->path, new_path, read_only ? 0444 : 0644, false, FS_NOCOW_FL);
+ r = copy_file_atomic(i->path, new_path, read_only ? 0444 : 0644, FS_NOCOW_FL, COPY_REFLINK);
break;
default:
@@ -634,11 +667,15 @@ int image_clone(Image *i, const char *new_name, bool read_only) {
return r;
STRV_FOREACH(j, settings) {
- r = clone_settings_file(*j, new_name);
+ r = clone_auxiliary_file(*j, new_name, ".nspawn");
if (r < 0 && r != -ENOENT)
log_debug_errno(r, "Failed to clone settings %s, ignoring: %m", *j);
}
+ r = clone_auxiliary_file(roothash, new_name, ".roothash");
+ if (r < 0 && r != -ENOENT)
+ log_debug_errno(r, "Failed to clone root hash file %s, ignoring: %m", roothash);
+
return 0;
}
@@ -675,7 +712,7 @@ int image_read_only(Image *i, bool b) {
use the "immutable" flag, to at least make the
top-level directory read-only. It's not as good as
a read-only subvolume, but at least something, and
- we can read the value back.*/
+ we can read the value back. */
r = chattr_path(i->path, b ? FS_IMMUTABLE_FL : 0, FS_IMMUTABLE_FL);
if (r < 0)
@@ -723,12 +760,17 @@ int image_path_lock(const char *path, int operation, LockFile *global, LockFile
* uses the device/inode number. This has the benefit that we
* can even lock a tree that is a mount point, correctly. */
- if (path_equal(path, "/"))
- return -EBUSY;
-
if (!path_is_absolute(path))
return -EINVAL;
+ if (getenv_bool("SYSTEMD_NSPAWN_LOCK") == 0) {
+ *local = *global = (LockFile) LOCK_FILE_INIT;
+ return 0;
+ }
+
+ if (path_equal(path, "/"))
+ return -EBUSY;
+
if (stat(path, &st) >= 0) {
if (asprintf(&p, "/run/systemd/nspawn/locks/inode-%lu:%lu", (unsigned long) st.st_dev, (unsigned long) st.st_ino) < 0)
return -ENOMEM;
@@ -746,7 +788,8 @@ int image_path_lock(const char *path, int operation, LockFile *global, LockFile
release_lock_file(&t);
return r;
}
- }
+ } else
+ *global = (LockFile) LOCK_FILE_INIT;
*local = t;
return 0;
@@ -782,6 +825,11 @@ int image_name_lock(const char *name, int operation, LockFile *ret) {
if (!image_name_is_valid(name))
return -EINVAL;
+ if (getenv_bool("SYSTEMD_NSPAWN_LOCK") == 0) {
+ *ret = (LockFile) LOCK_FILE_INIT;
+ return 0;
+ }
+
if (streq(name, ".host"))
return -EBUSY;
diff --git a/src/shared/machine-pool.c b/src/shared/machine-pool.c
index 23890c63a0..c581bdeb79 100644
--- a/src/shared/machine-pool.c
+++ b/src/shared/machine-pool.c
@@ -225,7 +225,7 @@ int setup_machine_directory(uint64_t size, sd_bus_error *error) {
return 1;
}
- if (path_is_mount_point("/var/lib/machines", AT_SYMLINK_FOLLOW) > 0) {
+ if (path_is_mount_point("/var/lib/machines", NULL, AT_SYMLINK_FOLLOW) > 0) {
log_debug("/var/lib/machines is already a mount point, not creating loopback file for it.");
return 0;
}
diff --git a/src/shared/nsflags.c b/src/shared/nsflags.c
new file mode 100644
index 0000000000..aeb79b131e
--- /dev/null
+++ b/src/shared/nsflags.c
@@ -0,0 +1,120 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sched.h>
+
+#include "alloc-util.h"
+#include "extract-word.h"
+#include "nsflags.h"
+#include "string-util.h"
+
+const struct namespace_flag_map namespace_flag_map[] = {
+ { CLONE_NEWCGROUP, "cgroup" },
+ { CLONE_NEWIPC, "ipc" },
+ { CLONE_NEWNET, "net" },
+ /* So, the mount namespace flag is called CLONE_NEWNS for historical reasons. Let's expose it here under a more
+ * explanatory name: "mnt". This is in-line with how the kernel exposes namespaces in /proc/$PID/ns. */
+ { CLONE_NEWNS, "mnt" },
+ { CLONE_NEWPID, "pid" },
+ { CLONE_NEWUSER, "user" },
+ { CLONE_NEWUTS, "uts" },
+ {}
+};
+
+const char* namespace_flag_to_string(unsigned long flag) {
+ unsigned i;
+
+ flag &= NAMESPACE_FLAGS_ALL;
+
+ for (i = 0; namespace_flag_map[i].name; i++)
+ if (flag == namespace_flag_map[i].flag)
+ return namespace_flag_map[i].name;
+
+ return NULL; /* either unknown namespace flag, or a combination of many. This call supports neither. */
+}
+
+unsigned long namespace_flag_from_string(const char *name) {
+ unsigned i;
+
+ if (isempty(name))
+ return 0;
+
+ for (i = 0; namespace_flag_map[i].name; i++)
+ if (streq(name, namespace_flag_map[i].name))
+ return namespace_flag_map[i].flag;
+
+ return 0;
+}
+
+int namespace_flag_from_string_many(const char *name, unsigned long *ret) {
+ unsigned long flags = 0;
+ int r;
+
+ assert_se(ret);
+
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
+ unsigned long f;
+
+ r = extract_first_word(&name, &word, NULL, 0);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+
+ f = namespace_flag_from_string(word);
+ if (f == 0)
+ return -EINVAL;
+
+ flags |= f;
+ }
+
+ *ret = flags;
+ return 0;
+}
+
+int namespace_flag_to_string_many(unsigned long flags, char **ret) {
+ _cleanup_free_ char *s = NULL;
+ unsigned i;
+
+ for (i = 0; namespace_flag_map[i].name; i++) {
+ if ((flags & namespace_flag_map[i].flag) != namespace_flag_map[i].flag)
+ continue;
+
+ if (!s) {
+ s = strdup(namespace_flag_map[i].name);
+ if (!s)
+ return -ENOMEM;
+ } else {
+ if (!strextend(&s, " ", namespace_flag_map[i].name, NULL))
+ return -ENOMEM;
+ }
+ }
+
+ if (!s) {
+ s = strdup("");
+ if (!s)
+ return -ENOMEM;
+ }
+
+ *ret = s;
+ s = NULL;
+
+ return 0;
+}
diff --git a/src/shared/nsflags.h b/src/shared/nsflags.h
new file mode 100644
index 0000000000..152ab8b936
--- /dev/null
+++ b/src/shared/nsflags.h
@@ -0,0 +1,49 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sched.h>
+
+#include "missing.h"
+
+/* The combination of all namespace flags defined by the kernel. The right type for this isn't clear. setns() and
+ * unshare() expect these flags to be passed as (signed) "int", while clone() wants them as "unsigned long". The latter
+ * is definitely more appropriate for a flags parameter, and also the larger type of the two, hence let's stick to that
+ * here. */
+#define NAMESPACE_FLAGS_ALL \
+ ((unsigned long) (CLONE_NEWCGROUP| \
+ CLONE_NEWIPC| \
+ CLONE_NEWNET| \
+ CLONE_NEWNS| \
+ CLONE_NEWPID| \
+ CLONE_NEWUSER| \
+ CLONE_NEWUTS))
+
+const char* namespace_flag_to_string(unsigned long flag);
+unsigned long namespace_flag_from_string(const char *name);
+int namespace_flag_from_string_many(const char *name, unsigned long *ret);
+int namespace_flag_to_string_many(unsigned long flags, char **ret);
+
+struct namespace_flag_map {
+ unsigned long flag;
+ const char *name;
+};
+
+extern const struct namespace_flag_map namespace_flag_map[];
diff --git a/src/shared/pager.c b/src/shared/pager.c
index 09672a4abf..f00ba9e1e7 100644
--- a/src/shared/pager.c
+++ b/src/shared/pager.c
@@ -44,7 +44,7 @@ static pid_t pager_pid = 0;
noreturn static void pager_fallback(void) {
int r;
- r = copy_bytes(STDIN_FILENO, STDOUT_FILENO, (uint64_t) -1, false);
+ r = copy_bytes(STDIN_FILENO, STDOUT_FILENO, (uint64_t) -1, 0);
if (r < 0) {
log_error_errno(r, "Internal pager failed: %m");
_exit(EXIT_FAILURE);
@@ -104,7 +104,8 @@ int pager_open(bool no_pager, bool jump_to_end) {
less_opts = "FRSXMK";
if (jump_to_end)
less_opts = strjoina(less_opts, " +G");
- setenv("LESS", less_opts, 1);
+ if (setenv("LESS", less_opts, 1) < 0)
+ _exit(EXIT_FAILURE);
/* Initialize a good charset for less. This is
* particularly important if we output UTF-8
@@ -112,8 +113,9 @@ int pager_open(bool no_pager, bool jump_to_end) {
less_charset = getenv("SYSTEMD_LESSCHARSET");
if (!less_charset && is_locale_utf8())
less_charset = "utf-8";
- if (less_charset)
- setenv("LESSCHARSET", less_charset, 1);
+ if (less_charset &&
+ setenv("LESSCHARSET", less_charset, 1) < 0)
+ _exit(EXIT_FAILURE);
/* Make sure the pager goes away when the parent dies */
if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
diff --git a/src/shared/path-lookup.c b/src/shared/path-lookup.c
index 862096ae7b..e2b3f8b742 100644
--- a/src/shared/path-lookup.c
+++ b/src/shared/path-lookup.c
@@ -33,6 +33,7 @@
#include "stat-util.h"
#include "string-util.h"
#include "strv.h"
+#include "user-util.h"
#include "util.h"
static int user_runtime_dir(char **ret, const char *suffix) {
@@ -57,6 +58,7 @@ static int user_runtime_dir(char **ret, const char *suffix) {
static int user_config_dir(char **ret, const char *suffix) {
const char *e;
char *j;
+ int r;
assert(ret);
@@ -64,13 +66,13 @@ static int user_config_dir(char **ret, const char *suffix) {
if (e)
j = strappend(e, suffix);
else {
- const char *home;
+ _cleanup_free_ char *home = NULL;
- home = getenv("HOME");
- if (!home)
- return -ENXIO;
+ r = get_home_dir(&home);
+ if (r < 0)
+ return r;
- j = strjoin(home, "/.config", suffix, NULL);
+ j = strjoin(home, "/.config", suffix);
}
if (!j)
@@ -83,6 +85,7 @@ static int user_config_dir(char **ret, const char *suffix) {
static int user_data_dir(char **ret, const char *suffix) {
const char *e;
char *j;
+ int r;
assert(ret);
assert(suffix);
@@ -95,14 +98,13 @@ static int user_data_dir(char **ret, const char *suffix) {
if (e)
j = strappend(e, suffix);
else {
- const char *home;
-
- home = getenv("HOME");
- if (!home)
- return -ENXIO;
+ _cleanup_free_ char *home = NULL;
+ r = get_home_dir(&home);
+ if (r < 0)
+ return r;
- j = strjoin(home, "/.local/share", suffix, NULL);
+ j = strjoin(home, "/.local/share", suffix);
}
if (!j)
return -ENOMEM;
@@ -136,10 +138,10 @@ static char** user_dirs(
NULL
};
- const char *e;
_cleanup_strv_free_ char **config_dirs = NULL, **data_dirs = NULL;
_cleanup_free_ char *data_home = NULL;
- _cleanup_free_ char **res = NULL;
+ _cleanup_strv_free_ char **res = NULL;
+ const char *e;
char **tmp;
int r;
@@ -186,9 +188,8 @@ static char** user_dirs(
if (strv_extend(&res, generator_early) < 0)
return NULL;
- if (!strv_isempty(config_dirs))
- if (strv_extend_strv_concat(&res, config_dirs, "/systemd/user") < 0)
- return NULL;
+ if (strv_extend_strv_concat(&res, config_dirs, "/systemd/user") < 0)
+ return NULL;
if (strv_extend(&res, persistent_config) < 0)
return NULL;
@@ -205,9 +206,8 @@ static char** user_dirs(
if (strv_extend(&res, data_home) < 0)
return NULL;
- if (!strv_isempty(data_dirs))
- if (strv_extend_strv_concat(&res, data_dirs, "/systemd/user") < 0)
- return NULL;
+ if (strv_extend_strv_concat(&res, data_dirs, "/systemd/user") < 0)
+ return NULL;
if (strv_extend_strv(&res, (char**) data_unit_paths, false) < 0)
return NULL;
@@ -220,6 +220,7 @@ static char** user_dirs(
tmp = res;
res = NULL;
+
return tmp;
}
@@ -328,12 +329,18 @@ static int acquire_config_dirs(UnitFileScope scope, char **persistent, char **ru
case UNIT_FILE_USER:
r = user_config_dir(&a, "/systemd/user");
- if (r < 0)
+ if (r < 0 && r != -ENXIO)
return r;
r = user_runtime_dir(runtime, "/systemd/user");
- if (r < 0)
- return r;
+ if (r < 0) {
+ if (r != -ENXIO)
+ return r;
+
+ /* If XDG_RUNTIME_DIR is not set, don't consider that fatal, simply initialize the runtime
+ * directory to NULL */
+ *runtime = NULL;
+ }
*persistent = a;
a = NULL;
@@ -382,12 +389,18 @@ static int acquire_control_dirs(UnitFileScope scope, char **persistent, char **r
case UNIT_FILE_USER:
r = user_config_dir(&a, "/systemd/system.control");
- if (r < 0)
+ if (r < 0 && r != -ENXIO)
return r;
r = user_runtime_dir(runtime, "/systemd/system.control");
- if (r < 0)
- return r;
+ if (r < 0) {
+ if (r != -ENXIO)
+ return r;
+
+ /* If XDG_RUNTIME_DIR is not set, don't consider this fatal, simply initialize the directory to
+ * NULL */
+ *runtime = NULL;
+ }
break;
@@ -474,22 +487,26 @@ int lookup_paths_init(
return -ENOMEM;
}
+ /* Note: when XDG_RUNTIME_DIR is not set this will not return -ENXIO, but simply set runtime_config to NULL */
r = acquire_config_dirs(scope, &persistent_config, &runtime_config);
- if (r < 0 && r != -ENXIO)
+ if (r < 0)
return r;
if ((flags & LOOKUP_PATHS_EXCLUDE_GENERATED) == 0) {
+ /* Note: if XDG_RUNTIME_DIR is not set, this will fail completely with ENXIO */
r = acquire_generator_dirs(scope, &generator, &generator_early, &generator_late);
if (r < 0 && r != -EOPNOTSUPP && r != -ENXIO)
return r;
}
+ /* Note: if XDG_RUNTIME_DIR is not set, this will fail completely with ENXIO */
r = acquire_transient_dir(scope, &transient);
if (r < 0 && r != -EOPNOTSUPP && r != -ENXIO)
return r;
+ /* Note: when XDG_RUNTIME_DIR is not set this will not return -ENXIO, but simply set runtime_control to NULL */
r = acquire_control_dirs(scope, &persistent_control, &runtime_control);
- if (r < 0 && r != -EOPNOTSUPP && r != -ENXIO)
+ if (r < 0 && r != -EOPNOTSUPP)
return r;
/* First priority is whatever has been passed to us via env vars */
@@ -503,8 +520,7 @@ int lookup_paths_init(
append = true;
}
- /* FIXME: empty components in other places should be
- * rejected. */
+ /* FIXME: empty components in other places should be rejected. */
r = path_split_and_make_absolute(e, &paths);
if (r < 0)
diff --git a/src/shared/ptyfwd.c b/src/shared/ptyfwd.c
index 293c6673fc..59b541d519 100644
--- a/src/shared/ptyfwd.c
+++ b/src/shared/ptyfwd.c
@@ -69,6 +69,7 @@ struct PTYForward {
bool read_from_master:1;
bool done:1;
+ bool drain:1;
bool last_char_set:1;
char last_char;
@@ -302,6 +303,11 @@ static int shovel(PTYForward *f) {
return pty_forward_done(f, 0);
}
+ /* If we were asked to drain, and there's nothing more to handle from the master, then call the callback
+ * too. */
+ if (f->drain && f->out_buffer_full == 0 && !f->master_readable)
+ return pty_forward_done(f, 0);
+
return 0;
}
@@ -438,6 +444,9 @@ int pty_forward_new(
r = sd_event_add_io(f->event, &f->stdin_event_source, STDIN_FILENO, EPOLLIN|EPOLLET, on_stdin_event, f);
if (r < 0 && r != -EPERM)
return r;
+
+ if (r >= 0)
+ (void) sd_event_source_set_description(f->stdin_event_source, "ptyfwd-stdin");
}
r = sd_event_add_io(f->event, &f->stdout_event_source, STDOUT_FILENO, EPOLLOUT|EPOLLET, on_stdout_event, f);
@@ -446,15 +455,21 @@ int pty_forward_new(
f->stdout_writable = true;
else if (r < 0)
return r;
+ else
+ (void) sd_event_source_set_description(f->stdout_event_source, "ptyfwd-stdout");
r = sd_event_add_io(f->event, &f->master_event_source, master, EPOLLIN|EPOLLOUT|EPOLLET, on_master_event, f);
if (r < 0)
return r;
+ (void) sd_event_source_set_description(f->master_event_source, "ptyfwd-master");
+
r = sd_event_add_signal(f->event, &f->sigwinch_event_source, SIGWINCH, on_sigwinch_event, f);
if (r < 0)
return r;
+ (void) sd_event_source_set_description(f->sigwinch_event_source, "ptyfwd-sigwinch");
+
*ret = f;
f = NULL;
@@ -519,3 +534,18 @@ void pty_forward_set_handler(PTYForward *f, PTYForwardHandler cb, void *userdata
f->handler = cb;
f->userdata = userdata;
}
+
+bool pty_forward_drain(PTYForward *f) {
+ assert(f);
+
+ /* Starts draining the forwarder. Specifically:
+ *
+ * - Returns true if there are no unprocessed bytes from the pty, false otherwise
+ *
+ * - Makes sure the handler function is called the next time the number of unprocessed bytes hits zero
+ */
+
+ f->drain = true;
+
+ return f->out_buffer_full == 0 && !f->master_readable;
+}
diff --git a/src/shared/ptyfwd.h b/src/shared/ptyfwd.h
index bd5d5fec0d..3fad1d3b26 100644
--- a/src/shared/ptyfwd.h
+++ b/src/shared/ptyfwd.h
@@ -51,4 +51,6 @@ bool pty_forward_is_done(PTYForward *f);
void pty_forward_set_handler(PTYForward *f, PTYForwardHandler handler, void *userdata);
+bool pty_forward_drain(PTYForward *f);
+
DEFINE_TRIVIAL_CLEANUP_FUNC(PTYForward*, pty_forward_free);
diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c
index c9b24f1065..2631856563 100644
--- a/src/shared/seccomp-util.c
+++ b/src/shared/seccomp-util.c
@@ -18,15 +18,93 @@
***/
#include <errno.h>
+#include <linux/seccomp.h>
#include <seccomp.h>
#include <stddef.h>
+#include <sys/mman.h>
#include <sys/prctl.h>
-#include <linux/seccomp.h>
+#include <sys/shm.h>
+#include "af-list.h"
+#include "alloc-util.h"
#include "macro.h"
+#include "nsflags.h"
#include "seccomp-util.h"
#include "string-util.h"
#include "util.h"
+#include "errno-list.h"
+
+const uint32_t seccomp_local_archs[] = {
+
+ /* Note: always list the native arch we are compiled as last, so that users can blacklist seccomp(), but our own calls to it still succeed */
+
+#if defined(__x86_64__) && defined(__ILP32__)
+ SCMP_ARCH_X86,
+ SCMP_ARCH_X86_64,
+ SCMP_ARCH_X32, /* native */
+#elif defined(__x86_64__) && !defined(__ILP32__)
+ SCMP_ARCH_X86,
+ SCMP_ARCH_X32,
+ SCMP_ARCH_X86_64, /* native */
+#elif defined(__i386__)
+ SCMP_ARCH_X86,
+#elif defined(__aarch64__)
+ SCMP_ARCH_ARM,
+ SCMP_ARCH_AARCH64, /* native */
+#elif defined(__arm__)
+ SCMP_ARCH_ARM,
+#elif defined(__mips__) && __BYTE_ORDER == __BIG_ENDIAN && _MIPS_SIM == _MIPS_SIM_ABI32
+ SCMP_ARCH_MIPSEL,
+ SCMP_ARCH_MIPS, /* native */
+#elif defined(__mips__) && __BYTE_ORDER == __LITTLE_ENDIAN && _MIPS_SIM == _MIPS_SIM_ABI32
+ SCMP_ARCH_MIPS,
+ SCMP_ARCH_MIPSEL, /* native */
+#elif defined(__mips__) && __BYTE_ORDER == __BIG_ENDIAN && _MIPS_SIM == _MIPS_SIM_ABI64
+ SCMP_ARCH_MIPSEL,
+ SCMP_ARCH_MIPS,
+ SCMP_ARCH_MIPSEL64N32,
+ SCMP_ARCH_MIPS64N32,
+ SCMP_ARCH_MIPSEL64,
+ SCMP_ARCH_MIPS64, /* native */
+#elif defined(__mips__) && __BYTE_ORDER == __LITTLE_ENDIAN && _MIPS_SIM == _MIPS_SIM_ABI64
+ SCMP_ARCH_MIPS,
+ SCMP_ARCH_MIPSEL,
+ SCMP_ARCH_MIPS64N32,
+ SCMP_ARCH_MIPSEL64N32,
+ SCMP_ARCH_MIPS64,
+ SCMP_ARCH_MIPSEL64, /* native */
+#elif defined(__mips__) && __BYTE_ORDER == __BIG_ENDIAN && _MIPS_SIM == _MIPS_SIM_NABI32
+ SCMP_ARCH_MIPSEL,
+ SCMP_ARCH_MIPS,
+ SCMP_ARCH_MIPSEL64,
+ SCMP_ARCH_MIPS64,
+ SCMP_ARCH_MIPSEL64N32,
+ SCMP_ARCH_MIPS64N32, /* native */
+#elif defined(__mips__) && __BYTE_ORDER == __LITTLE_ENDIAN && _MIPS_SIM == _MIPS_SIM_NABI32
+ SCMP_ARCH_MIPS,
+ SCMP_ARCH_MIPSEL,
+ SCMP_ARCH_MIPS64,
+ SCMP_ARCH_MIPSEL64,
+ SCMP_ARCH_MIPS64N32,
+ SCMP_ARCH_MIPSEL64N32, /* native */
+#elif defined(__powerpc64__) && __BYTE_ORDER == __BIG_ENDIAN
+ SCMP_ARCH_PPC,
+ SCMP_ARCH_PPC64LE,
+ SCMP_ARCH_PPC64, /* native */
+#elif defined(__powerpc64__) && __BYTE_ORDER == __LITTLE_ENDIAN
+ SCMP_ARCH_PPC,
+ SCMP_ARCH_PPC64,
+ SCMP_ARCH_PPC64LE, /* native */
+#elif defined(__powerpc__)
+ SCMP_ARCH_PPC,
+#elif defined(__s390x__)
+ SCMP_ARCH_S390,
+ SCMP_ARCH_S390X, /* native */
+#elif defined(__s390__)
+ SCMP_ARCH_S390,
+#endif
+ (uint32_t) -1
+ };
const char* seccomp_arch_to_string(uint32_t c) {
/* Maintain order used in <seccomp.h>.
@@ -120,18 +198,37 @@ int seccomp_arch_from_string(const char *n, uint32_t *ret) {
return 0;
}
-int seccomp_init_conservative(scmp_filter_ctx *ret, uint32_t default_action) {
+int seccomp_init_for_arch(scmp_filter_ctx *ret, uint32_t arch, uint32_t default_action) {
scmp_filter_ctx seccomp;
int r;
- /* Much like seccomp_init(), but tries to be a bit more conservative in its defaults: all secondary archs are
- * added by default, and NNP is turned off. */
+ /* Much like seccomp_init(), but initializes the filter for one specific architecture only, without affecting
+ * any others. Also, turns off the NNP fiddling. */
seccomp = seccomp_init(default_action);
if (!seccomp)
return -ENOMEM;
- r = seccomp_add_secondary_archs(seccomp);
+ if (arch != SCMP_ARCH_NATIVE &&
+ arch != seccomp_arch_native()) {
+
+ r = seccomp_arch_remove(seccomp, seccomp_arch_native());
+ if (r < 0)
+ goto finish;
+
+ r = seccomp_arch_add(seccomp, arch);
+ if (r < 0)
+ goto finish;
+
+ assert(seccomp_arch_exist(seccomp, arch) >= 0);
+ assert(seccomp_arch_exist(seccomp, SCMP_ARCH_NATIVE) == -EEXIST);
+ assert(seccomp_arch_exist(seccomp, seccomp_arch_native()) == -EEXIST);
+ } else {
+ assert(seccomp_arch_exist(seccomp, SCMP_ARCH_NATIVE) >= 0);
+ assert(seccomp_arch_exist(seccomp, seccomp_arch_native()) >= 0);
+ }
+
+ r = seccomp_attr_set(seccomp, SCMP_FLTATR_ACT_BADARCH, SCMP_ACT_ALLOW);
if (r < 0)
goto finish;
@@ -147,79 +244,48 @@ finish:
return r;
}
-int seccomp_add_secondary_archs(scmp_filter_ctx ctx) {
-
- /* Add in all possible secondary archs we are aware of that
- * this kernel might support. */
-
- static const int seccomp_arches[] = {
-#if defined(__i386__) || defined(__x86_64__)
- SCMP_ARCH_X86,
- SCMP_ARCH_X86_64,
- SCMP_ARCH_X32,
-
-#elif defined(__arm__) || defined(__aarch64__)
- SCMP_ARCH_ARM,
- SCMP_ARCH_AARCH64,
-
-#elif defined(__arm__) || defined(__aarch64__)
- SCMP_ARCH_ARM,
- SCMP_ARCH_AARCH64,
-
-#elif defined(__mips__) || defined(__mips64__)
- SCMP_ARCH_MIPS,
- SCMP_ARCH_MIPS64,
- SCMP_ARCH_MIPS64N32,
- SCMP_ARCH_MIPSEL,
- SCMP_ARCH_MIPSEL64,
- SCMP_ARCH_MIPSEL64N32,
-
-#elif defined(__powerpc__) || defined(__powerpc64__)
- SCMP_ARCH_PPC,
- SCMP_ARCH_PPC64,
- SCMP_ARCH_PPC64LE,
-
-#elif defined(__s390__) || defined(__s390x__)
- SCMP_ARCH_S390,
- SCMP_ARCH_S390X,
-#endif
- };
-
- unsigned i;
- int r;
-
- for (i = 0; i < ELEMENTSOF(seccomp_arches); i++) {
- r = seccomp_arch_add(ctx, seccomp_arches[i]);
- if (r < 0 && r != -EEXIST)
- return r;
- }
-
- return 0;
-}
-
static bool is_basic_seccomp_available(void) {
- int r;
- r = prctl(PR_GET_SECCOMP, 0, 0, 0, 0);
- return r >= 0;
+ return prctl(PR_GET_SECCOMP, 0, 0, 0, 0) >= 0;
}
static bool is_seccomp_filter_available(void) {
- int r;
- r = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0);
- return r < 0 && errno == EFAULT;
+ return prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0) < 0 &&
+ errno == EFAULT;
}
bool is_seccomp_available(void) {
static int cached_enabled = -1;
+
if (cached_enabled < 0)
- cached_enabled = is_basic_seccomp_available() && is_seccomp_filter_available();
+ cached_enabled =
+ is_basic_seccomp_available() &&
+ is_seccomp_filter_available();
+
return cached_enabled;
}
const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
+ [SYSCALL_FILTER_SET_DEFAULT] = {
+ .name = "@default",
+ .help = "System calls that are always permitted",
+ .value =
+ "clock_getres\0"
+ "clock_gettime\0"
+ "clock_nanosleep\0"
+ "execve\0"
+ "exit\0"
+ "exit_group\0"
+ "getrlimit\0" /* make sure processes can query stack size and such */
+ "gettimeofday\0"
+ "nanosleep\0"
+ "pause\0"
+ "rt_sigreturn\0"
+ "sigreturn\0"
+ "time\0"
+ },
[SYSCALL_FILTER_SET_BASIC_IO] = {
- /* Basic IO */
.name = "@basic-io",
+ .help = "Basic IO",
.value =
"close\0"
"dup2\0"
@@ -236,8 +302,8 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
"writev\0"
},
[SYSCALL_FILTER_SET_CLOCK] = {
- /* Clock */
.name = "@clock",
+ .help = "Change the system time",
.value =
"adjtimex\0"
"clock_adjtime\0"
@@ -246,8 +312,8 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
"stime\0"
},
[SYSCALL_FILTER_SET_CPU_EMULATION] = {
- /* CPU emulation calls */
.name = "@cpu-emulation",
+ .help = "System calls for CPU emulation functionality",
.value =
"modify_ldt\0"
"subpage_prot\0"
@@ -256,8 +322,8 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
"vm86old\0"
},
[SYSCALL_FILTER_SET_DEBUG] = {
- /* Debugging/Performance Monitoring/Tracing */
.name = "@debug",
+ .help = "Debugging, performance monitoring and tracing functionality",
.value =
"lookup_dcookie\0"
"perf_event_open\0"
@@ -270,27 +336,82 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
#endif
"sys_debug_setcontext\0"
},
- [SYSCALL_FILTER_SET_DEFAULT] = {
- /* Default list: the most basic of operations */
- .name = "@default",
+ [SYSCALL_FILTER_SET_FILE_SYSTEM] = {
+ .name = "@file-system",
+ .help = "File system operations",
.value =
- "clock_getres\0"
- "clock_gettime\0"
- "clock_nanosleep\0"
- "execve\0"
- "exit\0"
- "exit_group\0"
- "getrlimit\0" /* make sure processes can query stack size and such */
- "gettimeofday\0"
- "nanosleep\0"
- "pause\0"
- "rt_sigreturn\0"
- "sigreturn\0"
- "time\0"
+ "access\0"
+ "chdir\0"
+ "chmod\0"
+ "close\0"
+ "creat\0"
+ "faccessat\0"
+ "fallocate\0"
+ "fchdir\0"
+ "fchmod\0"
+ "fchmodat\0"
+ "fcntl64\0"
+ "fcntl\0"
+ "fgetxattr\0"
+ "flistxattr\0"
+ "fsetxattr\0"
+ "fstat64\0"
+ "fstat\0"
+ "fstatat64\0"
+ "fstatfs64\0"
+ "fstatfs\0"
+ "ftruncate64\0"
+ "ftruncate\0"
+ "futimesat\0"
+ "getcwd\0"
+ "getdents64\0"
+ "getdents\0"
+ "getxattr\0"
+ "inotify_add_watch\0"
+ "inotify_init1\0"
+ "inotify_rm_watch\0"
+ "lgetxattr\0"
+ "link\0"
+ "linkat\0"
+ "listxattr\0"
+ "llistxattr\0"
+ "lremovexattr\0"
+ "lsetxattr\0"
+ "lstat64\0"
+ "lstat\0"
+ "mkdir\0"
+ "mkdirat\0"
+ "mknod\0"
+ "mknodat\0"
+ "mmap2\0"
+ "mmap\0"
+ "munmap\0"
+ "newfstatat\0"
+ "open\0"
+ "openat\0"
+ "readlink\0"
+ "readlinkat\0"
+ "removexattr\0"
+ "rename\0"
+ "renameat2\0"
+ "renameat\0"
+ "rmdir\0"
+ "setxattr\0"
+ "stat64\0"
+ "stat\0"
+ "statfs\0"
+ "symlink\0"
+ "symlinkat\0"
+ "truncate64\0"
+ "truncate\0"
+ "unlink\0"
+ "unlinkat\0"
+ "utimensat\0"
+ "utimes\0"
},
[SYSCALL_FILTER_SET_IO_EVENT] = {
- /* Event loop use */
.name = "@io-event",
+ .help = "Event loop system calls",
.value =
"_newselect\0"
"epoll_create1\0"
@@ -308,9 +429,10 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
"select\0"
},
[SYSCALL_FILTER_SET_IPC] = {
- /* Message queues, SYSV IPC or other IPC */
.name = "@ipc",
- .value = "ipc\0"
+ .help = "SysV IPC, POSIX Message Queues or other IPC",
+ .value =
+ "ipc\0"
"memfd_create\0"
"mq_getsetattr\0"
"mq_notify\0"
@@ -336,24 +458,24 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
"shmget\0"
},
[SYSCALL_FILTER_SET_KEYRING] = {
- /* Keyring */
.name = "@keyring",
+ .help = "Kernel keyring access",
.value =
"add_key\0"
"keyctl\0"
"request_key\0"
},
[SYSCALL_FILTER_SET_MODULE] = {
- /* Kernel module control */
.name = "@module",
+ .help = "Loading and unloading of kernel modules",
.value =
"delete_module\0"
"finit_module\0"
"init_module\0"
},
[SYSCALL_FILTER_SET_MOUNT] = {
- /* Mounting */
.name = "@mount",
+ .help = "Mounting and unmounting of file systems",
.value =
"chroot\0"
"mount\0"
@@ -362,8 +484,8 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
"umount\0"
},
[SYSCALL_FILTER_SET_NETWORK_IO] = {
- /* Network or Unix socket IO, should not be needed if not network facing */
.name = "@network-io",
+ .help = "Network or Unix socket IO, should not be needed if not network facing",
.value =
"accept4\0"
"accept\0"
@@ -388,11 +510,13 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
"socketpair\0"
},
[SYSCALL_FILTER_SET_OBSOLETE] = {
- /* Unusual, obsolete or unimplemented, some unknown even to libseccomp */
+ /* some unknown even to libseccomp */
.name = "@obsolete",
+ .help = "Unusual, obsolete or unimplemented system calls",
.value =
"_sysctl\0"
"afs_syscall\0"
+ "bdflush\0"
"break\0"
"create_module\0"
"ftime\0"
@@ -417,14 +541,13 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
"vserver\0"
},
[SYSCALL_FILTER_SET_PRIVILEGED] = {
- /* Nice grab-bag of all system calls which need superuser capabilities */
.name = "@privileged",
+ .help = "All system calls which need super-user capabilities",
.value =
"@clock\0"
"@module\0"
"@raw-io\0"
"acct\0"
- "bdflush\0"
"bpf\0"
"capset\0"
"chown32\0"
@@ -459,8 +582,8 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
"vhangup\0"
},
[SYSCALL_FILTER_SET_PROCESS] = {
- /* Process control, execution, namespaces */
.name = "@process",
+ .help = "Process control, execution, namespaceing operations",
.value =
"arch_prctl\0"
"clone\0"
@@ -475,8 +598,8 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
"vfork\0"
},
[SYSCALL_FILTER_SET_RAW_IO] = {
- /* Raw I/O ports */
.name = "@raw-io",
+ .help = "Raw I/O port access",
.value =
"ioperm\0"
"iopl\0"
@@ -490,9 +613,17 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
"s390_pci_mmio_write\0"
#endif
},
+ [SYSCALL_FILTER_SET_REBOOT] = {
+ .name = "@reboot",
+ .help = "Reboot and reboot preparation/kexec",
+ .value =
+ "kexec\0"
+ "kexec_file_load\0"
+ "reboot\0"
+ },
[SYSCALL_FILTER_SET_RESOURCES] = {
- /* Alter resource settings */
.name = "@resources",
+ .help = "Alter resource settings",
.value =
"sched_setparam\0"
"sched_setscheduler\0"
@@ -506,6 +637,13 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
"sched_setattr\0"
"prlimit64\0"
},
+ [SYSCALL_FILTER_SET_SWAP] = {
+ .name = "@swap",
+ .help = "Enable/disable swap devices",
+ .value =
+ "swapoff\0"
+ "swapon\0"
+ },
};
const SyscallFilterSet *syscall_filter_set_find(const char *name) {
@@ -521,7 +659,12 @@ const SyscallFilterSet *syscall_filter_set_find(const char *name) {
return NULL;
}
-int seccomp_add_syscall_filter_set(scmp_filter_ctx seccomp, const SyscallFilterSet *set, uint32_t action) {
+static int seccomp_add_syscall_filter_set(
+ scmp_filter_ctx seccomp,
+ uint32_t default_action,
+ const SyscallFilterSet *set,
+ uint32_t action) {
+
const char *sys;
int r;
@@ -538,41 +681,647 @@ int seccomp_add_syscall_filter_set(scmp_filter_ctx seccomp, const SyscallFilterS
if (!other)
return -EINVAL;
- r = seccomp_add_syscall_filter_set(seccomp, other, action);
+ r = seccomp_add_syscall_filter_set(seccomp, default_action, other, action);
+ if (r < 0)
+ return r;
} else {
id = seccomp_syscall_resolve_name(sys);
if (id == __NR_SCMP_ERROR)
- return -EINVAL;
+ return -EINVAL; /* Not known at all? Then that's a real error */
- r = seccomp_rule_add(seccomp, action, id, 0);
+ r = seccomp_rule_add_exact(seccomp, action, id, 0);
+ if (r < 0)
+ /* If the system call is not known on this architecture, then that's fine, let's ignore it */
+ log_debug_errno(r, "Failed to add rule for system call %s, ignoring: %m", sys);
}
+ }
+
+ return 0;
+}
+
+int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action) {
+ uint32_t arch;
+ int r;
+
+ assert(set);
+
+ /* The one-stop solution: allocate a seccomp object, add the specified filter to it, and apply it. Once for
+ * earch local arch. */
+
+ SECCOMP_FOREACH_LOCAL_ARCH(arch) {
+ _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
+
+ log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch));
+
+ r = seccomp_init_for_arch(&seccomp, arch, default_action);
if (r < 0)
return r;
+
+ r = seccomp_add_syscall_filter_set(seccomp, default_action, set, action);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to add filter set, ignoring: %m");
+ continue;
+ }
+
+ r = seccomp_load(seccomp);
+ if (IN_SET(r, -EPERM, -EACCES))
+ return r;
+ if (r < 0)
+ log_debug_errno(r, "Failed to install filter set for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
}
return 0;
}
-int seccomp_load_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action) {
- scmp_filter_ctx seccomp;
+int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Set* set, uint32_t action) {
+ uint32_t arch;
int r;
- assert(set);
+ /* Similar to seccomp_load_syscall_filter_set(), but takes a raw Set* of syscalls, instead of a
+ * SyscallFilterSet* table. */
- /* The one-stop solution: allocate a seccomp object, add a filter to it, and apply it */
+ if (set_isempty(set) && default_action == SCMP_ACT_ALLOW)
+ return 0;
- r = seccomp_init_conservative(&seccomp, default_action);
- if (r < 0)
- return r;
+ SECCOMP_FOREACH_LOCAL_ARCH(arch) {
+ _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
+ Iterator i;
+ void *id;
- r = seccomp_add_syscall_filter_set(seccomp, set, action);
- if (r < 0)
- goto finish;
+ log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch));
- r = seccomp_load(seccomp);
+ r = seccomp_init_for_arch(&seccomp, arch, default_action);
+ if (r < 0)
+ return r;
-finish:
- seccomp_release(seccomp);
- return r;
+ SET_FOREACH(id, set, i) {
+ r = seccomp_rule_add_exact(seccomp, action, PTR_TO_INT(id) - 1, 0);
+ if (r < 0) {
+ /* If the system call is not known on this architecture, then that's fine, let's ignore it */
+ _cleanup_free_ char *n = NULL;
+
+ n = seccomp_syscall_resolve_num_arch(arch, PTR_TO_INT(id) - 1);
+ log_debug_errno(r, "Failed to add rule for system call %s, ignoring: %m", strna(n));
+ }
+ }
+
+ r = seccomp_load(seccomp);
+ if (IN_SET(r, -EPERM, -EACCES))
+ return r;
+ if (r < 0)
+ log_debug_errno(r, "Failed to install filter set for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ }
+
+ return 0;
+}
+
+int seccomp_restrict_namespaces(unsigned long retain) {
+ uint32_t arch;
+ int r;
+
+ if (log_get_max_level() >= LOG_DEBUG) {
+ _cleanup_free_ char *s = NULL;
+
+ (void) namespace_flag_to_string_many(retain, &s);
+ log_debug("Restricting namespace to: %s.", strna(s));
+ }
+
+ /* NOOP? */
+ if ((retain & NAMESPACE_FLAGS_ALL) == NAMESPACE_FLAGS_ALL)
+ return 0;
+
+ SECCOMP_FOREACH_LOCAL_ARCH(arch) {
+ _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
+ int clone_reversed_order = -1;
+ unsigned i;
+
+ log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch));
+
+ switch (arch) {
+
+ case SCMP_ARCH_X86_64:
+ case SCMP_ARCH_X86:
+ case SCMP_ARCH_X32:
+ case SCMP_ARCH_PPC64:
+ case SCMP_ARCH_PPC64LE:
+ clone_reversed_order = 0;
+ break;
+
+ case SCMP_ARCH_S390:
+ case SCMP_ARCH_S390X:
+ /* On s390/s390x the first two parameters to clone are switched */
+ clone_reversed_order = 1;
+ break;
+
+ /* Please add more definitions here, if you port systemd to other architectures! */
+
+#if SECCOMP_RESTRICT_NAMESPACES_BROKEN
+# warning "Consider adding the right clone() syscall definitions here!"
+#endif
+ }
+
+ if (clone_reversed_order < 0) /* we don't know the right order, let's ignore this arch... */
+ continue;
+
+ r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ALLOW);
+ if (r < 0)
+ return r;
+
+ if ((retain & NAMESPACE_FLAGS_ALL) == 0)
+ /* If every single kind of namespace shall be prohibited, then let's block the whole setns() syscall
+ * altogether. */
+ r = seccomp_rule_add_exact(
+ seccomp,
+ SCMP_ACT_ERRNO(EPERM),
+ SCMP_SYS(setns),
+ 0);
+ else
+ /* Otherwise, block only the invocations with the appropriate flags in the loop below, but also the
+ * special invocation with a zero flags argument, right here. */
+ r = seccomp_rule_add_exact(
+ seccomp,
+ SCMP_ACT_ERRNO(EPERM),
+ SCMP_SYS(setns),
+ 1,
+ SCMP_A1(SCMP_CMP_EQ, 0));
+ if (r < 0) {
+ log_debug_errno(r, "Failed to add setns() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ continue;
+ }
+
+ for (i = 0; namespace_flag_map[i].name; i++) {
+ unsigned long f;
+
+ f = namespace_flag_map[i].flag;
+ if ((retain & f) == f) {
+ log_debug("Permitting %s.", namespace_flag_map[i].name);
+ continue;
+ }
+
+ log_debug("Blocking %s.", namespace_flag_map[i].name);
+
+ r = seccomp_rule_add_exact(
+ seccomp,
+ SCMP_ACT_ERRNO(EPERM),
+ SCMP_SYS(unshare),
+ 1,
+ SCMP_A0(SCMP_CMP_MASKED_EQ, f, f));
+ if (r < 0) {
+ log_debug_errno(r, "Failed to add unshare() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ break;
+ }
+
+ if (clone_reversed_order == 0)
+ r = seccomp_rule_add_exact(
+ seccomp,
+ SCMP_ACT_ERRNO(EPERM),
+ SCMP_SYS(clone),
+ 1,
+ SCMP_A0(SCMP_CMP_MASKED_EQ, f, f));
+ else
+ r = seccomp_rule_add_exact(
+ seccomp,
+ SCMP_ACT_ERRNO(EPERM),
+ SCMP_SYS(clone),
+ 1,
+ SCMP_A1(SCMP_CMP_MASKED_EQ, f, f));
+ if (r < 0) {
+ log_debug_errno(r, "Failed to add clone() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ break;
+ }
+
+ if ((retain & NAMESPACE_FLAGS_ALL) != 0) {
+ r = seccomp_rule_add_exact(
+ seccomp,
+ SCMP_ACT_ERRNO(EPERM),
+ SCMP_SYS(setns),
+ 1,
+ SCMP_A1(SCMP_CMP_MASKED_EQ, f, f));
+ if (r < 0) {
+ log_debug_errno(r, "Failed to add setns() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ break;
+ }
+ }
+ }
+ if (r < 0)
+ continue;
+
+ r = seccomp_load(seccomp);
+ if (IN_SET(r, -EPERM, -EACCES))
+ return r;
+ if (r < 0)
+ log_debug_errno(r, "Failed to install namespace restriction rules for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ }
+
+ return 0;
+}
+
+int seccomp_protect_sysctl(void) {
+ uint32_t arch;
+ int r;
+
+ SECCOMP_FOREACH_LOCAL_ARCH(arch) {
+ _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
+
+ log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch));
+
+ r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ALLOW);
+ if (r < 0)
+ return r;
+
+ r = seccomp_rule_add_exact(
+ seccomp,
+ SCMP_ACT_ERRNO(EPERM),
+ SCMP_SYS(_sysctl),
+ 0);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to add _sysctl() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ continue;
+ }
+
+ r = seccomp_load(seccomp);
+ if (IN_SET(r, -EPERM, -EACCES))
+ return r;
+ if (r < 0)
+ log_debug_errno(r, "Failed to install sysctl protection rules for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ }
+
+ return 0;
+}
+
+int seccomp_restrict_address_families(Set *address_families, bool whitelist) {
+ uint32_t arch;
+ int r;
+
+ SECCOMP_FOREACH_LOCAL_ARCH(arch) {
+ _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
+ bool supported;
+ Iterator i;
+
+ log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch));
+
+ switch (arch) {
+
+ case SCMP_ARCH_X86_64:
+ case SCMP_ARCH_X32:
+ case SCMP_ARCH_ARM:
+ case SCMP_ARCH_AARCH64:
+ /* These we know we support (i.e. are the ones that do not use socketcall()) */
+ supported = true;
+ break;
+
+ case SCMP_ARCH_X86:
+ case SCMP_ARCH_S390:
+ case SCMP_ARCH_S390X:
+ case SCMP_ARCH_PPC:
+ case SCMP_ARCH_PPC64:
+ case SCMP_ARCH_PPC64LE:
+ default:
+ /* These we either know we don't support (i.e. are the ones that do use socketcall()), or we
+ * don't know */
+ supported = false;
+ break;
+ }
+
+ if (!supported)
+ continue;
+
+ r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ALLOW);
+ if (r < 0)
+ return r;
+
+ if (whitelist) {
+ int af, first = 0, last = 0;
+ void *afp;
+
+ /* If this is a whitelist, we first block the address families that are out of range and then
+ * everything that is not in the set. First, we find the lowest and highest address family in
+ * the set. */
+
+ SET_FOREACH(afp, address_families, i) {
+ af = PTR_TO_INT(afp);
+
+ if (af <= 0 || af >= af_max())
+ continue;
+
+ if (first == 0 || af < first)
+ first = af;
+
+ if (last == 0 || af > last)
+ last = af;
+ }
+
+ assert((first == 0) == (last == 0));
+
+ if (first == 0) {
+
+ /* No entries in the valid range, block everything */
+ r = seccomp_rule_add_exact(
+ seccomp,
+ SCMP_ACT_ERRNO(EAFNOSUPPORT),
+ SCMP_SYS(socket),
+ 0);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to add socket() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ continue;
+ }
+
+ } else {
+
+ /* Block everything below the first entry */
+ r = seccomp_rule_add_exact(
+ seccomp,
+ SCMP_ACT_ERRNO(EAFNOSUPPORT),
+ SCMP_SYS(socket),
+ 1,
+ SCMP_A0(SCMP_CMP_LT, first));
+ if (r < 0) {
+ log_debug_errno(r, "Failed to add socket() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ continue;
+ }
+
+ /* Block everything above the last entry */
+ r = seccomp_rule_add_exact(
+ seccomp,
+ SCMP_ACT_ERRNO(EAFNOSUPPORT),
+ SCMP_SYS(socket),
+ 1,
+ SCMP_A0(SCMP_CMP_GT, last));
+ if (r < 0) {
+ log_debug_errno(r, "Failed to add socket() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ continue;
+ }
+
+ /* Block everything between the first and last entry */
+ for (af = 1; af < af_max(); af++) {
+
+ if (set_contains(address_families, INT_TO_PTR(af)))
+ continue;
+
+ r = seccomp_rule_add_exact(
+ seccomp,
+ SCMP_ACT_ERRNO(EAFNOSUPPORT),
+ SCMP_SYS(socket),
+ 1,
+ SCMP_A0(SCMP_CMP_EQ, af));
+ if (r < 0)
+ break;
+ }
+
+ if (r < 0) {
+ log_debug_errno(r, "Failed to add socket() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ continue;
+ }
+ }
+
+ } else {
+ void *af;
+
+ /* If this is a blacklist, then generate one rule for
+ * each address family that are then combined in OR
+ * checks. */
+
+ SET_FOREACH(af, address_families, i) {
+
+ r = seccomp_rule_add_exact(
+ seccomp,
+ SCMP_ACT_ERRNO(EAFNOSUPPORT),
+ SCMP_SYS(socket),
+ 1,
+ SCMP_A0(SCMP_CMP_EQ, PTR_TO_INT(af)));
+ if (r < 0)
+ break;
+ }
+
+ if (r < 0) {
+ log_debug_errno(r, "Failed to add socket() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ continue;
+ }
+ }
+
+ r = seccomp_load(seccomp);
+ if (IN_SET(r, -EPERM, -EACCES))
+ return r;
+ if (r < 0)
+ log_debug_errno(r, "Failed to install socket family rules for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ }
+
+ return 0;
+}
+
+int seccomp_restrict_realtime(void) {
+ static const int permitted_policies[] = {
+ SCHED_OTHER,
+ SCHED_BATCH,
+ SCHED_IDLE,
+ };
+
+ int r, max_policy = 0;
+ uint32_t arch;
+ unsigned i;
+
+ /* Determine the highest policy constant we want to allow */
+ for (i = 0; i < ELEMENTSOF(permitted_policies); i++)
+ if (permitted_policies[i] > max_policy)
+ max_policy = permitted_policies[i];
+
+ SECCOMP_FOREACH_LOCAL_ARCH(arch) {
+ _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
+ int p;
+
+ log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch));
+
+ r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ALLOW);
+ if (r < 0)
+ return r;
+
+ /* Go through all policies with lower values than that, and block them -- unless they appear in the
+ * whitelist. */
+ for (p = 0; p < max_policy; p++) {
+ bool good = false;
+
+ /* Check if this is in the whitelist. */
+ for (i = 0; i < ELEMENTSOF(permitted_policies); i++)
+ if (permitted_policies[i] == p) {
+ good = true;
+ break;
+ }
+
+ if (good)
+ continue;
+
+ /* Deny this policy */
+ r = seccomp_rule_add_exact(
+ seccomp,
+ SCMP_ACT_ERRNO(EPERM),
+ SCMP_SYS(sched_setscheduler),
+ 1,
+ SCMP_A1(SCMP_CMP_EQ, p));
+ if (r < 0) {
+ log_debug_errno(r, "Failed to add scheduler rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ continue;
+ }
+ }
+
+ /* Blacklist all other policies, i.e. the ones with higher values. Note that all comparisons are
+ * unsigned here, hence no need no check for < 0 values. */
+ r = seccomp_rule_add_exact(
+ seccomp,
+ SCMP_ACT_ERRNO(EPERM),
+ SCMP_SYS(sched_setscheduler),
+ 1,
+ SCMP_A1(SCMP_CMP_GT, max_policy));
+ if (r < 0) {
+ log_debug_errno(r, "Failed to add scheduler rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ continue;
+ }
+
+ r = seccomp_load(seccomp);
+ if (IN_SET(r, -EPERM, -EACCES))
+ return r;
+ if (r < 0)
+ log_debug_errno(r, "Failed to install realtime protection rules for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ }
+
+ return 0;
+}
+
+int seccomp_memory_deny_write_execute(void) {
+
+ uint32_t arch;
+ int r;
+
+ SECCOMP_FOREACH_LOCAL_ARCH(arch) {
+ _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
+ int filter_syscall = 0, block_syscall = 0, shmat_syscall = 0;
+
+ log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch));
+
+ switch (arch) {
+
+ case SCMP_ARCH_X86:
+ filter_syscall = SCMP_SYS(mmap2);
+ block_syscall = SCMP_SYS(mmap);
+
+ /* Note that shmat() isn't available on i386, where the call is multiplexed through ipc(). We
+ * ignore that here, which means there's still a way to get writable/executable memory, if an
+ * IPC key is mapped like this on i386. That's a pity, but no total loss. */
+ break;
+
+ case SCMP_ARCH_X86_64:
+ case SCMP_ARCH_X32:
+ filter_syscall = SCMP_SYS(mmap);
+ shmat_syscall = SCMP_SYS(shmat);
+ break;
+
+ /* Please add more definitions here, if you port systemd to other architectures! */
+
+#if !defined(__i386__) && !defined(__x86_64__)
+#warning "Consider adding the right mmap() syscall definitions here!"
+#endif
+ }
+
+ /* Can't filter mmap() on this arch, then skip it */
+ if (filter_syscall == 0)
+ continue;
+
+ r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ALLOW);
+ if (r < 0)
+ return r;
+
+ if (filter_syscall != 0) {
+ r = seccomp_rule_add_exact(
+ seccomp,
+ SCMP_ACT_ERRNO(EPERM),
+ filter_syscall,
+ 1,
+ SCMP_A2(SCMP_CMP_MASKED_EQ, PROT_EXEC|PROT_WRITE, PROT_EXEC|PROT_WRITE));
+ if (r < 0) {
+ _cleanup_free_ char *n = NULL;
+
+ n = seccomp_syscall_resolve_num_arch(arch, filter_syscall);
+ log_debug_errno(r, "Failed to add %s() rule for architecture %s, skipping: %m",
+ strna(n),
+ seccomp_arch_to_string(arch));
+ continue;
+ }
+ }
+
+ if (block_syscall != 0) {
+ r = seccomp_rule_add_exact(
+ seccomp,
+ SCMP_ACT_ERRNO(EPERM),
+ block_syscall,
+ 0);
+ if (r < 0) {
+ _cleanup_free_ char *n = NULL;
+
+ n = seccomp_syscall_resolve_num_arch(arch, block_syscall);
+ log_debug_errno(r, "Failed to add %s() rule for architecture %s, skipping: %m",
+ strna(n),
+ seccomp_arch_to_string(arch));
+ continue;
+ }
+ }
+
+ r = seccomp_rule_add_exact(
+ seccomp,
+ SCMP_ACT_ERRNO(EPERM),
+ SCMP_SYS(mprotect),
+ 1,
+ SCMP_A2(SCMP_CMP_MASKED_EQ, PROT_EXEC, PROT_EXEC));
+ if (r < 0) {
+ log_debug_errno(r, "Failed to add mprotect() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ continue;
+ }
+
+ if (shmat_syscall != 0) {
+ r = seccomp_rule_add_exact(
+ seccomp,
+ SCMP_ACT_ERRNO(EPERM),
+ SCMP_SYS(shmat),
+ 1,
+ SCMP_A2(SCMP_CMP_MASKED_EQ, SHM_EXEC, SHM_EXEC));
+ if (r < 0) {
+ log_debug_errno(r, "Failed to add shmat() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ continue;
+ }
+ }
+
+ r = seccomp_load(seccomp);
+ if (IN_SET(r, -EPERM, -EACCES))
+ return r;
+ if (r < 0)
+ log_debug_errno(r, "Failed to install MemoryDenyWriteExecute= rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ }
+
+ return 0;
+}
+
+int seccomp_restrict_archs(Set *archs) {
+ _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
+ Iterator i;
+ void *id;
+ int r;
+
+ /* This installs a filter with no rules, but that restricts the system call architectures to the specified
+ * list. */
+
+ seccomp = seccomp_init(SCMP_ACT_ALLOW);
+ if (!seccomp)
+ return -ENOMEM;
+
+ SET_FOREACH(id, archs, i) {
+ r = seccomp_arch_add(seccomp, PTR_TO_UINT32(id) - 1);
+ if (r == -EEXIST)
+ continue;
+ if (r < 0)
+ return r;
+ }
+
+ r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
+ if (r < 0)
+ return r;
+ return seccomp_load(seccomp);
}
diff --git a/src/shared/seccomp-util.h b/src/shared/seccomp-util.h
index 8e209efef2..b56ac3f763 100644
--- a/src/shared/seccomp-util.h
+++ b/src/shared/seccomp-util.h
@@ -23,26 +23,29 @@
#include <stdbool.h>
#include <stdint.h>
+#include "set.h"
+
const char* seccomp_arch_to_string(uint32_t c);
int seccomp_arch_from_string(const char *n, uint32_t *ret);
-int seccomp_init_conservative(scmp_filter_ctx *ret, uint32_t default_action);
-
-int seccomp_add_secondary_archs(scmp_filter_ctx c);
+int seccomp_init_for_arch(scmp_filter_ctx *ret, uint32_t arch, uint32_t default_action);
bool is_seccomp_available(void);
typedef struct SyscallFilterSet {
const char *name;
+ const char *help;
const char *value;
} SyscallFilterSet;
enum {
+ /* Please leave DEFAULT first, but sort the rest alphabetically */
+ SYSCALL_FILTER_SET_DEFAULT,
SYSCALL_FILTER_SET_BASIC_IO,
SYSCALL_FILTER_SET_CLOCK,
SYSCALL_FILTER_SET_CPU_EMULATION,
SYSCALL_FILTER_SET_DEBUG,
- SYSCALL_FILTER_SET_DEFAULT,
+ SYSCALL_FILTER_SET_FILE_SYSTEM,
SYSCALL_FILTER_SET_IO_EVENT,
SYSCALL_FILTER_SET_IPC,
SYSCALL_FILTER_SET_KEYRING,
@@ -53,7 +56,9 @@ enum {
SYSCALL_FILTER_SET_PRIVILEGED,
SYSCALL_FILTER_SET_PROCESS,
SYSCALL_FILTER_SET_RAW_IO,
+ SYSCALL_FILTER_SET_REBOOT,
SYSCALL_FILTER_SET_RESOURCES,
+ SYSCALL_FILTER_SET_SWAP,
_SYSCALL_FILTER_SET_MAX
};
@@ -61,6 +66,43 @@ extern const SyscallFilterSet syscall_filter_sets[];
const SyscallFilterSet *syscall_filter_set_find(const char *name);
-int seccomp_add_syscall_filter_set(scmp_filter_ctx seccomp, const SyscallFilterSet *set, uint32_t action);
-
-int seccomp_load_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action);
+int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action);
+int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Set* set, uint32_t action);
+
+int seccomp_restrict_archs(Set *archs);
+int seccomp_restrict_namespaces(unsigned long retain);
+int seccomp_protect_sysctl(void);
+int seccomp_restrict_address_families(Set *address_families, bool whitelist);
+int seccomp_restrict_realtime(void);
+int seccomp_memory_deny_write_execute(void);
+
+#if defined(__i386__) || defined(__s390x__) || defined(__s390__) || defined(__powerpc64__) || defined(__powerpc__) || defined (__mips__)
+/* On these archs, socket() is implemented via the socketcall() syscall multiplexer, and we can't restrict it hence via
+ * seccomp */
+#define SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN 1
+#else
+#define SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN 0
+#endif
+
+/* mmap() blocking is only available on some archs for now */
+#if defined(__x86_64__) || defined(__i386__)
+#define SECCOMP_MEMORY_DENY_WRITE_EXECUTE_BROKEN 0
+#else
+#define SECCOMP_MEMORY_DENY_WRITE_EXECUTE_BROKEN 1
+#endif
+
+/* we don't know the right order of the clone() parameters except for these archs, for now */
+#if defined(__x86_64__) || defined(__i386__) || defined(__s390x__) || defined(__s390__) || defined(__powerpc64__)
+#define SECCOMP_RESTRICT_NAMESPACES_BROKEN 0
+#else
+#define SECCOMP_RESTRICT_NAMESPACES_BROKEN 1
+#endif
+
+extern const uint32_t seccomp_local_archs[];
+
+#define SECCOMP_FOREACH_LOCAL_ARCH(arch) \
+ for (unsigned _i = ({ (arch) = seccomp_local_archs[0]; 0; }); \
+ seccomp_local_archs[_i] != (uint32_t) -1; \
+ (arch) = seccomp_local_archs[++_i])
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(scmp_filter_ctx, seccomp_release);
diff --git a/src/shared/switch-root.c b/src/shared/switch-root.c
index 4eff4f692e..afdf1ab5ad 100644
--- a/src/shared/switch-root.c
+++ b/src/shared/switch-root.c
@@ -28,123 +28,102 @@
#include "base-filesystem.h"
#include "fd-util.h"
+#include "fs-util.h"
#include "log.h"
#include "missing.h"
#include "mkdir.h"
+#include "mount-util.h"
#include "path-util.h"
#include "rm-rf.h"
#include "stdio-util.h"
#include "string-util.h"
+#include "strv.h"
#include "switch-root.h"
#include "user-util.h"
#include "util.h"
-int switch_root(const char *new_root, const char *oldroot, bool detach_oldroot, unsigned long mountflags) {
-
- /* Don't try to unmount/move the old "/", there's no way to do it. */
- static const char move_mounts[] =
- "/dev\0"
- "/proc\0"
- "/sys\0"
- "/run\0";
+int switch_root(const char *new_root,
+ const char *old_root_after, /* path below the new root, where to place the old root after the transition */
+ bool unmount_old_root,
+ unsigned long mount_flags) { /* MS_MOVE or MS_BIND */
+ _cleanup_free_ char *resolved_old_root_after = NULL;
_cleanup_close_ int old_root_fd = -1;
- struct stat new_root_stat;
bool old_root_remove;
- const char *i, *temporary_old_root;
+ const char *i;
+ int r;
+
+ assert(new_root);
+ assert(old_root_after);
if (path_equal(new_root, "/"))
return 0;
- temporary_old_root = strjoina(new_root, oldroot);
- mkdir_p_label(temporary_old_root, 0755);
-
+ /* Check if we shall remove the contents of the old root */
old_root_remove = in_initrd();
+ if (old_root_remove) {
+ old_root_fd = open("/", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY|O_DIRECTORY);
+ if (old_root_fd < 0)
+ return log_error_errno(errno, "Failed to open root directory: %m");
+ }
- if (stat(new_root, &new_root_stat) < 0)
- return log_error_errno(errno, "Failed to stat directory %s: %m", new_root);
+ /* Determine where we shall place the old root after the transition */
+ r = chase_symlinks(old_root_after, new_root, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &resolved_old_root_after);
+ if (r < 0)
+ return log_error_errno(r, "Failed to resolve %s/%s: %m", new_root, old_root_after);
+ if (r == 0) /* Doesn't exist yet. Let's create it */
+ (void) mkdir_p_label(resolved_old_root_after, 0755);
- /* Work-around for kernel design: the kernel refuses switching
- * root if any file systems are mounted MS_SHARED. Hence
+ /* Work-around for kernel design: the kernel refuses MS_MOVE if any file systems are mounted MS_SHARED. Hence
* remount them MS_PRIVATE here as a work-around.
*
* https://bugzilla.redhat.com/show_bug.cgi?id=847418 */
if (mount(NULL, "/", NULL, MS_REC|MS_PRIVATE, NULL) < 0)
- log_warning_errno(errno, "Failed to make \"/\" private mount: %m");
-
- NULSTR_FOREACH(i, move_mounts) {
- char new_mount[PATH_MAX];
- struct stat sb;
- size_t n;
-
- n = snprintf(new_mount, sizeof new_mount, "%s%s", new_root, i);
- if (n >= sizeof new_mount) {
- bool move = mountflags & MS_MOVE;
-
- log_warning("New path is too long, %s: %s%s",
- move ? "forcing unmount instead" : "ignoring",
- new_root, i);
-
- if (move)
- if (umount2(i, MNT_FORCE) < 0)
- log_warning_errno(errno, "Failed to unmount %s: %m", i);
- continue;
- }
-
- mkdir_p_label(new_mount, 0755);
-
- if (stat(new_mount, &sb) < 0 ||
- sb.st_dev != new_root_stat.st_dev) {
-
- /* Mount point seems to be mounted already or
- * stat failed. Unmount the old mount point. */
- if (umount2(i, MNT_DETACH) < 0)
- log_warning_errno(errno, "Failed to unmount %s: %m", i);
- continue;
- }
-
- if (mount(i, new_mount, NULL, mountflags, NULL) < 0) {
- if (mountflags & MS_MOVE) {
- log_error_errno(errno, "Failed to move mount %s to %s, forcing unmount: %m", i, new_mount);
-
- if (umount2(i, MNT_FORCE) < 0)
- log_warning_errno(errno, "Failed to unmount %s: %m", i);
-
- } else if (mountflags & MS_BIND)
- log_error_errno(errno, "Failed to bind mount %s to %s: %m", i, new_mount);
- }
+ return log_error_errno(errno, "Failed to set \"/\" mount propagation to private: %m");
+
+ FOREACH_STRING(i, "/sys", "/dev", "/run", "/proc") {
+ _cleanup_free_ char *chased = NULL;
+
+ r = chase_symlinks(i, new_root, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &chased);
+ if (r < 0)
+ return log_error_errno(r, "Failed to resolve %s/%s: %m", new_root, i);
+ if (r > 0) {
+ /* Already exists. Let's see if it is a mount point already. */
+ r = path_is_mount_point(chased, NULL, 0);
+ if (r < 0)
+ return log_error_errno(r, "Failed to determine whether %s is a mount point: %m", chased);
+ if (r > 0) /* If it is already mounted, then do nothing */
+ continue;
+ } else
+ /* Doesn't exist yet? */
+ (void) mkdir_p_label(chased, 0755);
+
+ if (mount(i, chased, NULL, mount_flags, NULL) < 0)
+ return log_error_errno(r, "Failed to mount %s to %s: %m", i, chased);
}
- /* Do not fail, if base_filesystem_create() fails. Not all
- * switch roots are like base_filesystem_create() wants them
- * to look like. They might even boot, if they are RO and
- * don't have the FS layout. Just ignore the error and
- * switch_root() nevertheless. */
+ /* Do not fail if base_filesystem_create() fails. Not all switch roots are like base_filesystem_create() wants
+ * them to look like. They might even boot, if they are RO and don't have the FS layout. Just ignore the error
+ * and switch_root() nevertheless. */
(void) base_filesystem_create(new_root, UID_INVALID, GID_INVALID);
if (chdir(new_root) < 0)
return log_error_errno(errno, "Failed to change directory to %s: %m", new_root);
- if (old_root_remove) {
- old_root_fd = open("/", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY|O_DIRECTORY);
- if (old_root_fd < 0)
- log_warning_errno(errno, "Failed to open root directory: %m");
- }
-
- /* We first try a pivot_root() so that we can umount the old
- * root dir. In many cases (i.e. where rootfs is /), that's
- * not possible however, and hence we simply overmount root */
- if (pivot_root(new_root, temporary_old_root) >= 0) {
+ /* We first try a pivot_root() so that we can umount the old root dir. In many cases (i.e. where rootfs is /),
+ * that's not possible however, and hence we simply overmount root */
+ if (pivot_root(new_root, resolved_old_root_after) >= 0) {
/* Immediately get rid of the old root, if detach_oldroot is set.
* Since we are running off it we need to do this lazily. */
- if (detach_oldroot && umount2(oldroot, MNT_DETACH) < 0)
- log_error_errno(errno, "Failed to lazily umount old root dir %s, %s: %m",
- oldroot,
- errno == ENOENT ? "ignoring" : "leaving it around");
+ if (unmount_old_root) {
+ r = umount_recursive(old_root_after, MNT_DETACH);
+ if (r < 0)
+ log_warning_errno(r, "Failed to unmount old root directory tree, ignoring: %m");
+ }
} else if (mount(new_root, "/", NULL, MS_MOVE, NULL) < 0)
- return log_error_errno(errno, "Failed to mount moving %s to /: %m", new_root);
+ return log_error_errno(errno, "Failed to move %s to /: %m", new_root);
if (chroot(".") < 0)
return log_error_errno(errno, "Failed to change root: %m");
diff --git a/src/shared/tests.c b/src/shared/tests.c
index 409116290d..f300bbc66f 100644
--- a/src/shared/tests.c
+++ b/src/shared/tests.c
@@ -17,10 +17,14 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <alloc-util.h>
+#include <fs-util.h>
+#include <libgen.h>
#include <stdlib.h>
#include <util.h>
#include "tests.h"
+#include "path-util.h"
char* setup_fake_runtime_dir(void) {
char t[] = "/tmp/fake-xdg-runtime-XXXXXX", *p;
@@ -31,3 +35,39 @@ char* setup_fake_runtime_dir(void) {
return p;
}
+
+const char* get_testdata_dir(const char *suffix) {
+ const char *env;
+ /* convenience: caller does not need to free result */
+ static char testdir[PATH_MAX];
+
+ /* if the env var is set, use that */
+ env = getenv("SYSTEMD_TEST_DATA");
+ testdir[sizeof(testdir) - 1] = '\0';
+ if (env) {
+ if (access(env, F_OK) < 0) {
+ fputs("ERROR: $SYSTEMD_TEST_DATA directory does not exist\n", stderr);
+ exit(1);
+ }
+ strncpy(testdir, env, sizeof(testdir) - 1);
+ } else {
+ _cleanup_free_ char *exedir = NULL;
+ assert_se(readlink_and_make_absolute("/proc/self/exe", &exedir) >= 0);
+
+ /* Check if we're running from the builddir. If so, use the compiled in path. */
+ if (path_startswith(exedir, ABS_BUILD_DIR))
+ assert_se(snprintf(testdir, sizeof(testdir), "%s/test", ABS_SRC_DIR) > 0);
+ else
+ /* Try relative path, according to the install-test layout */
+ assert_se(snprintf(testdir, sizeof(testdir), "%s/testdata", dirname(exedir)) > 0);
+
+ /* test this without the suffix, as it may contain a glob */
+ if (access(testdir, F_OK) < 0) {
+ fputs("ERROR: Cannot find testdata directory, set $SYSTEMD_TEST_DATA\n", stderr);
+ exit(1);
+ }
+ }
+
+ strncpy(testdir + strlen(testdir), suffix, sizeof(testdir) - strlen(testdir) - 1);
+ return testdir;
+}
diff --git a/src/shared/tests.h b/src/shared/tests.h
index 93f09013a1..7055124990 100644
--- a/src/shared/tests.h
+++ b/src/shared/tests.h
@@ -20,3 +20,4 @@
***/
char* setup_fake_runtime_dir(void);
+const char* get_testdata_dir(const char *suffix);
diff --git a/src/shared/volatile-util.c b/src/shared/volatile-util.c
new file mode 100644
index 0000000000..e7e9721411
--- /dev/null
+++ b/src/shared/volatile-util.c
@@ -0,0 +1,68 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2015 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "alloc-util.h"
+#include "macro.h"
+#include "parse-util.h"
+#include "proc-cmdline.h"
+#include "string-util.h"
+#include "volatile-util.h"
+
+VolatileMode volatile_mode_from_string(const char *s) {
+ int b;
+
+ if (isempty(s))
+ return _VOLATILE_MODE_INVALID;
+
+ b = parse_boolean(s);
+ if (b > 0)
+ return VOLATILE_YES;
+ if (b == 0)
+ return VOLATILE_NO;
+
+ if (streq(s, "state"))
+ return VOLATILE_STATE;
+
+ return _VOLATILE_MODE_INVALID;
+}
+
+int query_volatile_mode(VolatileMode *ret) {
+ _cleanup_free_ char *mode = NULL;
+ VolatileMode m = VOLATILE_NO;
+ int r;
+
+ r = proc_cmdline_get_key("systemd.volatile", PROC_CMDLINE_VALUE_OPTIONAL, &mode);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ goto finish;
+
+ if (mode) {
+ m = volatile_mode_from_string(mode);
+ if (m < 0)
+ return -EINVAL;
+ } else
+ m = VOLATILE_YES;
+
+ r = 1;
+
+finish:
+ *ret = m;
+ return r;
+}
diff --git a/src/shared/volatile-util.h b/src/shared/volatile-util.h
new file mode 100644
index 0000000000..17930ba6ae
--- /dev/null
+++ b/src/shared/volatile-util.h
@@ -0,0 +1,32 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef enum VolatileMode {
+ VOLATILE_NO,
+ VOLATILE_YES,
+ VOLATILE_STATE,
+ _VOLATILE_MODE_MAX,
+ _VOLATILE_MODE_INVALID = -1
+} VolatileMode;
+
+VolatileMode volatile_mode_from_string(const char *s);
+
+int query_volatile_mode(VolatileMode *ret);
diff --git a/src/sleep/sleep.c b/src/sleep/sleep.c
index c8f0742183..3bac78b3e4 100644
--- a/src/sleep/sleep.c
+++ b/src/sleep/sleep.c
@@ -25,6 +25,7 @@
#include "sd-messages.h"
#include "def.h"
+#include "exec-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "log.h"
@@ -106,10 +107,10 @@ static int execute(char **modes, char **states) {
if (r < 0)
return r;
- execute_directories(dirs, DEFAULT_TIMEOUT_USEC, arguments);
+ execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, arguments);
log_struct(LOG_INFO,
- LOG_MESSAGE_ID(SD_MESSAGE_SLEEP_START),
+ "MESSAGE_ID=" SD_MESSAGE_SLEEP_START_STR,
LOG_MESSAGE("Suspending system..."),
"SLEEP=%s", arg_verb,
NULL);
@@ -119,13 +120,13 @@ static int execute(char **modes, char **states) {
return r;
log_struct(LOG_INFO,
- LOG_MESSAGE_ID(SD_MESSAGE_SLEEP_STOP),
+ "MESSAGE_ID=" SD_MESSAGE_SLEEP_STOP_STR,
LOG_MESSAGE("System resumed."),
"SLEEP=%s", arg_verb,
NULL);
arguments[1] = (char*) "post";
- execute_directories(dirs, DEFAULT_TIMEOUT_USEC, arguments);
+ execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, arguments);
return r;
}
diff --git a/src/socket-proxy/socket-proxyd.c b/src/socket-proxy/socket-proxyd.c
index 52b4db8875..1b99b7bc82 100644
--- a/src/socket-proxy/socket-proxyd.c
+++ b/src/socket-proxy/socket-proxyd.c
@@ -39,10 +39,11 @@
#include "set.h"
#include "socket-util.h"
#include "string-util.h"
+#include "parse-util.h"
#include "util.h"
#define BUFFER_SIZE (256 * 1024)
-#define CONNECTIONS_MAX 256
+static unsigned arg_connections_max = 256;
static const char *arg_remote_host = NULL;
@@ -445,7 +446,7 @@ static int add_connection_socket(Context *context, int fd) {
assert(context);
assert(fd >= 0);
- if (set_size(context->connections) > CONNECTIONS_MAX) {
+ if (set_size(context->connections) > arg_connections_max) {
log_warning("Hit connection limit, refusing connection.");
safe_close(fd);
return 0;
@@ -563,6 +564,7 @@ static void help(void) {
printf("%1$s [HOST:PORT]\n"
"%1$s [SOCKET]\n\n"
"Bidirectionally proxy local sockets to another (possibly remote) socket.\n\n"
+ " -c --connections-max= Set the maximum number of connections to be accepted\n"
" -h --help Show this help\n"
" --version Show package version\n",
program_invocation_short_name);
@@ -576,17 +578,18 @@ static int parse_argv(int argc, char *argv[]) {
};
static const struct option options[] = {
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, ARG_VERSION },
+ { "connections-max", required_argument, NULL, 'c' },
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, ARG_VERSION },
{}
};
- int c;
+ int c, r;
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
+ while ((c = getopt_long(argc, argv, "c:h", options, NULL)) >= 0)
switch (c) {
@@ -594,6 +597,20 @@ static int parse_argv(int argc, char *argv[]) {
help();
return 0;
+ case 'c':
+ r = safe_atou(optarg, &arg_connections_max);
+ if (r < 0) {
+ log_error("Failed to parse --connections-max= argument: %s", optarg);
+ return r;
+ }
+
+ if (arg_connections_max < 1) {
+ log_error("Connection limit is too low.");
+ return -EINVAL;
+ }
+
+ break;
+
case ARG_VERSION:
return version();
diff --git a/src/stdio-bridge/stdio-bridge.c b/src/stdio-bridge/stdio-bridge.c
index ce8efce3d5..02ba5269dd 100644
--- a/src/stdio-bridge/stdio-bridge.c
+++ b/src/stdio-bridge/stdio-bridge.c
@@ -115,7 +115,7 @@ int main(int argc, char *argv[]) {
in_fd = SD_LISTEN_FDS_START;
out_fd = SD_LISTEN_FDS_START;
} else {
- log_error("Illegal number of file descriptors passed\n");
+ log_error("Illegal number of file descriptors passed.");
goto finish;
}
@@ -190,7 +190,7 @@ int main(int argc, char *argv[]) {
}
for (;;) {
- _cleanup_(sd_bus_message_unrefp)sd_bus_message *m = NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
int events_a, events_b, fd;
uint64_t timeout_a, timeout_b, t;
struct timespec _ts, *ts;
diff --git a/src/system-update-generator/system-update-generator.c b/src/system-update-generator/system-update-generator.c
index a3d677f068..f1514c9638 100644
--- a/src/system-update-generator/system-update-generator.c
+++ b/src/system-update-generator/system-update-generator.c
@@ -22,12 +22,13 @@
#include "fs-util.h"
#include "log.h"
+#include "proc-cmdline.h"
+#include "special.h"
#include "string-util.h"
#include "util.h"
/*
- * Implements the logic described in
- * http://freedesktop.org/wiki/Software/systemd/SystemUpdates
+ * Implements the logic described in systemd.offline-updates(7).
*/
static const char *arg_dest = "/tmp";
@@ -43,15 +44,31 @@ static int generate_symlink(void) {
return -EINVAL;
}
- p = strjoina(arg_dest, "/default.target");
+ p = strjoina(arg_dest, "/" SPECIAL_DEFAULT_TARGET);
if (symlink(SYSTEM_DATA_UNIT_PATH "/system-update.target", p) < 0)
return log_error_errno(errno, "Failed to create symlink %s: %m", p);
+ return 1;
+}
+
+static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
+ assert(key);
+
+ /* Check if a run level is specified on the kernel command line. The
+ * command line has higher priority than any on-disk configuration, so
+ * it'll make any symlink we create moot.
+ */
+
+ if (streq(key, "systemd.unit") && !proc_cmdline_value_missing(key, value))
+ log_warning("Offline system update overriden by kernel command line systemd.unit= setting");
+ else if (!value && runlevel_to_target(key))
+ log_warning("Offline system update overriden by runlevel \"%s\" on the kernel command line", key);
+
return 0;
}
int main(int argc, char *argv[]) {
- int r;
+ int r, k;
if (argc > 1 && argc != 4) {
log_error("This program takes three or no arguments.");
@@ -69,5 +86,11 @@ int main(int argc, char *argv[]) {
r = generate_symlink();
+ if (r > 0) {
+ k = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
+ if (k < 0)
+ log_warning_errno(k, "Failed to parse kernel command line, ignoring: %m");
+ }
+
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index dd3b931cd6..1a47cb564e 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -50,7 +50,7 @@
#include "exit-status.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "fs-util.h"
#include "glob-util.h"
#include "hostname-util.h"
@@ -142,6 +142,7 @@ static const char *arg_kill_who = NULL;
static int arg_signal = SIGTERM;
static char *arg_root = NULL;
static usec_t arg_when = 0;
+static char *argv_cmdline = NULL;
static enum action {
_ACTION_INVALID,
ACTION_SYSTEMCTL,
@@ -173,6 +174,8 @@ static OutputMode arg_output = OUTPUT_SHORT;
static bool arg_plain = false;
static bool arg_firmware_setup = false;
static bool arg_now = false;
+static bool arg_jobs_before = false;
+static bool arg_jobs_after = false;
static int daemon_reload(int argc, char *argv[], void* userdata);
static int trivial_method(int argc, char *argv[], void *userdata);
@@ -204,6 +207,9 @@ static int acquire_bus(BusFocus focus, sd_bus **ret) {
if (arg_transport != BUS_TRANSPORT_LOCAL)
focus = BUS_FULL;
+ if (getenv_bool("SYSTEMCTL_FORCE_BUS") > 0)
+ focus = BUS_FULL;
+
if (!busses[focus]) {
bool user;
@@ -444,7 +450,7 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
unsigned basic_len;
id_len = MIN(max_id_len, 25u); /* as much as it needs, but at most 25 for now */
- basic_len = circle_len + 5 + id_len + 5 + active_len + sub_len;
+ basic_len = circle_len + 1 + id_len + 1 + load_len + 1 + active_len + 1 + sub_len + 1;
if (job_count)
basic_len += job_len + 1;
@@ -466,7 +472,8 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
id_len += incr;
desc_len += MIN(extra_len - incr, max_desc_len - desc_len);
}
- }
+ } else
+ desc_len = 0;
} else {
id_len = max_id_len;
desc_len = max_desc_len;
@@ -527,7 +534,7 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
}
if (u->machine) {
- j = strjoin(u->machine, ":", u->id, NULL);
+ j = strjoin(u->machine, ":", u->id);
if (!j)
return log_oom();
@@ -939,7 +946,7 @@ static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
char **a;
if (s->machine) {
- j = strjoin(s->machine, ":", s->path, NULL);
+ j = strjoin(s->machine, ":", s->path);
if (!j)
return log_oom();
path = j;
@@ -1223,7 +1230,7 @@ static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
format_timestamp_relative(trel2, sizeof(trel2), t->last_trigger);
if (t->machine) {
- j = strjoin(t->machine, ":", t->id, NULL);
+ j = strjoin(t->machine, ":", t->id);
if (!j)
return log_oom();
unit = j;
@@ -1728,7 +1735,7 @@ static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, cha
if (r < 0)
return bus_log_parse_error(r);
- *deps = ret;
+ *deps = strv_uniq(ret);
ret = NULL;
return 0;
@@ -1773,6 +1780,7 @@ static int list_dependencies_one(
STRV_FOREACH(c, deps) {
if (strv_contains(*units, *c)) {
if (!arg_plain) {
+ printf(" ");
r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
if (r < 0)
return r;
@@ -1915,7 +1923,7 @@ static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
bus = container;
}
- r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, mi);
+ r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, NULL, mi);
if (r < 0)
return r;
@@ -1950,7 +1958,7 @@ static int get_machine_list(
machine_infos[c].name = hn;
hn = NULL;
- get_machine_properties(bus, &machine_infos[c]);
+ (void) get_machine_properties(bus, &machine_infos[c]);
c++;
}
@@ -1980,7 +1988,7 @@ static int get_machine_list(
return log_oom();
}
- get_machine_properties(NULL, &machine_infos[c]);
+ (void) get_machine_properties(NULL, &machine_infos[c]);
c++;
}
@@ -2192,12 +2200,49 @@ finish:
return r;
}
+static int output_waiting_jobs(sd_bus *bus, uint32_t id, const char *method, const char *prefix) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ const char *name, *type, *state, *job_path, *unit_path;
+ uint32_t other_id;
+ int r;
+
+ assert(bus);
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ method,
+ &error,
+ &reply,
+ "u", id);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to get waiting jobs for job %" PRIu32, id);
+
+ r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ while ((r = sd_bus_message_read(reply, "(usssoo)", &other_id, &name, &type, &state, &job_path, &unit_path)) > 0)
+ printf("%s %u (%s/%s)\n", prefix, other_id, name, type);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ return 0;
+}
+
struct job_info {
uint32_t id;
const char *name, *type, *state;
};
-static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
+static void output_jobs_list(sd_bus *bus, const struct job_info* jobs, unsigned n, bool skipped) {
unsigned id_len, unit_len, type_len, state_len;
const struct job_info *j;
const char *on, *off;
@@ -2259,6 +2304,11 @@ static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipp
on, unit_len, e ? e : j->name, off,
type_len, j->type,
on, state_len, j->state, off);
+
+ if (arg_jobs_after)
+ output_waiting_jobs(bus, j->id, "GetJobAfter", "\twaiting for job");
+ if (arg_jobs_before)
+ output_waiting_jobs(bus, j->id, "GetJobBefore", "\tblocking job");
}
if (!arg_no_legend) {
@@ -2327,7 +2377,7 @@ static int list_jobs(int argc, char *argv[], void *userdata) {
pager_open(arg_no_pager, false);
- output_jobs_list(jobs, c, skipped);
+ output_jobs_list(bus, jobs, c, skipped);
return 0;
}
@@ -2432,17 +2482,24 @@ static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **un
assert(unit_path);
STRV_FOREACH(p, lp->search_path) {
- _cleanup_free_ char *path;
+ _cleanup_free_ char *path = NULL, *lpath = NULL;
+ int r;
- path = path_join(arg_root, *p, unit_name);
+ path = path_join(NULL, *p, unit_name);
if (!path)
return log_oom();
- if (access(path, F_OK) == 0) {
- *unit_path = path;
- path = NULL;
- return 1;
- }
+ r = chase_symlinks(path, arg_root, 0, &lpath);
+ if (r == -ENOENT)
+ continue;
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r < 0)
+ return log_error_errno(r, "Failed to access path '%s': %m", path);
+
+ *unit_path = lpath;
+ lpath = NULL;
+ return 1;
}
return 0;
@@ -2504,22 +2561,17 @@ static int unit_find_paths(
}
} else {
_cleanup_set_free_ Set *names;
+ _cleanup_free_ char *template = NULL;
names = set_new(NULL);
if (!names)
return log_oom();
- r = set_put(names, unit_name);
- if (r < 0)
- return log_error_errno(r, "Failed to add unit name: %m");
-
r = unit_file_find_path(lp, unit_name, &path);
if (r < 0)
return r;
if (r == 0) {
- _cleanup_free_ char *template = NULL;
-
r = unit_name_template(unit_name, &template);
if (r < 0 && r != -EINVAL)
return log_error_errno(r, "Failed to determine template name: %m");
@@ -2530,8 +2582,28 @@ static int unit_find_paths(
}
}
+ if (path)
+ /* We found the unit file. If we followed symlinks, this name might be
+ * different then the unit_name with started with. Look for dropins matching
+ * that "final" name. */
+ r = set_put(names, basename(path));
+ else if (!template)
+ /* No unit file, let's look for dropins matching the original name.
+ * systemd has fairly complicated rules (based on unit type and provenience),
+ * which units are allowed not to have the main unit file. We err on the
+ * side of including too many files, and always try to load dropins. */
+ r = set_put(names, unit_name);
+ else
+ /* The cases where we allow a unit to exist without the main file are
+ * never valid for templates. Don't try to load dropins in this case. */
+ goto not_found;
+
+ if (r < 0)
+ return log_error_errno(r, "Failed to add unit name: %m");
+
if (dropin_paths) {
- r = unit_file_find_dropin_paths(lp->search_path, NULL, names, &dropins);
+ r = unit_file_find_dropin_conf_paths(arg_root, lp->search_path,
+ NULL, names, &dropins);
if (r < 0)
return r;
}
@@ -2550,7 +2622,7 @@ static int unit_find_paths(
dropins = NULL;
r = 1;
}
-
+ not_found:
if (r == 0 && !arg_force)
log_error("No files found for %s.", unit_name);
@@ -3411,6 +3483,8 @@ static int set_exit_code(uint8_t code) {
static int start_special(int argc, char *argv[], void *userdata) {
enum action a;
int r;
+ bool termination_action; /* an action that terminates the manager,
+ * can be performed also by signal. */
assert(argv);
@@ -3450,40 +3524,43 @@ static int start_special(int argc, char *argv[], void *userdata) {
return r;
}
- if (arg_force >= 2 &&
- IN_SET(a,
- ACTION_HALT,
- ACTION_POWEROFF,
- ACTION_REBOOT))
+ termination_action = IN_SET(a,
+ ACTION_HALT,
+ ACTION_POWEROFF,
+ ACTION_REBOOT);
+ if (termination_action && arg_force >= 2)
return halt_now(a);
if (arg_force >= 1 &&
- IN_SET(a,
- ACTION_HALT,
- ACTION_POWEROFF,
- ACTION_REBOOT,
- ACTION_KEXEC,
- ACTION_EXIT))
- return trivial_method(argc, argv, userdata);
+ (termination_action || IN_SET(a, ACTION_KEXEC, ACTION_EXIT)))
+ r = trivial_method(argc, argv, userdata);
+ else {
+ /* First try logind, to allow authentication with polkit */
+ if (IN_SET(a,
+ ACTION_POWEROFF,
+ ACTION_REBOOT,
+ ACTION_SUSPEND,
+ ACTION_HIBERNATE,
+ ACTION_HYBRID_SLEEP)) {
+
+ r = logind_reboot(a);
+ if (r >= 0)
+ return r;
+ if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS))
+ /* requested operation is not supported or already in progress */
+ return r;
- /* First try logind, to allow authentication with polkit */
- if (IN_SET(a,
- ACTION_POWEROFF,
- ACTION_REBOOT,
- ACTION_SUSPEND,
- ACTION_HIBERNATE,
- ACTION_HYBRID_SLEEP)) {
- r = logind_reboot(a);
- if (r >= 0)
- return r;
- if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS))
- /* requested operation is not supported or already in progress */
- return r;
+ /* On all other errors, try low-level operation */
+ }
- /* On all other errors, try low-level operation */
+ r = start_unit(argc, argv, userdata);
}
- return start_unit(argc, argv, userdata);
+ if (termination_action && arg_force < 2 &&
+ IN_SET(r, -ENOENT, -ETIMEDOUT))
+ log_notice("It is possible to perform action directly, see discussion of --force --force in man:systemctl(1).");
+
+ return r;
}
static int start_system_special(int argc, char *argv[], void *userdata) {
@@ -4882,7 +4959,7 @@ static int show_one(
return log_error_errno(r, "Failed to get properties: %s", bus_error_message(&error, r));
if (unit) {
- r = bus_message_map_all_properties(reply, property_map, &info);
+ r = bus_message_map_all_properties(reply, property_map, &error, &info);
if (r < 0)
return log_error_errno(r, "Failed to map properties: %s", bus_error_message(&error, r));
@@ -4959,13 +5036,10 @@ static int show_one(
r = 0;
if (show_properties) {
char **pp;
- int not_found_level = streq(verb, "show") ? LOG_DEBUG : LOG_WARNING;
STRV_FOREACH(pp, arg_properties)
- if (!set_contains(found_properties, *pp)) {
- log_full(not_found_level, "Property %s does not exist.", *pp);
- r = -ENXIO;
- }
+ if (!set_contains(found_properties, *pp))
+ log_debug("Property %s does not exist.", *pp);
} else if (streq(verb, "help"))
show_unit_help(&info);
@@ -5057,8 +5131,9 @@ static int show_all(
static int show_system_status(sd_bus *bus) {
char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
- _cleanup_free_ char *hn = NULL;
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(machine_info_clear) struct machine_info mi = {};
+ _cleanup_free_ char *hn = NULL;
const char *on, *off;
int r;
@@ -5066,9 +5141,9 @@ static int show_system_status(sd_bus *bus) {
if (!hn)
return log_oom();
- r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
+ r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &error, &mi);
if (r < 0)
- return log_error_errno(r, "Failed to read server status: %m");
+ return log_error_errno(r, "Failed to read server status: %s", bus_error_message(&error, r));
if (streq_ptr(mi.state, "degraded")) {
on = ansi_highlight_red();
@@ -5231,7 +5306,7 @@ static int cat_file(const char *filename, bool newline) {
ansi_normal());
fflush(stdout);
- return copy_bytes(fd, STDOUT_FILENO, (uint64_t) -1, false);
+ return copy_bytes(fd, STDOUT_FILENO, (uint64_t) -1, 0);
}
static int cat(int argc, char *argv[], void *userdata) {
@@ -5584,10 +5659,23 @@ static int switch_root(int argc, char *argv[], void *userdata) {
init = NULL;
}
+ /* Instruct PID1 to exclude us from its killing spree applied during
+ * the transition. Otherwise we would exit with a failure status even
+ * though the switch to the new root has succeed. */
+ argv_cmdline[0] = '@';
+
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ /* If we are slow to exit after the root switch, the new systemd instance
+ * will send us a signal to terminate. Just ignore it and exit normally.
+ * This way the unit does not end up as failed.
+ */
+ r = ignore_signals(SIGTERM, -1);
+ if (r < 0)
+ log_warning_errno(r, "Failed to change disposition of SIGTERM to ignore: %m");
+
log_debug("Switching root - root: %s; init: %s", root, strna(init));
r = sd_bus_call_method(
@@ -5599,8 +5687,11 @@ static int switch_root(int argc, char *argv[], void *userdata) {
&error,
NULL,
"ss", root, init);
- if (r < 0)
+ if (r < 0) {
+ (void) default_signals(SIGTERM, -1);
+
return log_error_errno(r, "Failed to switch root: %s", bus_error_message(&error, r));
+ }
return 0;
}
@@ -5874,6 +5965,7 @@ static int mangle_names(char **original_names, char ***mangled_names) {
} else {
r = unit_name_mangle(*name, UNIT_NAME_NOGLOB, i);
if (r < 0) {
+ *i = NULL;
strv_free(l);
return log_error_errno(r, "Failed to mangle unit name: %m");
}
@@ -5944,7 +6036,7 @@ static int unit_exists(const char *unit) {
if (r < 0)
return log_error_errno(r, "Failed to get properties: %s", bus_error_message(&error, r));
- r = bus_message_map_all_properties(reply, property_map, &info);
+ r = bus_message_map_all_properties(reply, property_map, &error, &info);
if (r < 0)
return log_error_errno(r, "Failed to map properties: %s", bus_error_message(&error, r));
@@ -6134,21 +6226,25 @@ static int enable_unit(int argc, char *argv[], void *userdata) {
"4) In case of template units, the unit is meant to be enabled with some\n"
" instance name specified.");
- if (arg_now && n_changes > 0 && STR_IN_SET(argv[0], "enable", "disable", "mask")) {
- char *new_args[n_changes + 2];
+ if (arg_now && STR_IN_SET(argv[0], "enable", "disable", "mask")) {
sd_bus *bus;
- unsigned i;
+ unsigned len, i;
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
goto finish;
- new_args[0] = (char*) (streq(argv[0], "enable") ? "start" : "stop");
- for (i = 0; i < n_changes; i++)
- new_args[i + 1] = basename(changes[i].path);
- new_args[i + 1] = NULL;
+ len = strv_length(names);
+ {
+ char *new_args[len + 2];
+
+ new_args[0] = (char*) (streq(argv[0], "enable") ? "start" : "stop");
+ for (i = 0; i < len; i++)
+ new_args[i + 1] = basename(names[i]);
+ new_args[i + 1] = NULL;
- r = start_unit(strv_length(new_args), new_args, userdata);
+ r = start_unit(len + 1, new_args, userdata);
+ }
}
finish:
@@ -6376,7 +6472,7 @@ static int unit_is_enabled(int argc, char *argv[], void *userdata) {
r = unit_file_get_state(arg_scope, arg_root, *name, &state);
if (r < 0)
- return log_error_errno(state, "Failed to get unit file state for %s: %m", *name);
+ return log_error_errno(r, "Failed to get unit file state for %s: %m", *name);
if (IN_SET(state,
UNIT_FILE_ENABLED,
@@ -6493,7 +6589,7 @@ static int create_edit_temp_file(const char *new_path, const char *original_path
if (r < 0)
return log_error_errno(r, "Failed to create directories for \"%s\": %m", new_path);
- r = copy_file(original_path, t, 0, 0644, 0);
+ r = copy_file(original_path, t, 0, 0644, 0, COPY_REFLINK);
if (r == -ENOENT) {
r = touch(t);
@@ -6519,12 +6615,12 @@ static int get_file_to_edit(
assert(name);
assert(ret_path);
- path = strjoin(paths->persistent_config, "/", name, NULL);
+ path = strjoin(paths->persistent_config, "/", name);
if (!path)
return log_oom();
if (arg_runtime) {
- run = strjoin(paths->runtime_config, "/", name, NULL);
+ run = strjoin(paths->runtime_config, "/", name);
if (!run)
return log_oom();
}
@@ -6717,29 +6813,54 @@ static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
return r;
STRV_FOREACH(name, names) {
- _cleanup_free_ char *path = NULL, *new_path = NULL, *tmp_path = NULL;
+ _cleanup_free_ char *path = NULL, *new_path = NULL, *tmp_path = NULL, *tmp_name = NULL;
+ const char *unit_name;
r = unit_find_paths(bus, *name, &lp, &path, NULL);
if (r < 0)
return r;
- else if (!arg_force) {
- if (r == 0) {
- log_error("Run 'systemctl edit --force %s' to create a new unit.", *name);
- return -ENOENT;
- } else if (!path) {
- // FIXME: support units with path==NULL (no FragmentPath)
- log_error("No fragment exists for %s.", *name);
+
+ if (r == 0) {
+ assert(!path);
+
+ if (!arg_force) {
+ log_error("Run 'systemctl edit%s --force %s' to create a new unit.",
+ arg_scope == UNIT_FILE_GLOBAL ? " --global" :
+ arg_scope == UNIT_FILE_USER ? " --user" : "",
+ *name);
return -ENOENT;
}
- }
- if (path) {
+ /* Create a new unit from scratch */
+ unit_name = *name;
+ r = unit_file_create_new(&lp, unit_name,
+ arg_full ? NULL : ".d/override.conf",
+ &new_path, &tmp_path);
+ } else {
+ assert(path);
+
+ unit_name = basename(path);
+ /* We follow unit aliases, but we need to propagate the instance */
+ if (unit_name_is_valid(*name, UNIT_NAME_INSTANCE) &&
+ unit_name_is_valid(unit_name, UNIT_NAME_TEMPLATE)) {
+ _cleanup_free_ char *instance = NULL;
+
+ r = unit_name_to_instance(*name, &instance);
+ if (r < 0)
+ return r;
+
+ r = unit_name_replace_instance(unit_name, instance, &tmp_name);
+ if (r < 0)
+ return r;
+
+ unit_name = tmp_name;
+ }
+
if (arg_full)
- r = unit_file_create_copy(&lp, *name, path, &new_path, &tmp_path);
+ r = unit_file_create_copy(&lp, unit_name, path, &new_path, &tmp_path);
else
- r = unit_file_create_new(&lp, *name, ".d/override.conf", &new_path, &tmp_path);
- } else
- r = unit_file_create_new(&lp, *name, NULL, &new_path, &tmp_path);
+ r = unit_file_create_new(&lp, unit_name, ".d/override.conf", &new_path, &tmp_path);
+ }
if (r < 0)
return r;
@@ -6851,6 +6972,7 @@ static void systemctl_help(void) {
" -a --all Show all properties/all units currently in memory,\n"
" including dead/empty ones. To list all units installed on\n"
" the system, use the 'list-unit-files' command instead.\n"
+ " --failed Same as --state=failed\n"
" -l --full Don't ellipsize unit names on output\n"
" -r --recursive Show unit list of host and local containers\n"
" --reverse Show reverse dependencies with 'list-dependencies'\n"
@@ -7210,18 +7332,16 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
case 't': {
if (isempty(optarg)) {
- log_error("--type requires arguments.");
+ log_error("--type= requires arguments.");
return -EINVAL;
}
- p = optarg;
- for (;;) {
+ for (p = optarg;;) {
_cleanup_free_ char *type = NULL;
r = extract_first_word(&p, &type, ",", 0);
if (r < 0)
return log_error_errno(r, "Failed to parse type: %s", optarg);
-
if (r == 0)
break;
@@ -7263,15 +7383,13 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
arg_properties = new0(char*, 1);
if (!arg_properties)
return log_oom();
- } else {
- p = optarg;
- for (;;) {
+ } else
+ for (p = optarg;;) {
_cleanup_free_ char *prop = NULL;
r = extract_first_word(&p, &prop, ",", 0);
if (r < 0)
return log_error_errno(r, "Failed to parse property: %s", optarg);
-
if (r == 0)
break;
@@ -7280,7 +7398,6 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
prop = NULL;
}
- }
/* If the user asked for a particular
* property, show it to him, even if it is
@@ -7300,10 +7417,12 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
case ARG_AFTER:
arg_dependency = DEPENDENCY_AFTER;
+ arg_jobs_after = true;
break;
case ARG_BEFORE:
arg_dependency = DEPENDENCY_BEFORE;
+ arg_jobs_before = true;
break;
case ARG_SHOW_TYPES:
@@ -7453,18 +7572,16 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
case ARG_STATE: {
if (isempty(optarg)) {
- log_error("--signal requires arguments.");
+ log_error("--state= requires arguments.");
return -EINVAL;
}
- p = optarg;
- for (;;) {
+ for (p = optarg;;) {
_cleanup_free_ char *s = NULL;
r = extract_first_word(&p, &s, ",", 0);
if (r < 0)
- return log_error_errno(r, "Failed to parse signal: %s", optarg);
-
+ return log_error_errno(r, "Failed to parse state: %s", optarg);
if (r == 0)
break;
@@ -8143,7 +8260,7 @@ static int halt_now(enum action a) {
_cleanup_free_ char *param = NULL;
r = read_one_line_file("/run/systemd/reboot-param", &param);
- if (r < 0)
+ if (r < 0 && r != -ENOENT)
log_warning_errno(r, "Failed to read reboot parameter file: %m");
if (!isempty(param)) {
@@ -8324,6 +8441,8 @@ static int logind_cancel_shutdown(void) {
int main(int argc, char*argv[]) {
int r;
+ argv_cmdline = argv[0];
+
setlocale(LC_ALL, "");
log_parse_environment();
log_open();
diff --git a/src/systemd/_sd-common.h b/src/systemd/_sd-common.h
index 3bb886be75..97c3943861 100644
--- a/src/systemd/_sd-common.h
+++ b/src/systemd/_sd-common.h
@@ -22,8 +22,8 @@
/* This is a private header; never even think of including this directly! */
-#if __INCLUDE_LEVEL__ <= 1
-#error "Do not include _sd-common.h directly; it is a private header."
+#if defined(__INCLUDE_LEVEL__) && __INCLUDE_LEVEL__ <= 1
+# error "Do not include _sd-common.h directly; it is a private header."
#endif
#ifndef _sd_printf_
diff --git a/src/systemd/sd-bus-vtable.h b/src/systemd/sd-bus-vtable.h
index e8f84eb545..1e82cae038 100644
--- a/src/systemd/sd-bus-vtable.h
+++ b/src/systemd/sd-bus-vtable.h
@@ -86,18 +86,26 @@ struct sd_bus_vtable {
{ \
.type = _SD_BUS_VTABLE_START, \
.flags = _flags, \
- .x.start.element_size = sizeof(sd_bus_vtable), \
+ .x = { \
+ .start = { \
+ .element_size = sizeof(sd_bus_vtable) \
+ }, \
+ }, \
}
#define SD_BUS_METHOD_WITH_OFFSET(_member, _signature, _result, _handler, _offset, _flags) \
{ \
.type = _SD_BUS_VTABLE_METHOD, \
.flags = _flags, \
- .x.method.member = _member, \
- .x.method.signature = _signature, \
- .x.method.result = _result, \
- .x.method.handler = _handler, \
- .x.method.offset = _offset, \
+ .x = { \
+ .method = { \
+ .member = _member, \
+ .signature = _signature, \
+ .result = _result, \
+ .handler = _handler, \
+ .offset = _offset, \
+ }, \
+ }, \
}
#define SD_BUS_METHOD(_member, _signature, _result, _handler, _flags) \
SD_BUS_METHOD_WITH_OFFSET(_member, _signature, _result, _handler, 0, _flags)
@@ -106,34 +114,50 @@ struct sd_bus_vtable {
{ \
.type = _SD_BUS_VTABLE_SIGNAL, \
.flags = _flags, \
- .x.signal.member = _member, \
- .x.signal.signature = _signature, \
+ .x = { \
+ .signal = { \
+ .member = _member, \
+ .signature = _signature, \
+ }, \
+ }, \
}
#define SD_BUS_PROPERTY(_member, _signature, _get, _offset, _flags) \
{ \
.type = _SD_BUS_VTABLE_PROPERTY, \
.flags = _flags, \
- .x.property.member = _member, \
- .x.property.signature = _signature, \
- .x.property.get = _get, \
- .x.property.offset = _offset, \
+ .x = { \
+ .property = { \
+ .member = _member, \
+ .signature = _signature, \
+ .get = _get, \
+ .set = NULL, \
+ .offset = _offset, \
+ }, \
+ }, \
}
#define SD_BUS_WRITABLE_PROPERTY(_member, _signature, _get, _set, _offset, _flags) \
{ \
.type = _SD_BUS_VTABLE_WRITABLE_PROPERTY, \
.flags = _flags, \
- .x.property.member = _member, \
- .x.property.signature = _signature, \
- .x.property.get = _get, \
- .x.property.set = _set, \
- .x.property.offset = _offset, \
+ .x = { \
+ .property = { \
+ .member = _member, \
+ .signature = _signature, \
+ .get = _get, \
+ .set = _set, \
+ .offset = _offset, \
+ }, \
+ }, \
}
#define SD_BUS_VTABLE_END \
{ \
.type = _SD_BUS_VTABLE_END, \
+ .flags = 0, \
+ .x = { \
+ }, \
}
_SD_END_DECLARATIONS;
diff --git a/src/systemd/sd-daemon.h b/src/systemd/sd-daemon.h
index 740b176903..8c096f610f 100644
--- a/src/systemd/sd-daemon.h
+++ b/src/systemd/sd-daemon.h
@@ -22,6 +22,7 @@
#include <inttypes.h>
#include <sys/types.h>
+#include <sys/socket.h>
#include "_sd-common.h"
@@ -131,6 +132,18 @@ int sd_is_socket(int fd, int family, int type, int listening);
int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port);
/*
+ Helper call for identifying a passed file descriptor. Returns 1 if the
+ file descriptor is an Internet socket of the specified type
+ (SOCK_DGRAM, SOCK_STREAM, ...), and if the address of the socket is
+ the same as the address specified by addr. The listening flag is used
+ the same way as in sd_is_socket(). Returns a negative errno style
+ error code on failure.
+
+ See sd_is_socket_sockaddr(3) for more information.
+*/
+int sd_is_socket_sockaddr(int fd, int type, const struct sockaddr* addr, unsigned addr_len, int listening);
+
+/*
Helper call for identifying a passed file descriptor. Returns 1 if
the file descriptor is an AF_UNIX socket of the specified type
(SOCK_DGRAM, SOCK_STREAM, ...) and path, 0 otherwise. If type is 0
diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h
index 9a90c2ed42..ffe7f836de 100644
--- a/src/systemd/sd-dhcp-client.h
+++ b/src/systemd/sd-dhcp-client.h
@@ -126,6 +126,9 @@ int sd_dhcp_client_get_client_id(
int sd_dhcp_client_set_mtu(
sd_dhcp_client *client,
uint32_t mtu);
+int sd_dhcp_client_set_client_port(
+ sd_dhcp_client *client,
+ uint16_t port);
int sd_dhcp_client_set_hostname(
sd_dhcp_client *client,
const char *hostname);
diff --git a/src/systemd/sd-id128.h b/src/systemd/sd-id128.h
index ee011b1861..9b38969b77 100644
--- a/src/systemd/sd-id128.h
+++ b/src/systemd/sd-id128.h
@@ -39,12 +39,12 @@ union sd_id128 {
#define SD_ID128_STRING_MAX 33
char *sd_id128_to_string(sd_id128_t id, char s[SD_ID128_STRING_MAX]);
-
int sd_id128_from_string(const char *s, sd_id128_t *ret);
int sd_id128_randomize(sd_id128_t *ret);
int sd_id128_get_machine(sd_id128_t *ret);
+int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *ret);
int sd_id128_get_boot(sd_id128_t *ret);
int sd_id128_get_invocation(sd_id128_t *ret);
@@ -100,6 +100,9 @@ int sd_id128_get_invocation(sd_id128_t *ret);
((x).bytes[15] & 15) >= 10 ? 'a' + ((x).bytes[15] & 15) - 10 : '0' + ((x).bytes[15] & 15), \
0 })
+#define SD_ID128_MAKE_STR(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) \
+ #a #b #c #d #e #f #g #h #i #j #k #l #m #n #o #p
+
_sd_pure_ static __inline__ int sd_id128_equal(sd_id128_t a, sd_id128_t b) {
return memcmp(&a, &b, 16) == 0;
}
diff --git a/src/systemd/sd-messages.h b/src/systemd/sd-messages.h
index 79246ae060..f466d9b062 100644
--- a/src/systemd/sd-messages.h
+++ b/src/systemd/sd-messages.h
@@ -33,59 +33,109 @@ _SD_BEGIN_DECLARATIONS;
* with journalctl --new-id128. Do not use any other IDs, and do not
* count them up manually. */
-#define SD_MESSAGE_JOURNAL_START SD_ID128_MAKE(f7,73,79,a8,49,0b,40,8b,be,5f,69,40,50,5a,77,7b)
-#define SD_MESSAGE_JOURNAL_STOP SD_ID128_MAKE(d9,3f,b3,c9,c2,4d,45,1a,97,ce,a6,15,ce,59,c0,0b)
-#define SD_MESSAGE_JOURNAL_DROPPED SD_ID128_MAKE(a5,96,d6,fe,7b,fa,49,94,82,8e,72,30,9e,95,d6,1e)
-#define SD_MESSAGE_JOURNAL_MISSED SD_ID128_MAKE(e9,bf,28,e6,e8,34,48,1b,b6,f4,8f,54,8a,d1,36,06)
-#define SD_MESSAGE_JOURNAL_USAGE SD_ID128_MAKE(ec,38,7f,57,7b,84,4b,8f,a9,48,f3,3c,ad,9a,75,e6)
-
-#define SD_MESSAGE_COREDUMP SD_ID128_MAKE(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1)
-#define SD_MESSAGE_TRUNCATED_CORE SD_ID128_MAKE(5a,ad,d8,e9,54,dc,4b,1a,8c,95,4d,63,fd,9e,11,37)
-
-#define SD_MESSAGE_SESSION_START SD_ID128_MAKE(8d,45,62,0c,1a,43,48,db,b1,74,10,da,57,c6,0c,66)
-#define SD_MESSAGE_SESSION_STOP SD_ID128_MAKE(33,54,93,94,24,b4,45,6d,98,02,ca,83,33,ed,42,4a)
-#define SD_MESSAGE_SEAT_START SD_ID128_MAKE(fc,be,fc,5d,a2,3d,42,80,93,f9,7c,82,a9,29,0f,7b)
-#define SD_MESSAGE_SEAT_STOP SD_ID128_MAKE(e7,85,2b,fe,46,78,4e,d0,ac,cd,e0,4b,c8,64,c2,d5)
-#define SD_MESSAGE_MACHINE_START SD_ID128_MAKE(24,d8,d4,45,25,73,40,24,96,06,83,81,a6,31,2d,f2)
-#define SD_MESSAGE_MACHINE_STOP SD_ID128_MAKE(58,43,2b,d3,ba,ce,47,7c,b5,14,b5,63,81,b8,a7,58)
-
-#define SD_MESSAGE_TIME_CHANGE SD_ID128_MAKE(c7,a7,87,07,9b,35,4e,aa,a9,e7,7b,37,18,93,cd,27)
-#define SD_MESSAGE_TIMEZONE_CHANGE SD_ID128_MAKE(45,f8,2f,4a,ef,7a,4b,bf,94,2c,e8,61,d1,f2,09,90)
-
-#define SD_MESSAGE_STARTUP_FINISHED SD_ID128_MAKE(b0,7a,24,9c,d0,24,41,4a,82,dd,00,cd,18,13,78,ff)
-
-#define SD_MESSAGE_SLEEP_START SD_ID128_MAKE(6b,bd,95,ee,97,79,41,e4,97,c4,8b,e2,7c,25,41,28)
-#define SD_MESSAGE_SLEEP_STOP SD_ID128_MAKE(88,11,e6,df,2a,8e,40,f5,8a,94,ce,a2,6f,8e,bf,14)
-
-#define SD_MESSAGE_SHUTDOWN SD_ID128_MAKE(98,26,88,66,d1,d5,4a,49,9c,4e,98,92,1d,93,bc,40)
-
-#define SD_MESSAGE_UNIT_STARTING SD_ID128_MAKE(7d,49,58,e8,42,da,4a,75,8f,6c,1c,dc,7b,36,dc,c5)
-#define SD_MESSAGE_UNIT_STARTED SD_ID128_MAKE(39,f5,34,79,d3,a0,45,ac,8e,11,78,62,48,23,1f,bf)
-#define SD_MESSAGE_UNIT_STOPPING SD_ID128_MAKE(de,5b,42,6a,63,be,47,a7,b6,ac,3e,aa,c8,2e,2f,6f)
-#define SD_MESSAGE_UNIT_STOPPED SD_ID128_MAKE(9d,1a,aa,27,d6,01,40,bd,96,36,54,38,aa,d2,02,86)
-#define SD_MESSAGE_UNIT_FAILED SD_ID128_MAKE(be,02,cf,68,55,d2,42,8b,a4,0d,f7,e9,d0,22,f0,3d)
-#define SD_MESSAGE_UNIT_RELOADING SD_ID128_MAKE(d3,4d,03,7f,ff,18,47,e6,ae,66,9a,37,0e,69,47,25)
-#define SD_MESSAGE_UNIT_RELOADED SD_ID128_MAKE(7b,05,eb,c6,68,38,42,22,ba,a8,88,11,79,cf,da,54)
-
-#define SD_MESSAGE_SPAWN_FAILED SD_ID128_MAKE(64,12,57,65,1c,1b,4e,c9,a8,62,4d,7a,40,a9,e1,e7)
-
-#define SD_MESSAGE_FORWARD_SYSLOG_MISSED SD_ID128_MAKE(00,27,22,9c,a0,64,41,81,a7,6c,4e,92,45,8a,fa,2e)
-
-#define SD_MESSAGE_OVERMOUNTING SD_ID128_MAKE(1d,ee,03,69,c7,fc,47,36,b7,09,9b,38,ec,b4,6e,e7)
-
-#define SD_MESSAGE_LID_OPENED SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,6f)
-#define SD_MESSAGE_LID_CLOSED SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,70)
-#define SD_MESSAGE_SYSTEM_DOCKED SD_ID128_MAKE(f5,f4,16,b8,62,07,4b,28,92,7a,48,c3,ba,7d,51,ff)
-#define SD_MESSAGE_SYSTEM_UNDOCKED SD_ID128_MAKE(51,e1,71,bd,58,52,48,56,81,10,14,4c,51,7c,ca,53)
-#define SD_MESSAGE_POWER_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,71)
-#define SD_MESSAGE_SUSPEND_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,72)
-#define SD_MESSAGE_HIBERNATE_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,73)
-
-#define SD_MESSAGE_INVALID_CONFIGURATION SD_ID128_MAKE(c7,72,d2,4e,9a,88,4c,be,b9,ea,12,62,5c,30,6c,01)
-
-#define SD_MESSAGE_DNSSEC_FAILURE SD_ID128_MAKE(16,75,d7,f1,72,17,40,98,b1,10,8b,f8,c7,dc,8f,5d)
-#define SD_MESSAGE_DNSSEC_TRUST_ANCHOR_REVOKED SD_ID128_MAKE(4d,44,08,cf,d0,d1,44,85,91,84,d1,e6,5d,7c,8a,65)
-#define SD_MESSAGE_DNSSEC_DOWNGRADE SD_ID128_MAKE(36,db,2d,fa,5a,90,45,e1,bd,4a,f5,f9,3e,1c,f0,57)
+#define SD_MESSAGE_JOURNAL_START SD_ID128_MAKE(f7,73,79,a8,49,0b,40,8b,be,5f,69,40,50,5a,77,7b)
+#define SD_MESSAGE_JOURNAL_START_STR SD_ID128_MAKE_STR(f7,73,79,a8,49,0b,40,8b,be,5f,69,40,50,5a,77,7b)
+#define SD_MESSAGE_JOURNAL_STOP SD_ID128_MAKE(d9,3f,b3,c9,c2,4d,45,1a,97,ce,a6,15,ce,59,c0,0b)
+#define SD_MESSAGE_JOURNAL_STOP_STR SD_ID128_MAKE_STR(d9,3f,b3,c9,c2,4d,45,1a,97,ce,a6,15,ce,59,c0,0b)
+#define SD_MESSAGE_JOURNAL_DROPPED SD_ID128_MAKE(a5,96,d6,fe,7b,fa,49,94,82,8e,72,30,9e,95,d6,1e)
+#define SD_MESSAGE_JOURNAL_DROPPED_STR SD_ID128_MAKE_STR(a5,96,d6,fe,7b,fa,49,94,82,8e,72,30,9e,95,d6,1e)
+#define SD_MESSAGE_JOURNAL_MISSED SD_ID128_MAKE(e9,bf,28,e6,e8,34,48,1b,b6,f4,8f,54,8a,d1,36,06)
+#define SD_MESSAGE_JOURNAL_MISSED_STR SD_ID128_MAKE_STR(e9,bf,28,e6,e8,34,48,1b,b6,f4,8f,54,8a,d1,36,06)
+#define SD_MESSAGE_JOURNAL_USAGE SD_ID128_MAKE(ec,38,7f,57,7b,84,4b,8f,a9,48,f3,3c,ad,9a,75,e6)
+#define SD_MESSAGE_JOURNAL_USAGE_STR SD_ID128_MAKE_STR(ec,38,7f,57,7b,84,4b,8f,a9,48,f3,3c,ad,9a,75,e6)
+
+#define SD_MESSAGE_COREDUMP SD_ID128_MAKE(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1)
+#define SD_MESSAGE_COREDUMP_STR SD_ID128_MAKE_STR(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1)
+#define SD_MESSAGE_TRUNCATED_CORE SD_ID128_MAKE(5a,ad,d8,e9,54,dc,4b,1a,8c,95,4d,63,fd,9e,11,37)
+#define SD_MESSAGE_TRUNCATED_CORE_STR SD_ID128_MAKE_STR(5a,ad,d8,e9,54,dc,4b,1a,8c,95,4d,63,fd,9e,11,37)
+#define SD_MESSAGE_BACKTRACE SD_ID128_MAKE(1f,4e,0a,44,a8,86,49,93,9a,ae,a3,4f,c6,da,8c,95)
+#define SD_MESSAGE_BACKTRACE_STR SD_ID128_MAKE_STR(1f,4e,0a,44,a8,86,49,93,9a,ae,a3,4f,c6,da,8c,95)
+
+#define SD_MESSAGE_SESSION_START SD_ID128_MAKE(8d,45,62,0c,1a,43,48,db,b1,74,10,da,57,c6,0c,66)
+#define SD_MESSAGE_SESSION_START_STR SD_ID128_MAKE_STR(8d,45,62,0c,1a,43,48,db,b1,74,10,da,57,c6,0c,66)
+#define SD_MESSAGE_SESSION_STOP SD_ID128_MAKE(33,54,93,94,24,b4,45,6d,98,02,ca,83,33,ed,42,4a)
+#define SD_MESSAGE_SESSION_STOP_STR SD_ID128_MAKE_STR(33,54,93,94,24,b4,45,6d,98,02,ca,83,33,ed,42,4a)
+#define SD_MESSAGE_SEAT_START SD_ID128_MAKE(fc,be,fc,5d,a2,3d,42,80,93,f9,7c,82,a9,29,0f,7b)
+#define SD_MESSAGE_SEAT_START_STR SD_ID128_MAKE_STR(fc,be,fc,5d,a2,3d,42,80,93,f9,7c,82,a9,29,0f,7b)
+#define SD_MESSAGE_SEAT_STOP SD_ID128_MAKE(e7,85,2b,fe,46,78,4e,d0,ac,cd,e0,4b,c8,64,c2,d5)
+#define SD_MESSAGE_SEAT_STOP_STR SD_ID128_MAKE_STR(e7,85,2b,fe,46,78,4e,d0,ac,cd,e0,4b,c8,64,c2,d5)
+#define SD_MESSAGE_MACHINE_START SD_ID128_MAKE(24,d8,d4,45,25,73,40,24,96,06,83,81,a6,31,2d,f2)
+#define SD_MESSAGE_MACHINE_START_STR SD_ID128_MAKE_STR(24,d8,d4,45,25,73,40,24,96,06,83,81,a6,31,2d,f2)
+#define SD_MESSAGE_MACHINE_STOP SD_ID128_MAKE(58,43,2b,d3,ba,ce,47,7c,b5,14,b5,63,81,b8,a7,58)
+#define SD_MESSAGE_MACHINE_STOP_STR SD_ID128_MAKE_STR(58,43,2b,d3,ba,ce,47,7c,b5,14,b5,63,81,b8,a7,58)
+
+#define SD_MESSAGE_TIME_CHANGE SD_ID128_MAKE(c7,a7,87,07,9b,35,4e,aa,a9,e7,7b,37,18,93,cd,27)
+#define SD_MESSAGE_TIME_CHANGE_STR SD_ID128_MAKE_STR(c7,a7,87,07,9b,35,4e,aa,a9,e7,7b,37,18,93,cd,27)
+#define SD_MESSAGE_TIMEZONE_CHANGE SD_ID128_MAKE(45,f8,2f,4a,ef,7a,4b,bf,94,2c,e8,61,d1,f2,09,90)
+#define SD_MESSAGE_TIMEZONE_CHANGE_STR SD_ID128_MAKE_STR(45,f8,2f,4a,ef,7a,4b,bf,94,2c,e8,61,d1,f2,09,90)
+
+#define SD_MESSAGE_STARTUP_FINISHED SD_ID128_MAKE(b0,7a,24,9c,d0,24,41,4a,82,dd,00,cd,18,13,78,ff)
+#define SD_MESSAGE_STARTUP_FINISHED_STR SD_ID128_MAKE_STR(b0,7a,24,9c,d0,24,41,4a,82,dd,00,cd,18,13,78,ff)
+#define SD_MESSAGE_USER_STARTUP_FINISHED \
+ SD_ID128_MAKE(ee,d0,0a,68,ff,d8,4e,31,88,21,05,fd,97,3a,bd,d1)
+#define SD_MESSAGE_USER_STARTUP_FINISHED_STR \
+ SD_ID128_MAKE_STR(ee,d0,0a,68,ff,d8,4e,31,88,21,05,fd,97,3a,bd,d1)
+
+#define SD_MESSAGE_SLEEP_START SD_ID128_MAKE(6b,bd,95,ee,97,79,41,e4,97,c4,8b,e2,7c,25,41,28)
+#define SD_MESSAGE_SLEEP_START_STR SD_ID128_MAKE_STR(6b,bd,95,ee,97,79,41,e4,97,c4,8b,e2,7c,25,41,28)
+#define SD_MESSAGE_SLEEP_STOP SD_ID128_MAKE(88,11,e6,df,2a,8e,40,f5,8a,94,ce,a2,6f,8e,bf,14)
+#define SD_MESSAGE_SLEEP_STOP_STR SD_ID128_MAKE_STR(88,11,e6,df,2a,8e,40,f5,8a,94,ce,a2,6f,8e,bf,14)
+
+#define SD_MESSAGE_SHUTDOWN SD_ID128_MAKE(98,26,88,66,d1,d5,4a,49,9c,4e,98,92,1d,93,bc,40)
+#define SD_MESSAGE_SHUTDOWN_STR SD_ID128_MAKE_STR(98,26,88,66,d1,d5,4a,49,9c,4e,98,92,1d,93,bc,40)
+
+#define SD_MESSAGE_UNIT_STARTING SD_ID128_MAKE(7d,49,58,e8,42,da,4a,75,8f,6c,1c,dc,7b,36,dc,c5)
+#define SD_MESSAGE_UNIT_STARTING_STR SD_ID128_MAKE_STR(7d,49,58,e8,42,da,4a,75,8f,6c,1c,dc,7b,36,dc,c5)
+#define SD_MESSAGE_UNIT_STARTED SD_ID128_MAKE(39,f5,34,79,d3,a0,45,ac,8e,11,78,62,48,23,1f,bf)
+#define SD_MESSAGE_UNIT_STARTED_STR SD_ID128_MAKE_STR(39,f5,34,79,d3,a0,45,ac,8e,11,78,62,48,23,1f,bf)
+#define SD_MESSAGE_UNIT_STOPPING SD_ID128_MAKE(de,5b,42,6a,63,be,47,a7,b6,ac,3e,aa,c8,2e,2f,6f)
+#define SD_MESSAGE_UNIT_STOPPING_STR SD_ID128_MAKE_STR(de,5b,42,6a,63,be,47,a7,b6,ac,3e,aa,c8,2e,2f,6f)
+#define SD_MESSAGE_UNIT_STOPPED SD_ID128_MAKE(9d,1a,aa,27,d6,01,40,bd,96,36,54,38,aa,d2,02,86)
+#define SD_MESSAGE_UNIT_STOPPED_STR SD_ID128_MAKE_STR(9d,1a,aa,27,d6,01,40,bd,96,36,54,38,aa,d2,02,86)
+#define SD_MESSAGE_UNIT_FAILED SD_ID128_MAKE(be,02,cf,68,55,d2,42,8b,a4,0d,f7,e9,d0,22,f0,3d)
+#define SD_MESSAGE_UNIT_FAILED_STR SD_ID128_MAKE_STR(be,02,cf,68,55,d2,42,8b,a4,0d,f7,e9,d0,22,f0,3d)
+#define SD_MESSAGE_UNIT_RELOADING SD_ID128_MAKE(d3,4d,03,7f,ff,18,47,e6,ae,66,9a,37,0e,69,47,25)
+#define SD_MESSAGE_UNIT_RELOADING_STR SD_ID128_MAKE_STR(d3,4d,03,7f,ff,18,47,e6,ae,66,9a,37,0e,69,47,25)
+#define SD_MESSAGE_UNIT_RELOADED SD_ID128_MAKE(7b,05,eb,c6,68,38,42,22,ba,a8,88,11,79,cf,da,54)
+#define SD_MESSAGE_UNIT_RELOADED_STR SD_ID128_MAKE_STR(7b,05,eb,c6,68,38,42,22,ba,a8,88,11,79,cf,da,54)
+
+#define SD_MESSAGE_SPAWN_FAILED SD_ID128_MAKE(64,12,57,65,1c,1b,4e,c9,a8,62,4d,7a,40,a9,e1,e7)
+#define SD_MESSAGE_SPAWN_FAILED_STR SD_ID128_MAKE_STR(64,12,57,65,1c,1b,4e,c9,a8,62,4d,7a,40,a9,e1,e7)
+
+#define SD_MESSAGE_FORWARD_SYSLOG_MISSED SD_ID128_MAKE(00,27,22,9c,a0,64,41,81,a7,6c,4e,92,45,8a,fa,2e)
+#define SD_MESSAGE_FORWARD_SYSLOG_MISSED_STR \
+ SD_ID128_MAKE_STR(00,27,22,9c,a0,64,41,81,a7,6c,4e,92,45,8a,fa,2e)
+
+#define SD_MESSAGE_OVERMOUNTING SD_ID128_MAKE(1d,ee,03,69,c7,fc,47,36,b7,09,9b,38,ec,b4,6e,e7)
+#define SD_MESSAGE_OVERMOUNTING_STR SD_ID128_MAKE_STR(1d,ee,03,69,c7,fc,47,36,b7,09,9b,38,ec,b4,6e,e7)
+
+#define SD_MESSAGE_LID_OPENED SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,6f)
+#define SD_MESSAGE_LID_OPENED_STR SD_ID128_MAKE_STR(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,6f)
+#define SD_MESSAGE_LID_CLOSED SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,70)
+#define SD_MESSAGE_LID_CLOSED_STR SD_ID128_MAKE_STR(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,70)
+#define SD_MESSAGE_SYSTEM_DOCKED SD_ID128_MAKE(f5,f4,16,b8,62,07,4b,28,92,7a,48,c3,ba,7d,51,ff)
+#define SD_MESSAGE_SYSTEM_DOCKED_STR SD_ID128_MAKE_STR(f5,f4,16,b8,62,07,4b,28,92,7a,48,c3,ba,7d,51,ff)
+#define SD_MESSAGE_SYSTEM_UNDOCKED SD_ID128_MAKE(51,e1,71,bd,58,52,48,56,81,10,14,4c,51,7c,ca,53)
+#define SD_MESSAGE_SYSTEM_UNDOCKED_STR SD_ID128_MAKE_STR(51,e1,71,bd,58,52,48,56,81,10,14,4c,51,7c,ca,53)
+#define SD_MESSAGE_POWER_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,71)
+#define SD_MESSAGE_POWER_KEY_STR SD_ID128_MAKE_STR(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,71)
+#define SD_MESSAGE_SUSPEND_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,72)
+#define SD_MESSAGE_SUSPEND_KEY_STR SD_ID128_MAKE_STR(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,72)
+#define SD_MESSAGE_HIBERNATE_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,73)
+#define SD_MESSAGE_HIBERNATE_KEY_STR SD_ID128_MAKE_STR(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,73)
+
+#define SD_MESSAGE_INVALID_CONFIGURATION SD_ID128_MAKE(c7,72,d2,4e,9a,88,4c,be,b9,ea,12,62,5c,30,6c,01)
+#define SD_MESSAGE_INVALID_CONFIGURATION_STR \
+ SD_ID128_MAKE_STR(c7,72,d2,4e,9a,88,4c,be,b9,ea,12,62,5c,30,6c,01)
+
+#define SD_MESSAGE_DNSSEC_FAILURE SD_ID128_MAKE(16,75,d7,f1,72,17,40,98,b1,10,8b,f8,c7,dc,8f,5d)
+#define SD_MESSAGE_DNSSEC_FAILURE_STR SD_ID128_MAKE_STR(16,75,d7,f1,72,17,40,98,b1,10,8b,f8,c7,dc,8f,5d)
+#define SD_MESSAGE_DNSSEC_TRUST_ANCHOR_REVOKED \
+ SD_ID128_MAKE(4d,44,08,cf,d0,d1,44,85,91,84,d1,e6,5d,7c,8a,65)
+#define SD_MESSAGE_DNSSEC_TRUST_ANCHOR_REVOKED_STR \
+ SD_ID128_MAKE_STR(4d,44,08,cf,d0,d1,44,85,91,84,d1,e6,5d,7c,8a,65)
+#define SD_MESSAGE_DNSSEC_DOWNGRADE SD_ID128_MAKE(36,db,2d,fa,5a,90,45,e1,bd,4a,f5,f9,3e,1c,f0,57)
+#define SD_MESSAGE_DNSSEC_DOWNGRADE_STR SD_ID128_MAKE_STR(36,db,2d,fa,5a,90,45,e1,bd,4a,f5,f9,3e,1c,f0,57)
_SD_END_DECLARATIONS;
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index 0684f58fcd..4a0a49f2bb 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -30,7 +30,7 @@
#include "def.h"
#include "fd-util.h"
#include "fileio-label.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "hashmap.h"
#include "path-util.h"
#include "selinux-util.h"
@@ -211,7 +211,7 @@ static int make_backup(const char *target, const char *x) {
if (r < 0)
return r;
- r = copy_bytes(src, fileno(dst), (uint64_t) -1, true);
+ r = copy_bytes(src, fileno(dst), (uint64_t) -1, COPY_REFLINK);
if (r < 0)
goto fail;
diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c
index c2c80175a2..9fde9b1884 100644
--- a/src/sysv-generator/sysv-generator.c
+++ b/src/sysv-generator/sysv-generator.c
@@ -292,8 +292,10 @@ static int sysv_translate_facility(SysvStub *s, unsigned line, const char *name,
if (!streq(table[i], n))
continue;
- if (!table[i+1])
+ if (!table[i+1]) {
+ *ret = NULL;
return 0;
+ }
m = strdup(table[i+1]);
if (!m)
@@ -312,7 +314,7 @@ static int sysv_translate_facility(SysvStub *s, unsigned line, const char *name,
if (r < 0)
return log_error_errno(r, "[%s:%u] Could not build name for facility %s: %m", s->path, line, name);
- return r;
+ return 1;
}
/* Strip ".sh" suffix from file name for comparison */
@@ -324,8 +326,10 @@ static int sysv_translate_facility(SysvStub *s, unsigned line, const char *name,
}
/* Names equaling the file name of the services are redundant */
- if (streq_ptr(n, filename))
+ if (streq_ptr(n, filename)) {
+ *ret = NULL;
return 0;
+ }
/* Everything else we assume to be normal service names */
m = sysv_translate_name(n);
@@ -562,7 +566,7 @@ static int load_sysv(SysvStub *s) {
char *d = NULL;
if (chkconfig_description)
- d = strjoin(chkconfig_description, " ", j, NULL);
+ d = strjoin(chkconfig_description, " ", j);
else
d = strdup(j);
if (!d)
@@ -624,7 +628,7 @@ static int load_sysv(SysvStub *s) {
char *d = NULL;
if (long_description)
- d = strjoin(long_description, " ", t, NULL);
+ d = strjoin(long_description, " ", t);
else
d = strdup(j);
if (!d)
@@ -803,7 +807,7 @@ static int enumerate_sysv(const LookupPaths *lp, Hashmap *all_services) {
continue;
}
- fpath = strjoin(*path, "/", de->d_name, NULL);
+ fpath = strjoin(*path, "/", de->d_name);
if (!fpath)
return log_oom();
@@ -849,7 +853,7 @@ static int set_dependencies_from_rcnd(const LookupPaths *lp, Hashmap *all_servic
_cleanup_free_ char *path = NULL;
struct dirent *de;
- path = strjoin(*p, "/", rcnd_table[i].path, NULL);
+ path = strjoin(*p, "/", rcnd_table[i].path);
if (!path) {
r = log_oom();
goto finish;
@@ -879,7 +883,7 @@ static int set_dependencies_from_rcnd(const LookupPaths *lp, Hashmap *all_servic
if (a < 0 || b < 0)
continue;
- fpath = strjoin(*p, "/", de->d_name, NULL);
+ fpath = strjoin(*p, "/", de->d_name);
if (!fpath) {
r = log_oom();
goto finish;
diff --git a/src/test/test-af-list.c b/src/test/test-af-list.c
index e2479133de..e5ca54c8e7 100644
--- a/src/test/test-af-list.c
+++ b/src/test/test-af-list.c
@@ -24,6 +24,7 @@
#include "string-util.h"
#include "util.h"
+_unused_ \
static const struct af_name* lookup_af(register const char *str, register GPERF_LEN_TYPE len);
#include "af-from-name.h"
diff --git a/src/test/test-arphrd-list.c b/src/test/test-arphrd-list.c
index 8f4f342faa..bb51518c9c 100644
--- a/src/test/test-arphrd-list.c
+++ b/src/test/test-arphrd-list.c
@@ -24,6 +24,7 @@
#include "string-util.h"
#include "util.h"
+_unused_ \
static const struct arphrd_name* lookup_arphrd(register const char *str, register GPERF_LEN_TYPE len);
#include "arphrd-from-name.h"
diff --git a/src/test/test-calendarspec.c b/src/test/test-calendarspec.c
index 59217b131c..f90b73aeaf 100644
--- a/src/test/test-calendarspec.c
+++ b/src/test/test-calendarspec.c
@@ -143,6 +143,7 @@ int main(int argc, char* argv[]) {
test_one("Wed-Wed,Wed *-1", "Wed *-*-01 00:00:00");
test_one("Wed..Wed,Wed *-1", "Wed *-*-01 00:00:00");
test_one("Wed, 17:48", "Wed *-*-* 17:48:00");
+ test_one("Wednesday,", "Wed *-*-* 00:00:00");
test_one("Wed-Sat,Tue 12-10-15 1:2:3", "Tue..Sat 2012-10-15 01:02:03");
test_one("Wed..Sat,Tue 12-10-15 1:2:3", "Tue..Sat 2012-10-15 01:02:03");
test_one("*-*-7 0:0:0", "*-*-07 00:00:00");
@@ -171,11 +172,27 @@ int main(int argc, char* argv[]) {
test_one("2015-10-25 01:00:00 uTc", "2015-10-25 01:00:00 UTC");
test_one("2016-03-27 03:17:00.4200005", "2016-03-27 03:17:00.420001");
test_one("2016-03-27 03:17:00/0.42", "2016-03-27 03:17:00/0.420000");
- test_one("2016-03-27 03:17:00/0.42", "2016-03-27 03:17:00/0.420000");
- test_one("9..11,13:00,30", "*-*-* 09,10,11,13:00,30:00");
- test_one("1..3-1..3 1..3:1..3", "*-01,02,03-01,02,03 01,02,03:01,02,03:00");
- test_one("00:00:1.125..2.125", "*-*-* 00:00:01.125000,02.125000");
- test_one("00:00:1.0..3.8", "*-*-* 00:00:01,02,03");
+ test_one("9..11,13:00,30", "*-*-* 09..11,13:00,30:00");
+ test_one("1..3-1..3 1..3:1..3", "*-01..03-01..03 01..03:01..03:00");
+ test_one("00:00:1.125..2.125", "*-*-* 00:00:01.125000..02.125000");
+ test_one("00:00:1.0..3.8", "*-*-* 00:00:01..03");
+ test_one("00:00:01..03", "*-*-* 00:00:01..03");
+ test_one("00:00:01/2,02..03", "*-*-* 00:00:01/2,02..03");
+ test_one("*-*~1 Utc", "*-*~01 00:00:00 UTC");
+ test_one("*-*~05,3 ", "*-*~03,05 00:00:00");
+ test_one("*-*~* 00:00:00", "*-*-* 00:00:00");
+ test_one("Monday", "Mon *-*-* 00:00:00");
+ test_one("Monday *-*-*", "Mon *-*-* 00:00:00");
+ test_one("*-*-*", "*-*-* 00:00:00");
+ test_one("*:*:*", "*-*-* *:*:*");
+ test_one("*:*", "*-*-* *:*:00");
+ test_one("12:*", "*-*-* 12:*:00");
+ test_one("*:30", "*-*-* *:30:00");
+ test_one("93..00-*-*", "1993..2000-*-* 00:00:00");
+ test_one("00..07-*-*", "2000..2007-*-* 00:00:00");
+ test_one("*:20..39/5", "*-*-* *:20..35/5:00");
+ test_one("00:00:20..40/1", "*-*-* 00:00:20..40");
+ test_one("*~03/1,03..05", "*-*~03/1,03..05 00:00:00");
test_next("2016-03-27 03:17:00", "", 12345, 1459048620000000);
test_next("2016-03-27 03:17:00", "CET", 12345, 1459041420000000);
@@ -190,8 +207,17 @@ int main(int argc, char* argv[]) {
test_next("2015-11-13 09:11:23.42/1.77", "EET", 1447398683420000, 1447398685190000);
test_next("2015-11-13 09:11:23.42/1.77", "EET", 1447398683419999, 1447398683420000);
test_next("Sun 16:00:00", "CET", 1456041600123456, 1456066800000000);
+ test_next("*-04-31", "", 12345, -1);
+ test_next("2016-02~01 UTC", "", 12345, 1456704000000000);
+ test_next("Mon 2017-05~01..07 UTC", "", 12345, 1496016000000000);
+ test_next("Mon 2017-05~07/1 UTC", "", 12345, 1496016000000000);
+ test_next("2017-08-06 9,11,13,15,17:00 UTC", "", 1502029800000000, 1502031600000000);
+ test_next("2017-08-06 9..17/2:00 UTC", "", 1502029800000000, 1502031600000000);
+ test_next("2016-12-* 3..21/6:00 UTC", "", 1482613200000001, 1482634800000000);
assert_se(calendar_spec_from_string("test", &c) < 0);
+ assert_se(calendar_spec_from_string(" utc", &c) < 0);
+ assert_se(calendar_spec_from_string(" ", &c) < 0);
assert_se(calendar_spec_from_string("", &c) < 0);
assert_se(calendar_spec_from_string("7", &c) < 0);
assert_se(calendar_spec_from_string("121212:1:2", &c) < 0);
@@ -199,6 +225,22 @@ int main(int argc, char* argv[]) {
assert_se(calendar_spec_from_string("2000-03-05 00:00.1:00", &c) < 0);
assert_se(calendar_spec_from_string("00:00:00/0.00000001", &c) < 0);
assert_se(calendar_spec_from_string("00:00:00.0..00.9", &c) < 0);
+ assert_se(calendar_spec_from_string("2016~11-22", &c) < 0);
+ assert_se(calendar_spec_from_string("*-*~5/5", &c) < 0);
+ assert_se(calendar_spec_from_string("Monday.. 12:00", &c) < 0);
+ assert_se(calendar_spec_from_string("Monday..", &c) < 0);
+ assert_se(calendar_spec_from_string("-00:+00/-5", &c) < 0);
+ assert_se(calendar_spec_from_string("00:+00/-5", &c) < 0);
+ assert_se(calendar_spec_from_string("2016- 11- 24 12: 30: 00", &c) < 0);
+ assert_se(calendar_spec_from_string("*~29", &c) < 0);
+ assert_se(calendar_spec_from_string("*~16..31", &c) < 0);
+ assert_se(calendar_spec_from_string("12..1/2-*", &c) < 0);
+ assert_se(calendar_spec_from_string("*:05..05", &c) < 0);
+ assert_se(calendar_spec_from_string("*:05..10/6", &c) < 0);
+ assert_se(calendar_spec_from_string("20/4:00", &c) < 0);
+ assert_se(calendar_spec_from_string("00:00/60", &c) < 0);
+ assert_se(calendar_spec_from_string("00:00:2300", &c) < 0);
+ assert_se(calendar_spec_from_string("00:00:18446744073709551615", &c) < 0);
test_timestamp();
test_hourly_bug_4031();
diff --git a/src/test/test-cgroup-mask.c b/src/test/test-cgroup-mask.c
index a027eb0fd2..b42088c680 100644
--- a/src/test/test-cgroup-mask.c
+++ b/src/test/test-cgroup-mask.c
@@ -27,6 +27,7 @@
#include "unit.h"
static int test_cgroup_mask(void) {
+ _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
Manager *m = NULL;
Unit *son, *daughter, *parent, *root, *grandchild, *parent_deep;
FILE *serial = NULL;
@@ -34,7 +35,8 @@ static int test_cgroup_mask(void) {
int r;
/* Prepare the manager. */
- assert_se(set_unit_path(TEST_DIR) >= 0);
+ assert_se(set_unit_path(get_testdata_dir("")) >= 0);
+ assert_se(runtime_dir = setup_fake_runtime_dir());
r = manager_new(UNIT_FILE_USER, true, &m);
if (r == -EPERM || r == -EACCES) {
puts("manager_new: Permission denied. Skipping test.");
@@ -110,10 +112,8 @@ static int test_cgroup_mask(void) {
}
int main(int argc, char* argv[]) {
- _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
int rc = 0;
- assert_se(runtime_dir = setup_fake_runtime_dir());
TEST_REQ_RUNNING_SYSTEMD(rc = test_cgroup_mask());
return rc;
diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c
index c24c784e9b..30cd463722 100644
--- a/src/test/test-cgroup-util.c
+++ b/src/test/test-cgroup-util.c
@@ -18,11 +18,13 @@
***/
#include "alloc-util.h"
+#include "build.h"
#include "cgroup-util.h"
#include "dirent-util.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "parse-util.h"
+#include "proc-cmdline.h"
#include "process-util.h"
#include "stat-util.h"
#include "string-util.h"
@@ -332,7 +334,49 @@ static void test_fd_is_cgroup_fs(void) {
fd = safe_close(fd);
}
+static void test_is_wanted_print(bool header) {
+ _cleanup_free_ char *cmdline = NULL;
+
+ log_info("-- %s --", __func__);
+ assert_se(proc_cmdline(&cmdline) >= 0);
+ log_info("cmdline: %s", cmdline);
+ if (header) {
+
+ log_info(_CGROUP_HIEARCHY_);
+ (void) system("findmnt -n /sys/fs/cgroup");
+ }
+
+ log_info("is_unified_wanted() → %s", yes_no(cg_is_unified_wanted()));
+ log_info("is_hybrid_wanted() → %s", yes_no(cg_is_hybrid_wanted()));
+ log_info("is_legacy_wanted() → %s", yes_no(cg_is_legacy_wanted()));
+ log_info(" ");
+}
+
+static void test_is_wanted(void) {
+ assert_se(setenv("SYSTEMD_PROC_CMDLINE",
+ "systemd.unified_cgroup_hierarchy", 1) >= 0);
+ test_is_wanted_print(false);
+
+ assert_se(setenv("SYSTEMD_PROC_CMDLINE",
+ "systemd.unified_cgroup_hierarchy=0", 1) >= 0);
+ test_is_wanted_print(false);
+
+ assert_se(setenv("SYSTEMD_PROC_CMDLINE",
+ "systemd.unified_cgroup_hierarchy=0 "
+ "systemd.legacy_systemd_cgroup_controller", 1) >= 0);
+ test_is_wanted_print(false);
+
+ assert_se(setenv("SYSTEMD_PROC_CMDLINE",
+ "systemd.unified_cgroup_hierarchy=0 "
+ "systemd.legacy_systemd_cgroup_controller=0", 1) >= 0);
+ test_is_wanted_print(false);
+}
+
int main(void) {
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+ log_open();
+
test_path_decode_unit();
test_path_get_unit();
test_path_get_user_unit();
@@ -349,6 +393,9 @@ int main(void) {
TEST_REQ_RUNNING_SYSTEMD(test_mask_supported());
TEST_REQ_RUNNING_SYSTEMD(test_is_cgroup_fs());
TEST_REQ_RUNNING_SYSTEMD(test_fd_is_cgroup_fs());
+ test_is_wanted_print(true);
+ test_is_wanted_print(false); /* run twice to test caching */
+ test_is_wanted();
return 0;
}
diff --git a/src/test/test-conf-files.c b/src/test/test-conf-files.c
index 03b3a9fa5c..22b7c61204 100644
--- a/src/test/test-conf-files.c
+++ b/src/test/test-conf-files.c
@@ -47,13 +47,16 @@ static void setup_test_dir(char *tmp_dir, const char *files, ...) {
static void test_conf_files_list(bool use_root) {
char tmp_dir[] = "/tmp/test-conf-files-XXXXXX";
- _cleanup_strv_free_ char **found_files = NULL;
- const char *root_dir, *search_1, *search_2, *expect_a, *expect_b;
+ _cleanup_strv_free_ char **found_files = NULL, **found_files2 = NULL;
+ const char *root_dir, *search_1, *search_2, *expect_a, *expect_b, *expect_c;
+
+ log_debug("/* %s */", __func__);
setup_test_dir(tmp_dir,
"/dir1/a.conf",
"/dir2/a.conf",
"/dir2/b.conf",
+ "/dir2/c.foo",
NULL);
if (use_root) {
@@ -68,6 +71,9 @@ static void test_conf_files_list(bool use_root) {
expect_a = strjoina(tmp_dir, "/dir1/a.conf");
expect_b = strjoina(tmp_dir, "/dir2/b.conf");
+ expect_c = strjoina(tmp_dir, "/dir2/c.foo");
+
+ log_debug("/* Check when filtered by suffix */");
assert_se(conf_files_list(&found_files, ".conf", root_dir, search_1, search_2, NULL) == 0);
strv_print(found_files);
@@ -77,10 +83,24 @@ static void test_conf_files_list(bool use_root) {
assert_se(streq_ptr(found_files[1], expect_b));
assert_se(found_files[2] == NULL);
+ log_debug("/* Check when unfiltered */");
+ assert_se(conf_files_list(&found_files2, NULL, root_dir, search_1, search_2, NULL) == 0);
+ strv_print(found_files2);
+
+ assert_se(found_files2);
+ assert_se(streq_ptr(found_files2[0], expect_a));
+ assert_se(streq_ptr(found_files2[1], expect_b));
+ assert_se(streq_ptr(found_files2[2], expect_c));
+ assert_se(found_files2[3] == NULL);
+
assert_se(rm_rf(tmp_dir, REMOVE_ROOT|REMOVE_PHYSICAL) == 0);
}
int main(int argc, char **argv) {
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+ log_open();
+
test_conf_files_list(false);
test_conf_files_list(true);
return 0;
diff --git a/src/test/test-conf-parser.c b/src/test/test-conf-parser.c
index be5d2611f8..77fcbc0dd3 100644
--- a/src/test/test-conf-parser.c
+++ b/src/test/test-conf-parser.c
@@ -109,8 +109,10 @@ static void test_config_parse_path(void) {
test_config_parse_path_one("/path", "/path");
test_config_parse_path_one("/path//////////", "/path");
test_config_parse_path_one("///path/foo///bar////bar//", "/path/foo/bar/bar");
+ test_config_parse_path_one("/path/\xc3\x80", "/path/\xc3\x80");
test_config_parse_path_one("not_absolute/path", NULL);
+ test_config_parse_path_one("/path/\xc3\x7f", NULL);
}
static void test_config_parse_log_level(void) {
@@ -180,6 +182,8 @@ static void test_config_parse_strv(void) {
test_config_parse_strv_one("foo", STRV_MAKE("foo"));
test_config_parse_strv_one("foo bar foo", STRV_MAKE("foo", "bar", "foo"));
test_config_parse_strv_one("\"foo bar\" foo", STRV_MAKE("foo bar", "foo"));
+ test_config_parse_strv_one("\xc3\x80", STRV_MAKE("\xc3\x80"));
+ test_config_parse_strv_one("\xc3\x7f", STRV_MAKE_EMPTY);
}
static void test_config_parse_mode(void) {
diff --git a/src/test/test-copy.c b/src/test/test-copy.c
index ed1ea51dbd..ed6725611d 100644
--- a/src/test/test-copy.c
+++ b/src/test/test-copy.c
@@ -31,6 +31,7 @@
#include "rm-rf.h"
#include "string-util.h"
#include "strv.h"
+#include "user-util.h"
#include "util.h"
static void test_copy_file(void) {
@@ -52,7 +53,7 @@ static void test_copy_file(void) {
assert_se(write_string_file(fn, "foo bar bar bar foo", WRITE_STRING_FILE_CREATE) == 0);
- assert_se(copy_file(fn, fn_copy, 0, 0644, 0) == 0);
+ assert_se(copy_file(fn, fn_copy, 0, 0644, 0, COPY_REFLINK) == 0);
assert_se(read_full_file(fn_copy, &buf, &sz) == 0);
assert_se(streq(buf, "foo bar bar bar foo\n"));
@@ -77,8 +78,8 @@ static void test_copy_file_fd(void) {
assert_se(out_fd >= 0);
assert_se(write_string_file(in_fn, text, WRITE_STRING_FILE_CREATE) == 0);
- assert_se(copy_file_fd("/a/file/which/does/not/exist/i/guess", out_fd, true) < 0);
- assert_se(copy_file_fd(in_fn, out_fd, true) >= 0);
+ assert_se(copy_file_fd("/a/file/which/does/not/exist/i/guess", out_fd, COPY_REFLINK) < 0);
+ assert_se(copy_file_fd(in_fn, out_fd, COPY_REFLINK) >= 0);
assert_se(lseek(out_fd, SEEK_SET, 0) == 0);
assert_se(read(out_fd, buf, sizeof(buf)) == sizeof(text) - 1);
@@ -106,7 +107,7 @@ static void test_copy_tree(void) {
STRV_FOREACH(p, files) {
_cleanup_free_ char *f;
- assert_se(f = strappend(original_dir, *p));
+ assert_se((f = strappend(original_dir, *p)));
assert_se(mkdir_parents(f, 0755) >= 0);
assert_se(write_string_file(f, "file", WRITE_STRING_FILE_CREATE) == 0);
@@ -115,8 +116,8 @@ static void test_copy_tree(void) {
STRV_FOREACH_PAIR(link, p, links) {
_cleanup_free_ char *f, *l;
- assert_se(f = strappend(original_dir, *p));
- assert_se(l = strappend(original_dir, *link));
+ assert_se((f = strappend(original_dir, *p)));
+ assert_se((l = strappend(original_dir, *link)));
assert_se(mkdir_parents(l, 0755) >= 0);
assert_se(symlink(f, l) == 0);
@@ -125,13 +126,13 @@ static void test_copy_tree(void) {
unixsockp = strjoina(original_dir, "unixsock");
assert_se(mknod(unixsockp, S_IFSOCK|0644, 0) >= 0);
- assert_se(copy_tree(original_dir, copy_dir, true) == 0);
+ assert_se(copy_tree(original_dir, copy_dir, UID_INVALID, GID_INVALID, COPY_REFLINK|COPY_MERGE) == 0);
STRV_FOREACH(p, files) {
_cleanup_free_ char *buf = NULL, *f;
size_t sz = 0;
- assert_se(f = strappend(copy_dir, *p));
+ assert_se((f = strappend(copy_dir, *p)));
assert_se(access(f, F_OK) == 0);
assert_se(read_full_file(f, &buf, &sz) == 0);
@@ -141,10 +142,10 @@ static void test_copy_tree(void) {
STRV_FOREACH_PAIR(link, p, links) {
_cleanup_free_ char *target = NULL, *f, *l;
- assert_se(f = strjoin(original_dir, *p, NULL));
- assert_se(l = strjoin(copy_dir, *link, NULL));
+ assert_se((f = strjoin(original_dir, *p)));
+ assert_se((l = strjoin(copy_dir, *link)));
- assert_se(readlink_and_canonicalize(l, &target) == 0);
+ assert_se(readlink_and_canonicalize(l, NULL, &target) == 0);
assert_se(path_equal(f, target));
}
@@ -152,8 +153,8 @@ static void test_copy_tree(void) {
assert_se(stat(unixsockp, &st) >= 0);
assert_se(S_ISSOCK(st.st_mode));
- assert_se(copy_tree(original_dir, copy_dir, false) < 0);
- assert_se(copy_tree("/tmp/inexistent/foo/bar/fsdoi", copy_dir, false) < 0);
+ assert_se(copy_tree(original_dir, copy_dir, UID_INVALID, GID_INVALID, COPY_REFLINK) < 0);
+ assert_se(copy_tree("/tmp/inexistent/foo/bar/fsdoi", copy_dir, UID_INVALID, GID_INVALID, COPY_REFLINK) < 0);
(void) rm_rf(copy_dir, REMOVE_ROOT|REMOVE_PHYSICAL);
(void) rm_rf(original_dir, REMOVE_ROOT|REMOVE_PHYSICAL);
@@ -172,7 +173,7 @@ static void test_copy_bytes(void) {
assert_se(pipe2(pipefd, O_CLOEXEC) == 0);
- r = copy_bytes(infd, pipefd[1], (uint64_t) -1, false);
+ r = copy_bytes(infd, pipefd[1], (uint64_t) -1, 0);
assert_se(r == 0);
r = read(pipefd[0], buf, sizeof(buf));
@@ -185,13 +186,13 @@ static void test_copy_bytes(void) {
assert_se(strneq(buf, buf2, r));
/* test copy_bytes with invalid descriptors */
- r = copy_bytes(pipefd[0], pipefd[0], 1, false);
+ r = copy_bytes(pipefd[0], pipefd[0], 1, 0);
assert_se(r == -EBADF);
- r = copy_bytes(pipefd[1], pipefd[1], 1, false);
+ r = copy_bytes(pipefd[1], pipefd[1], 1, 0);
assert_se(r == -EBADF);
- r = copy_bytes(pipefd[1], infd, 1, false);
+ r = copy_bytes(pipefd[1], infd, 1, 0);
assert_se(r == -EBADF);
}
@@ -213,7 +214,7 @@ static void test_copy_bytes_regular_file(const char *src, bool try_reflink, uint
fd3 = mkostemp_safe(fn3);
assert_se(fd3 >= 0);
- r = copy_bytes(fd, fd2, max_bytes, try_reflink);
+ r = copy_bytes(fd, fd2, max_bytes, try_reflink ? COPY_REFLINK : 0);
if (max_bytes == (uint64_t) -1)
assert_se(r == 0);
else
@@ -221,7 +222,7 @@ static void test_copy_bytes_regular_file(const char *src, bool try_reflink, uint
assert_se(lseek(fd2, 0, SEEK_SET) == 0);
- r = copy_bytes(fd2, fd3, max_bytes, try_reflink);
+ r = copy_bytes(fd2, fd3, max_bytes, try_reflink ? COPY_REFLINK : 0);
if (max_bytes == (uint64_t) -1)
assert_se(r == 0);
else
diff --git a/src/test/test-date.c b/src/test/test-date.c
index 7f497bb7d5..b77598c81d 100644
--- a/src/test/test-date.c
+++ b/src/test/test-date.c
@@ -60,7 +60,7 @@ static void test_one(const char *p) {
_cleanup_free_ char *with_utc;
log_info("Test: %s", p);
- with_utc = strjoin(p, " UTC", NULL);
+ with_utc = strjoin(p, " UTC");
test_should_pass(p);
test_should_pass(with_utc);
}
@@ -69,7 +69,7 @@ static void test_one_noutc(const char *p) {
_cleanup_free_ char *with_utc;
log_info("Test: %s", p);
- with_utc = strjoin(p, " UTC", NULL);
+ with_utc = strjoin(p, " UTC");
test_should_pass(p);
test_should_fail(with_utc);
}
@@ -95,6 +95,16 @@ int main(int argc, char *argv[]) {
test_one_noutc("@1395716396");
test_should_parse("today UTC");
test_should_fail("today UTC UTC");
+ test_should_parse("1970-1-1 UTC");
+ test_should_fail("1969-1-1 UTC");
+#if SIZEOF_TIME_T == 8
+ test_should_parse("9999-12-30 23:59:59 UTC");
+ test_should_fail("9999-12-31 00:00:00 UTC");
+ test_should_fail("10000-01-01 00:00:00 UTC");
+#elif SIZEOF_TIME_T == 4
+ test_should_parse("2038-01-19 03:14:07 UTC");
+ test_should_fail( "2038-01-19 03:14:08 UTC");
+#endif
return 0;
}
diff --git a/src/test/test-dissect-image.c b/src/test/test-dissect-image.c
new file mode 100644
index 0000000000..2bb68be0db
--- /dev/null
+++ b/src/test/test-dissect-image.c
@@ -0,0 +1,66 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <fcntl.h>
+#include <stdio.h>
+
+#include "dissect-image.h"
+#include "log.h"
+#include "loop-util.h"
+#include "string-util.h"
+
+int main(int argc, char *argv[]) {
+ _cleanup_(loop_device_unrefp) LoopDevice *d = NULL;
+ _cleanup_(dissected_image_unrefp) DissectedImage *m = NULL;
+ int r, i;
+
+ log_set_max_level(LOG_DEBUG);
+
+ if (argc < 2) {
+ log_error("Requires one command line argument.");
+ return EXIT_FAILURE;
+ }
+
+ r = loop_device_make_by_path(argv[1], O_RDONLY, &d);
+ if (r < 0) {
+ log_error_errno(r, "Failed to set up loopback device: %m");
+ return EXIT_FAILURE;
+ }
+
+ r = dissect_image(d->fd, NULL, 0, DISSECT_IMAGE_REQUIRE_ROOT, &m);
+ if (r < 0) {
+ log_error_errno(r, "Failed to dissect image: %m");
+ return EXIT_FAILURE;
+ }
+
+ for (i = 0; i < _PARTITION_DESIGNATOR_MAX; i++) {
+
+ if (!m->partitions[i].found)
+ continue;
+
+ printf("Found %s partition, %s of type %s at #%i (%s)\n",
+ partition_designator_to_string(i),
+ m->partitions[i].rw ? "writable" : "read-only",
+ strna(m->partitions[i].fstype),
+ m->partitions[i].partno,
+ strna(m->partitions[i].node));
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/src/test/test-dns-domain.c b/src/test/test-dns-domain.c
index e2f097c95e..a7cd8e4b51 100644
--- a/src/test/test-dns-domain.c
+++ b/src/test/test-dns-domain.c
@@ -373,16 +373,16 @@ static void test_dns_name_is_valid(void) {
test_dns_name_is_valid_one("ä", 1);
test_dns_name_is_valid_one("\n", 0);
- /* 256 characters*/
+ /* 256 characters */
test_dns_name_is_valid_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345", 0);
- /* 255 characters*/
+ /* 255 characters */
test_dns_name_is_valid_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a1234", 0);
- /* 254 characters*/
+ /* 254 characters */
test_dns_name_is_valid_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a123", 0);
- /* 253 characters*/
+ /* 253 characters */
test_dns_name_is_valid_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12", 1);
/* label of 64 chars length */
@@ -627,6 +627,18 @@ static void test_dns_name_apply_idna(void) {
test_dns_name_apply_idna_one("föö.bär.", "xn--f-1gaa.xn--br-via");
}
+static void test_dns_name_is_valid_or_address(void) {
+ assert_se(dns_name_is_valid_or_address(NULL) == 0);
+ assert_se(dns_name_is_valid_or_address("") == 0);
+ assert_se(dns_name_is_valid_or_address("foobar") > 0);
+ assert_se(dns_name_is_valid_or_address("foobar.com") > 0);
+ assert_se(dns_name_is_valid_or_address("foobar..com") == 0);
+ assert_se(dns_name_is_valid_or_address("foobar.com.") > 0);
+ assert_se(dns_name_is_valid_or_address("127.0.0.1") > 0);
+ assert_se(dns_name_is_valid_or_address("::") > 0);
+ assert_se(dns_name_is_valid_or_address("::1") > 0);
+}
+
int main(int argc, char *argv[]) {
test_dns_label_unescape();
@@ -654,6 +666,7 @@ int main(int argc, char *argv[]) {
test_dns_name_compare_func();
test_dns_name_common_suffix();
test_dns_name_apply_idna();
+ test_dns_name_is_valid_or_address();
return 0;
}
diff --git a/src/test/test-engine.c b/src/test/test-engine.c
index a651f6b683..8133343fb3 100644
--- a/src/test/test-engine.c
+++ b/src/test/test-engine.c
@@ -37,10 +37,9 @@ int main(int argc, char *argv[]) {
Job *j;
int r;
- assert_se(runtime_dir = setup_fake_runtime_dir());
-
/* prepare the test */
- assert_se(set_unit_path(TEST_DIR) >= 0);
+ assert_se(set_unit_path(get_testdata_dir("")) >= 0);
+ assert_se(runtime_dir = setup_fake_runtime_dir());
r = manager_new(UNIT_FILE_USER, true, &m);
if (MANAGER_SKIP_TEST(r)) {
log_notice_errno(r, "Skipping test: manager_new: %m");
diff --git a/src/test/test-env-util.c b/src/test/test-env-util.c
index 35bb62906e..904c50f0ed 100644
--- a/src/test/test-env-util.c
+++ b/src/test/test-env-util.c
@@ -45,6 +45,16 @@ static void test_strv_env_delete(void) {
assert_se(strv_length(d) == 2);
}
+static void test_strv_env_get(void) {
+ char **l;
+
+ l = STRV_MAKE("ONE_OR_TWO=1", "THREE=3", "ONE_OR_TWO=2", "FOUR=4");
+
+ assert_se(streq(strv_env_get(l, "ONE_OR_TWO"), "2"));
+ assert_se(streq(strv_env_get(l, "THREE"), "3"));
+ assert_se(streq(strv_env_get(l, "FOUR"), "4"));
+}
+
static void test_strv_env_unset(void) {
_cleanup_strv_free_ char **l = NULL;
@@ -102,7 +112,90 @@ static void test_strv_env_merge(void) {
assert_se(strv_length(r) == 5);
}
-static void test_replace_env_arg(void) {
+static void test_env_strv_get_n(void) {
+ const char *_env[] = {
+ "FOO=NO NO NO",
+ "FOO=BAR BAR",
+ "BAR=waldo",
+ "PATH=unset",
+ NULL
+ };
+ char **env = (char**) _env;
+
+ assert_se(streq(strv_env_get_n(env, "FOO__", 3, 0), "BAR BAR"));
+ assert_se(streq(strv_env_get_n(env, "FOO__", 3, REPLACE_ENV_USE_ENVIRONMENT), "BAR BAR"));
+ assert_se(streq(strv_env_get_n(env, "FOO", 3, 0), "BAR BAR"));
+ assert_se(streq(strv_env_get_n(env, "FOO", 3, REPLACE_ENV_USE_ENVIRONMENT), "BAR BAR"));
+
+ assert_se(streq(strv_env_get_n(env, "PATH__", 4, 0), "unset"));
+ assert_se(streq(strv_env_get_n(env, "PATH", 4, 0), "unset"));
+ assert_se(streq(strv_env_get_n(env, "PATH__", 4, REPLACE_ENV_USE_ENVIRONMENT), "unset"));
+ assert_se(streq(strv_env_get_n(env, "PATH", 4, REPLACE_ENV_USE_ENVIRONMENT), "unset"));
+
+ env[3] = NULL; /* kill our $PATH */
+
+ assert_se(!strv_env_get_n(env, "PATH__", 4, 0));
+ assert_se(!strv_env_get_n(env, "PATH", 4, 0));
+ assert_se(streq(strv_env_get_n(env, "PATH__", 4, REPLACE_ENV_USE_ENVIRONMENT),
+ getenv("PATH")));
+ assert_se(streq(strv_env_get_n(env, "PATH", 4, REPLACE_ENV_USE_ENVIRONMENT),
+ getenv("PATH")));
+}
+
+static void test_replace_env(bool braceless) {
+ const char *env[] = {
+ "FOO=BAR BAR",
+ "BAR=waldo",
+ NULL
+ };
+ _cleanup_free_ char *t = NULL, *s = NULL, *q = NULL, *r = NULL, *p = NULL;
+ unsigned flags = REPLACE_ENV_ALLOW_BRACELESS*braceless;
+
+ t = replace_env("FOO=$FOO=${FOO}", (char**) env, flags);
+ assert_se(streq(t, braceless ? "FOO=BAR BAR=BAR BAR" : "FOO=$FOO=BAR BAR"));
+
+ s = replace_env("BAR=$BAR=${BAR}", (char**) env, flags);
+ assert_se(streq(s, braceless ? "BAR=waldo=waldo" : "BAR=$BAR=waldo"));
+
+ q = replace_env("BARBAR=$BARBAR=${BARBAR}", (char**) env, flags);
+ assert_se(streq(q, braceless ? "BARBAR==" : "BARBAR=$BARBAR="));
+
+ r = replace_env("BAR=$BAR$BAR${BAR}${BAR}", (char**) env, flags);
+ assert_se(streq(r, braceless ? "BAR=waldowaldowaldowaldo" : "BAR=$BAR$BARwaldowaldo"));
+
+ p = replace_env("${BAR}$BAR$BAR", (char**) env, flags);
+ assert_se(streq(p, braceless ? "waldowaldowaldo" : "waldo$BAR$BAR"));
+}
+
+static void test_replace_env2(bool extended) {
+ const char *env[] = {
+ "FOO=foo",
+ "BAR=bar",
+ NULL
+ };
+ _cleanup_free_ char *t = NULL, *s = NULL, *q = NULL, *r = NULL, *p = NULL, *x = NULL;
+ unsigned flags = REPLACE_ENV_ALLOW_EXTENDED*extended;
+
+ t = replace_env("FOO=${FOO:-${BAR}}", (char**) env, flags);
+ assert_se(streq(t, extended ? "FOO=foo" : "FOO=${FOO:-bar}"));
+
+ s = replace_env("BAR=${XXX:-${BAR}}", (char**) env, flags);
+ assert_se(streq(s, extended ? "BAR=bar" : "BAR=${XXX:-bar}"));
+
+ q = replace_env("XXX=${XXX:+${BAR}}", (char**) env, flags);
+ assert_se(streq(q, extended ? "XXX=" : "XXX=${XXX:+bar}"));
+
+ r = replace_env("FOO=${FOO:+${BAR}}", (char**) env, flags);
+ assert_se(streq(r, extended ? "FOO=bar" : "FOO=${FOO:+bar}"));
+
+ p = replace_env("FOO=${FOO:-${BAR}post}", (char**) env, flags);
+ assert_se(streq(p, extended ? "FOO=foo" : "FOO=${FOO:-barpost}"));
+
+ x = replace_env("XXX=${XXX:+${BAR}post}", (char**) env, flags);
+ assert_se(streq(x, extended ? "XXX=" : "XXX=${XXX:+barpost}"));
+}
+
+static void test_replace_env_argv(void) {
const char *env[] = {
"FOO=BAR BAR",
"BAR=waldo",
@@ -120,6 +213,12 @@ static void test_replace_env_arg(void) {
"${FOO",
"FOO$$${FOO}",
"$$FOO${FOO}",
+ "${FOO:-${BAR}}",
+ "${QUUX:-${FOO}}",
+ "${FOO:+${BAR}}",
+ "${QUUX:+${BAR}}",
+ "${FOO:+|${BAR}|}}",
+ "${FOO:+|${BAR}{|}",
NULL
};
_cleanup_strv_free_ char **r = NULL;
@@ -137,7 +236,13 @@ static void test_replace_env_arg(void) {
assert_se(streq(r[8], "${FOO"));
assert_se(streq(r[9], "FOO$BAR BAR"));
assert_se(streq(r[10], "$FOOBAR BAR"));
- assert_se(strv_length(r) == 11);
+ assert_se(streq(r[11], "${FOO:-waldo}"));
+ assert_se(streq(r[12], "${QUUX:-BAR BAR}"));
+ assert_se(streq(r[13], "${FOO:+waldo}"));
+ assert_se(streq(r[14], "${QUUX:+waldo}"));
+ assert_se(streq(r[15], "${FOO:+|waldo|}}"));
+ assert_se(streq(r[16], "${FOO:+|waldo{|}"));
+ assert_se(strv_length(r) == 17);
}
static void test_env_clean(void) {
@@ -209,16 +314,32 @@ static void test_env_assignment_is_valid(void) {
assert_se(!env_assignment_is_valid("głąb=printf \"\x1b]0;<mock-chroot>\x07<mock-chroot>\""));
}
+static void test_deserialize_environment(void) {
+ _cleanup_strv_free_ char **env = strv_new("A=1", NULL);
+
+ assert_se(deserialize_environment(&env, "env=test") < 0);
+ assert_se(deserialize_environment(&env, "env=B=2") >= 0);
+
+ assert_se(strv_equal(env, STRV_MAKE("A=1", "B=2")));
+}
+
int main(int argc, char *argv[]) {
test_strv_env_delete();
+ test_strv_env_get();
test_strv_env_unset();
test_strv_env_set();
test_strv_env_merge();
- test_replace_env_arg();
+ test_env_strv_get_n();
+ test_replace_env(false);
+ test_replace_env(true);
+ test_replace_env2(false);
+ test_replace_env2(true);
+ test_replace_env_argv();
test_env_clean();
test_env_name_is_valid();
test_env_value_is_valid();
test_env_assignment_is_valid();
+ test_deserialize_environment();
return 0;
}
diff --git a/src/test/test-exec-util.c b/src/test/test-exec-util.c
new file mode 100644
index 0000000000..482b0751b9
--- /dev/null
+++ b/src/test/test-exec-util.c
@@ -0,0 +1,348 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+ Copyright 2013 Thomas H.P. Andersen
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "alloc-util.h"
+#include "copy.h"
+#include "def.h"
+#include "env-util.h"
+#include "exec-util.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "fs-util.h"
+#include "log.h"
+#include "macro.h"
+#include "rm-rf.h"
+#include "string-util.h"
+#include "strv.h"
+
+static int here = 0, here2 = 0, here3 = 0;
+void *ignore_stdout_args[] = {&here, &here2, &here3};
+
+/* noop handlers, just check that arguments are passed correctly */
+static int ignore_stdout_func(int fd, void *arg) {
+ assert(fd >= 0);
+ assert(arg == &here);
+ safe_close(fd);
+
+ return 0;
+}
+static int ignore_stdout_func2(int fd, void *arg) {
+ assert(fd >= 0);
+ assert(arg == &here2);
+ safe_close(fd);
+
+ return 0;
+}
+static int ignore_stdout_func3(int fd, void *arg) {
+ assert(fd >= 0);
+ assert(arg == &here3);
+ safe_close(fd);
+
+ return 0;
+}
+
+static const gather_stdout_callback_t ignore_stdout[] = {
+ ignore_stdout_func,
+ ignore_stdout_func2,
+ ignore_stdout_func3,
+};
+
+static void test_execute_directory(bool gather_stdout) {
+ char template_lo[] = "/tmp/test-exec-util.XXXXXXX";
+ char template_hi[] = "/tmp/test-exec-util.XXXXXXX";
+ const char * dirs[] = {template_hi, template_lo, NULL};
+ const char *name, *name2, *name3, *overridden, *override, *masked, *mask;
+
+ log_info("/* %s (%s) */", __func__, gather_stdout ? "gathering stdout" : "asynchronous");
+
+ assert_se(mkdtemp(template_lo));
+ assert_se(mkdtemp(template_hi));
+
+ name = strjoina(template_lo, "/script");
+ name2 = strjoina(template_hi, "/script2");
+ name3 = strjoina(template_lo, "/useless");
+ overridden = strjoina(template_lo, "/overridden");
+ override = strjoina(template_hi, "/overridden");
+ masked = strjoina(template_lo, "/masked");
+ mask = strjoina(template_hi, "/masked");
+
+ assert_se(write_string_file(name,
+ "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works",
+ WRITE_STRING_FILE_CREATE) == 0);
+ assert_se(write_string_file(name2,
+ "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works2",
+ WRITE_STRING_FILE_CREATE) == 0);
+ assert_se(write_string_file(overridden,
+ "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed",
+ WRITE_STRING_FILE_CREATE) == 0);
+ assert_se(write_string_file(override,
+ "#!/bin/sh\necho 'Executing '$0",
+ WRITE_STRING_FILE_CREATE) == 0);
+ assert_se(write_string_file(masked,
+ "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed",
+ WRITE_STRING_FILE_CREATE) == 0);
+ assert_se(symlink("/dev/null", mask) == 0);
+ assert_se(touch(name3) >= 0);
+
+ assert_se(chmod(name, 0755) == 0);
+ assert_se(chmod(name2, 0755) == 0);
+ assert_se(chmod(overridden, 0755) == 0);
+ assert_se(chmod(override, 0755) == 0);
+ assert_se(chmod(masked, 0755) == 0);
+
+ if (gather_stdout)
+ execute_directories(dirs, DEFAULT_TIMEOUT_USEC, ignore_stdout, ignore_stdout_args, NULL);
+ else
+ execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, NULL);
+
+ assert_se(chdir(template_lo) == 0);
+ assert_se(access("it_works", F_OK) >= 0);
+ assert_se(access("failed", F_OK) < 0);
+
+ assert_se(chdir(template_hi) == 0);
+ assert_se(access("it_works2", F_OK) >= 0);
+ assert_se(access("failed", F_OK) < 0);
+
+ (void) rm_rf(template_lo, REMOVE_ROOT|REMOVE_PHYSICAL);
+ (void) rm_rf(template_hi, REMOVE_ROOT|REMOVE_PHYSICAL);
+}
+
+static void test_execution_order(void) {
+ char template_lo[] = "/tmp/test-exec-util-lo.XXXXXXX";
+ char template_hi[] = "/tmp/test-exec-util-hi.XXXXXXX";
+ const char *dirs[] = {template_hi, template_lo, NULL};
+ const char *name, *name2, *name3, *overridden, *override, *masked, *mask;
+ const char *output, *t;
+ _cleanup_free_ char *contents = NULL;
+
+ assert_se(mkdtemp(template_lo));
+ assert_se(mkdtemp(template_hi));
+
+ output = strjoina(template_hi, "/output");
+
+ log_info("/* %s >>%s */", __func__, output);
+
+ /* write files in "random" order */
+ name2 = strjoina(template_lo, "/90-bar");
+ name = strjoina(template_hi, "/80-foo");
+ name3 = strjoina(template_lo, "/last");
+ overridden = strjoina(template_lo, "/30-override");
+ override = strjoina(template_hi, "/30-override");
+ masked = strjoina(template_lo, "/10-masked");
+ mask = strjoina(template_hi, "/10-masked");
+
+ t = strjoina("#!/bin/sh\necho $(basename $0) >>", output);
+ assert_se(write_string_file(name, t, WRITE_STRING_FILE_CREATE) == 0);
+
+ t = strjoina("#!/bin/sh\necho $(basename $0) >>", output);
+ assert_se(write_string_file(name2, t, WRITE_STRING_FILE_CREATE) == 0);
+
+ t = strjoina("#!/bin/sh\necho $(basename $0) >>", output);
+ assert_se(write_string_file(name3, t, WRITE_STRING_FILE_CREATE) == 0);
+
+ t = strjoina("#!/bin/sh\necho OVERRIDDEN >>", output);
+ assert_se(write_string_file(overridden, t, WRITE_STRING_FILE_CREATE) == 0);
+
+ t = strjoina("#!/bin/sh\necho $(basename $0) >>", output);
+ assert_se(write_string_file(override, t, WRITE_STRING_FILE_CREATE) == 0);
+
+ t = strjoina("#!/bin/sh\necho MASKED >>", output);
+ assert_se(write_string_file(masked, t, WRITE_STRING_FILE_CREATE) == 0);
+
+ assert_se(symlink("/dev/null", mask) == 0);
+
+ assert_se(chmod(name, 0755) == 0);
+ assert_se(chmod(name2, 0755) == 0);
+ assert_se(chmod(name3, 0755) == 0);
+ assert_se(chmod(overridden, 0755) == 0);
+ assert_se(chmod(override, 0755) == 0);
+ assert_se(chmod(masked, 0755) == 0);
+
+ execute_directories(dirs, DEFAULT_TIMEOUT_USEC, ignore_stdout, ignore_stdout_args, NULL);
+
+ assert_se(read_full_file(output, &contents, NULL) >= 0);
+ assert_se(streq(contents, "30-override\n80-foo\n90-bar\nlast\n"));
+
+ (void) rm_rf(template_lo, REMOVE_ROOT|REMOVE_PHYSICAL);
+ (void) rm_rf(template_hi, REMOVE_ROOT|REMOVE_PHYSICAL);
+}
+
+static int gather_stdout_one(int fd, void *arg) {
+ char ***s = arg, *t;
+ char buf[128] = {};
+
+ assert_se(s);
+ assert_se(read(fd, buf, sizeof buf) >= 0);
+ safe_close(fd);
+
+ assert_se(t = strndup(buf, sizeof buf));
+ assert_se(strv_push(s, t) >= 0);
+
+ return 0;
+}
+static int gather_stdout_two(int fd, void *arg) {
+ char ***s = arg, **t;
+
+ STRV_FOREACH(t, *s)
+ assert_se(write(fd, *t, strlen(*t)) == (ssize_t) strlen(*t));
+ safe_close(fd);
+
+ return 0;
+}
+static int gather_stdout_three(int fd, void *arg) {
+ char **s = arg;
+ char buf[128] = {};
+
+ assert_se(read(fd, buf, sizeof buf - 1) > 0);
+ safe_close(fd);
+ assert_se(*s = strndup(buf, sizeof buf));
+
+ return 0;
+}
+
+const gather_stdout_callback_t const gather_stdout[] = {
+ gather_stdout_one,
+ gather_stdout_two,
+ gather_stdout_three,
+};
+
+
+static void test_stdout_gathering(void) {
+ char template[] = "/tmp/test-exec-util.XXXXXXX";
+ const char *dirs[] = {template, NULL};
+ const char *name, *name2, *name3;
+ int r;
+
+ char **tmp = NULL; /* this is only used in the forked process, no cleanup here */
+ _cleanup_free_ char *output = NULL;
+
+ void* args[] = {&tmp, &tmp, &output};
+
+ assert_se(mkdtemp(template));
+
+ log_info("/* %s */", __func__);
+
+ /* write files */
+ name = strjoina(template, "/10-foo");
+ name2 = strjoina(template, "/20-bar");
+ name3 = strjoina(template, "/30-last");
+
+ assert_se(write_string_file(name,
+ "#!/bin/sh\necho a\necho b\necho c\n",
+ WRITE_STRING_FILE_CREATE) == 0);
+ assert_se(write_string_file(name2,
+ "#!/bin/sh\necho d\n",
+ WRITE_STRING_FILE_CREATE) == 0);
+ assert_se(write_string_file(name3,
+ "#!/bin/sh\nsleep 1",
+ WRITE_STRING_FILE_CREATE) == 0);
+
+ assert_se(chmod(name, 0755) == 0);
+ assert_se(chmod(name2, 0755) == 0);
+ assert_se(chmod(name3, 0755) == 0);
+
+ r = execute_directories(dirs, DEFAULT_TIMEOUT_USEC, gather_stdout, args, NULL);
+ assert_se(r >= 0);
+
+ log_info("got: %s", output);
+
+ assert_se(streq(output, "a\nb\nc\nd\n"));
+}
+
+static void test_environment_gathering(void) {
+ char template[] = "/tmp/test-exec-util.XXXXXXX", **p;
+ const char *dirs[] = {template, NULL};
+ const char *name, *name2, *name3;
+ int r;
+
+ char **tmp = NULL; /* this is only used in the forked process, no cleanup here */
+ _cleanup_strv_free_ char **env = NULL;
+
+ void* const args[] = { &tmp, &tmp, &env };
+
+ assert_se(mkdtemp(template));
+
+ log_info("/* %s */", __func__);
+
+ /* write files */
+ name = strjoina(template, "/10-foo");
+ name2 = strjoina(template, "/20-bar");
+ name3 = strjoina(template, "/30-last");
+
+ assert_se(write_string_file(name,
+ "#!/bin/sh\n"
+ "echo A=23\n",
+ WRITE_STRING_FILE_CREATE) == 0);
+ assert_se(write_string_file(name2,
+ "#!/bin/sh\n"
+ "echo A=22:$A\n\n\n", /* substitution from previous generator */
+ WRITE_STRING_FILE_CREATE) == 0);
+ assert_se(write_string_file(name3,
+ "#!/bin/sh\n"
+ "echo A=$A:24\n"
+ "echo B=12\n"
+ "echo C=000\n"
+ "echo C=001\n" /* variable overwriting */
+ /* various invalid entries */
+ "echo unset A\n"
+ "echo unset A=\n"
+ "echo unset A=B\n"
+ "echo unset \n"
+ "echo A B=C\n"
+ "echo A\n"
+ /* test variable assignment without newline */
+ "echo PATH=$PATH:/no/such/file", /* no newline */
+ WRITE_STRING_FILE_CREATE) == 0);
+
+ assert_se(chmod(name, 0755) == 0);
+ assert_se(chmod(name2, 0755) == 0);
+ assert_se(chmod(name3, 0755) == 0);
+
+ r = execute_directories(dirs, DEFAULT_TIMEOUT_USEC, gather_environment, args, NULL);
+ assert_se(r >= 0);
+
+ STRV_FOREACH(p, env)
+ log_info("got env: \"%s\"", *p);
+
+ assert_se(streq(strv_env_get(env, "A"), "22:23:24"));
+ assert_se(streq(strv_env_get(env, "B"), "12"));
+ assert_se(streq(strv_env_get(env, "C"), "001"));
+ assert_se(endswith(strv_env_get(env, "PATH"), ":/no/such/file"));
+}
+
+int main(int argc, char *argv[]) {
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+ log_open();
+
+ test_execute_directory(true);
+ test_execute_directory(false);
+ test_execution_order();
+ test_stdout_gathering();
+ test_environment_gathering();
+
+ return 0;
+}
diff --git a/src/test/test-execute.c b/src/test/test-execute.c
index 6029853e3e..90540b884b 100644
--- a/src/test/test-execute.c
+++ b/src/test/test-execute.c
@@ -33,7 +33,9 @@
#ifdef HAVE_SECCOMP
#include "seccomp-util.h"
#endif
+#include "stat-util.h"
#include "test-helper.h"
+#include "tests.h"
#include "unit.h"
#include "util.h"
#include "virt.h"
@@ -144,11 +146,11 @@ static void test_exec_privatetmp(Manager *m) {
static void test_exec_privatedevices(Manager *m) {
if (detect_container() > 0) {
- log_notice("testing in container, skipping private device tests");
+ log_notice("testing in container, skipping %s", __func__);
return;
}
if (!is_inaccessible_available()) {
- log_notice("testing without inaccessible, skipping private device tests");
+ log_notice("testing without inaccessible, skipping %s", __func__);
return;
}
@@ -157,12 +159,22 @@ static void test_exec_privatedevices(Manager *m) {
}
static void test_exec_privatedevices_capabilities(Manager *m) {
+ int r;
+
if (detect_container() > 0) {
- log_notice("testing in container, skipping private device tests");
+ log_notice("testing in container, skipping %s", __func__);
return;
}
if (!is_inaccessible_available()) {
- log_notice("testing without inaccessible, skipping private device tests");
+ log_notice("testing without inaccessible, skipping %s", __func__);
+ return;
+ }
+
+ /* We use capsh to test if the capabilities are
+ * properly set, so be sure that it exists */
+ r = find_binary("capsh", NULL);
+ if (r < 0) {
+ log_error_errno(r, "Skipping %s, could not find capsh binary: %m", __func__);
return;
}
@@ -173,30 +185,51 @@ static void test_exec_privatedevices_capabilities(Manager *m) {
}
static void test_exec_protectkernelmodules(Manager *m) {
+ int r;
+
if (detect_container() > 0) {
- log_notice("testing in container, skipping protectkernelmodules tests");
+ log_notice("testing in container, skipping %s", __func__);
return;
}
if (!is_inaccessible_available()) {
- log_notice("testing without inaccessible, skipping protectkernelmodules tests");
+ log_notice("testing without inaccessible, skipping %s", __func__);
return;
}
+ r = find_binary("capsh", NULL);
+ if (r < 0) {
+ log_error_errno(r, "Skipping %s, could not find capsh binary: %m", __func__);
+ return;
+ }
+
+
test(m, "exec-protectkernelmodules-no-capabilities.service", 0, CLD_EXITED);
test(m, "exec-protectkernelmodules-yes-capabilities.service", 0, CLD_EXITED);
test(m, "exec-protectkernelmodules-yes-mount-propagation.service", 0, CLD_EXITED);
}
static void test_exec_readonlypaths(Manager *m) {
+
+ if (path_is_read_only_fs("/var") > 0)
+ return;
+
test(m, "exec-readonlypaths.service", 0, CLD_EXITED);
test(m, "exec-readonlypaths-mount-propagation.service", 0, CLD_EXITED);
}
static void test_exec_readwritepaths(Manager *m) {
+
+ if (path_is_read_only_fs("/") > 0)
+ return;
+
test(m, "exec-readwritepaths-mount-propagation.service", 0, CLD_EXITED);
}
static void test_exec_inaccessiblepaths(Manager *m) {
+
+ if (path_is_read_only_fs("/") > 0)
+ return;
+
test(m, "exec-inaccessiblepaths-mount-propagation.service", 0, CLD_EXITED);
}
@@ -219,6 +252,18 @@ static void test_exec_systemcallerrornumber(Manager *m) {
#endif
}
+static void test_exec_restrict_namespaces(Manager *m) {
+#ifdef HAVE_SECCOMP
+ if (!is_seccomp_available())
+ return;
+
+ test(m, "exec-restrict-namespaces-no.service", 0, CLD_EXITED);
+ test(m, "exec-restrict-namespaces-yes.service", 1, CLD_EXITED);
+ test(m, "exec-restrict-namespaces-mnt.service", 0, CLD_EXITED);
+ test(m, "exec-restrict-namespaces-mnt-blacklist.service", 1, CLD_EXITED);
+#endif
+}
+
static void test_exec_systemcall_system_mode_with_user(Manager *m) {
#ifdef HAVE_SECCOMP
if (!is_seccomp_available())
@@ -228,7 +273,7 @@ static void test_exec_systemcall_system_mode_with_user(Manager *m) {
else if (getpwnam("nfsnobody"))
test(m, "exec-systemcallfilter-system-user-nfsnobody.service", 0, CLD_EXITED);
else
- log_error_errno(errno, "Skipping test_exec_systemcall_system_mode_with_user, could not find nobody/nfsnobody user: %m");
+ log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody user: %m", __func__);
#endif
}
@@ -238,7 +283,7 @@ static void test_exec_user(Manager *m) {
else if (getpwnam("nfsnobody"))
test(m, "exec-user-nfsnobody.service", 0, CLD_EXITED);
else
- log_error_errno(errno, "Skipping test_exec_user, could not find nobody/nfsnobody user: %m");
+ log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody user: %m", __func__);
}
static void test_exec_group(Manager *m) {
@@ -247,7 +292,7 @@ static void test_exec_group(Manager *m) {
else if (getgrnam("nfsnobody"))
test(m, "exec-group-nfsnobody.service", 0, CLD_EXITED);
else
- log_error_errno(errno, "Skipping test_exec_group, could not find nobody/nfsnobody group: %m");
+ log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody group: %m", __func__);
}
static void test_exec_supplementary_groups(Manager *m) {
@@ -328,17 +373,15 @@ static void test_exec_runtimedirectory(Manager *m) {
else if (getgrnam("nfsnobody"))
test(m, "exec-runtimedirectory-owner-nfsnobody.service", 0, CLD_EXITED);
else
- log_error_errno(errno, "Skipping test_exec_runtimedirectory-owner, could not find nobody/nfsnobody group: %m");
+ log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody group: %m", __func__);
}
static void test_exec_capabilityboundingset(Manager *m) {
int r;
- /* We use capsh to test if the capabilities are
- * properly set, so be sure that it exists */
r = find_binary("capsh", NULL);
if (r < 0) {
- log_error_errno(r, "Skipping test_exec_capabilityboundingset, could not find capsh binary: %m");
+ log_error_errno(r, "Skipping %s, could not find capsh binary: %m", __func__);
return;
}
@@ -364,9 +407,9 @@ static void test_exec_capabilityambientset(Manager *m) {
test(m, "exec-capabilityambientset-nfsnobody.service", 0, CLD_EXITED);
test(m, "exec-capabilityambientset-merge-nfsnobody.service", 0, CLD_EXITED);
} else
- log_error_errno(errno, "Skipping test_exec_capabilityambientset, could not find nobody/nfsnobody user: %m");
+ log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody user: %m", __func__);
} else
- log_error_errno(errno, "Skipping test_exec_capabilityambientset, the kernel does not support ambient capabilities: %m");
+ log_error_errno(errno, "Skipping %s, the kernel does not support ambient capabilities: %m", __func__);
}
static void test_exec_privatenetwork(Manager *m) {
@@ -374,7 +417,7 @@ static void test_exec_privatenetwork(Manager *m) {
r = find_binary("ip", NULL);
if (r < 0) {
- log_error_errno(r, "Skipping test_exec_privatenetwork, could not find ip binary: %m");
+ log_error_errno(r, "Skipping %s, could not find ip binary: %m", __func__);
return;
}
@@ -397,8 +440,12 @@ static void test_exec_spec_interpolation(Manager *m) {
test(m, "exec-spec-interpolation.service", 0, CLD_EXITED);
}
-static int run_tests(UnitFileScope scope, test_function_t *tests) {
- test_function_t *test = NULL;
+static void test_exec_read_only_path_suceed(Manager *m) {
+ test(m, "exec-read-only-path-succeed.service", 0, CLD_EXITED);
+}
+
+static int run_tests(UnitFileScope scope, const test_function_t *tests) {
+ const test_function_t *test = NULL;
Manager *m = NULL;
int r;
@@ -421,7 +468,7 @@ static int run_tests(UnitFileScope scope, test_function_t *tests) {
}
int main(int argc, char *argv[]) {
- test_function_t user_tests[] = {
+ static const test_function_t user_tests[] = {
test_exec_workingdirectory,
test_exec_personality,
test_exec_ignoresigpipe,
@@ -435,6 +482,7 @@ int main(int argc, char *argv[]) {
test_exec_privatenetwork,
test_exec_systemcallfilter,
test_exec_systemcallerrornumber,
+ test_exec_restrict_namespaces,
test_exec_user,
test_exec_group,
test_exec_supplementary_groups,
@@ -449,14 +497,16 @@ int main(int argc, char *argv[]) {
test_exec_oomscoreadjust,
test_exec_ioschedulingclass,
test_exec_spec_interpolation,
+ test_exec_read_only_path_suceed,
NULL,
};
- test_function_t system_tests[] = {
+ static const test_function_t system_tests[] = {
test_exec_systemcall_system_mode_with_user,
NULL,
};
int r;
+ log_set_max_level(LOG_DEBUG);
log_parse_environment();
log_open();
@@ -467,7 +517,7 @@ int main(int argc, char *argv[]) {
}
assert_se(setenv("XDG_RUNTIME_DIR", "/tmp/", 1) == 0);
- assert_se(set_unit_path(TEST_DIR "/test-execute/") >= 0);
+ assert_se(set_unit_path(get_testdata_dir("/test-execute")) >= 0);
/* Unset VAR1, VAR2 and VAR3 which are used in the PassEnvironment test
* cases, otherwise (and if they are present in the environment),
diff --git a/src/test/test-fd-util.c b/src/test/test-fd-util.c
index f555bb976c..4425b5fe5f 100644
--- a/src/test/test-fd-util.c
+++ b/src/test/test-fd-util.c
@@ -94,10 +94,20 @@ static void test_same_fd(void) {
assert_se(same_fd(b, a) == 0);
}
+static void test_open_serialization_fd(void) {
+ _cleanup_close_ int fd = -1;
+
+ fd = open_serialization_fd("test");
+ assert_se(fd >= 0);
+
+ write(fd, "test\n", 5);
+}
+
int main(int argc, char *argv[]) {
test_close_many();
test_close_nointr();
test_same_fd();
+ test_open_serialization_fd();
return 0;
}
diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c
index 92663ef66f..b1d688c89e 100644
--- a/src/test/test-fileio.c
+++ b/src/test/test-fileio.c
@@ -71,6 +71,8 @@ static void test_parse_env_file(void) {
"seven=\"sevenval\" #nocomment\n"
"eight=eightval #nocomment\n"
"export nine=nineval\n"
+ "ten=ignored\n"
+ "ten=ignored\n"
"ten=", f);
fflush(f);
@@ -204,6 +206,113 @@ static void test_parse_multiline_env_file(void) {
unlink(p);
}
+static void test_merge_env_file(void) {
+ char t[] = "/tmp/test-fileio-XXXXXX";
+ int fd, r;
+ FILE *f;
+ _cleanup_strv_free_ char **a = NULL;
+ char **i;
+
+ fd = mkostemp_safe(t);
+ assert_se(fd >= 0);
+
+ log_info("/* %s (%s) */", __func__, t);
+
+ f = fdopen(fd, "w");
+ assert_se(f);
+
+ r = write_string_stream(f,
+ "one=1 \n"
+ "twelve=${one}2\n"
+ "twentyone=2${one}\n"
+ "one=2\n"
+ "twentytwo=2${one}\n"
+ "xxx_minus_three=$xxx - 3\n"
+ "xxx=0x$one$one$one\n"
+ "yyy=${one:-fallback}\n"
+ "zzz=${one:+replacement}\n"
+ "zzzz=${foobar:-${nothing}}\n"
+ "zzzzz=${nothing:+${nothing}}\n"
+ , false);
+ assert(r >= 0);
+
+ r = merge_env_file(&a, NULL, t);
+ assert_se(r >= 0);
+ strv_sort(a);
+
+ STRV_FOREACH(i, a)
+ log_info("Got: <%s>", *i);
+
+ assert_se(streq(a[0], "one=2"));
+ assert_se(streq(a[1], "twelve=12"));
+ assert_se(streq(a[2], "twentyone=21"));
+ assert_se(streq(a[3], "twentytwo=22"));
+ assert_se(streq(a[4], "xxx=0x222"));
+ assert_se(streq(a[5], "xxx_minus_three= - 3"));
+ assert_se(streq(a[6], "yyy=2"));
+ assert_se(streq(a[7], "zzz=replacement"));
+ assert_se(streq(a[8], "zzzz="));
+ assert_se(streq(a[9], "zzzzz="));
+ assert_se(a[10] == NULL);
+
+ r = merge_env_file(&a, NULL, t);
+ assert_se(r >= 0);
+ strv_sort(a);
+
+ STRV_FOREACH(i, a)
+ log_info("Got2: <%s>", *i);
+
+ assert_se(streq(a[0], "one=2"));
+ assert_se(streq(a[1], "twelve=12"));
+ assert_se(streq(a[2], "twentyone=21"));
+ assert_se(streq(a[3], "twentytwo=22"));
+ assert_se(streq(a[4], "xxx=0x222"));
+ assert_se(streq(a[5], "xxx_minus_three=0x222 - 3"));
+ assert_se(streq(a[6], "yyy=2"));
+ assert_se(streq(a[7], "zzz=replacement"));
+ assert_se(streq(a[8], "zzzz="));
+ assert_se(streq(a[9], "zzzzz="));
+ assert_se(a[10] == NULL);
+}
+
+static void test_merge_env_file_invalid(void) {
+ char t[] = "/tmp/test-fileio-XXXXXX";
+ int fd, r;
+ FILE *f;
+ _cleanup_strv_free_ char **a = NULL;
+ char **i;
+
+ fd = mkostemp_safe(t);
+ assert_se(fd >= 0);
+
+ log_info("/* %s (%s) */", __func__, t);
+
+ f = fdopen(fd, "w");
+ assert_se(f);
+
+ r = write_string_stream(f,
+ "unset one \n"
+ "unset one= \n"
+ "unset one=1 \n"
+ "one \n"
+ "one = \n"
+ "one two =\n"
+ "\x20two=\n"
+ "#comment=comment\n"
+ ";comment2=comment2\n"
+ "#\n"
+ "\n\n" /* empty line */
+ , false);
+ assert(r >= 0);
+
+ r = merge_env_file(&a, NULL, t);
+ assert_se(r >= 0);
+
+ STRV_FOREACH(i, a)
+ log_info("Got: <%s>", *i);
+
+ assert_se(strv_isempty(a));
+}
static void test_executable_is_script(void) {
char t[] = "/tmp/test-executable-XXXXXX";
@@ -367,7 +476,7 @@ static void test_write_string_file_verify(void) {
int r;
assert_se(read_one_line_file("/proc/cmdline", &buf) >= 0);
- assert_se((buf2 = strjoin(buf, "\n", NULL)));
+ assert_se((buf2 = strjoin(buf, "\n")));
r = write_string_file("/proc/cmdline", buf, 0);
assert_se(r == -EACCES || r == -EIO);
@@ -555,11 +664,14 @@ static void test_tempfn(void) {
}
int main(int argc, char *argv[]) {
+ log_set_max_level(LOG_DEBUG);
log_parse_environment();
log_open();
test_parse_env_file();
test_parse_multiline_env_file();
+ test_merge_env_file();
+ test_merge_env_file_invalid();
test_executable_is_script();
test_status_field();
test_capeff();
diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c
index 53a3cdc663..e774f567e0 100644
--- a/src/test/test-fs-util.c
+++ b/src/test/test-fs-util.c
@@ -60,66 +60,139 @@ static void test_chase_symlinks(void) {
p = strjoina(temp, "/start");
assert_se(symlink("top/dot/dotdota", p) >= 0);
- r = chase_symlinks(p, NULL, &result);
- assert_se(r >= 0);
+ /* Paths that use symlinks underneath the "root" */
+
+ r = chase_symlinks(p, NULL, 0, &result);
+ assert_se(r > 0);
assert_se(path_equal(result, "/usr"));
result = mfree(result);
- r = chase_symlinks(p, temp, &result);
+ r = chase_symlinks(p, temp, 0, &result);
assert_se(r == -ENOENT);
q = strjoina(temp, "/usr");
+
+ r = chase_symlinks(p, temp, CHASE_NONEXISTENT, &result);
+ assert_se(r == 0);
+ assert_se(path_equal(result, q));
+
assert_se(mkdir(q, 0700) >= 0);
- r = chase_symlinks(p, temp, &result);
- assert_se(r >= 0);
+ result = mfree(result);
+ r = chase_symlinks(p, temp, 0, &result);
+ assert_se(r > 0);
assert_se(path_equal(result, q));
p = strjoina(temp, "/slash");
assert_se(symlink("/", p) >= 0);
result = mfree(result);
- r = chase_symlinks(p, NULL, &result);
- assert_se(r >= 0);
+ r = chase_symlinks(p, NULL, 0, &result);
+ assert_se(r > 0);
assert_se(path_equal(result, "/"));
result = mfree(result);
- r = chase_symlinks(p, temp, &result);
- assert_se(r >= 0);
+ r = chase_symlinks(p, temp, 0, &result);
+ assert_se(r > 0);
assert_se(path_equal(result, temp));
+ /* Paths that would "escape" outside of the "root" */
+
+ p = strjoina(temp, "/6dots");
+ assert_se(symlink("../../..", p) >= 0);
+
+ result = mfree(result);
+ r = chase_symlinks(p, temp, 0, &result);
+ assert_se(r > 0 && path_equal(result, temp));
+
+ p = strjoina(temp, "/6dotsusr");
+ assert_se(symlink("../../../usr", p) >= 0);
+
+ result = mfree(result);
+ r = chase_symlinks(p, temp, 0, &result);
+ assert_se(r > 0 && path_equal(result, q));
+
+ p = strjoina(temp, "/top/8dotsusr");
+ assert_se(symlink("../../../../usr", p) >= 0);
+
+ result = mfree(result);
+ r = chase_symlinks(p, temp, 0, &result);
+ assert_se(r > 0 && path_equal(result, q));
+
+ /* Paths that contain repeated slashes */
+
p = strjoina(temp, "/slashslash");
assert_se(symlink("///usr///", p) >= 0);
result = mfree(result);
- r = chase_symlinks(p, NULL, &result);
- assert_se(r >= 0);
+ r = chase_symlinks(p, NULL, 0, &result);
+ assert_se(r > 0);
assert_se(path_equal(result, "/usr"));
result = mfree(result);
- r = chase_symlinks(p, temp, &result);
- assert_se(r >= 0);
+ r = chase_symlinks(p, temp, 0, &result);
+ assert_se(r > 0);
assert_se(path_equal(result, q));
+ /* Paths using . */
+
result = mfree(result);
- r = chase_symlinks("/etc/./.././", NULL, &result);
- assert_se(r >= 0);
+ r = chase_symlinks("/etc/./.././", NULL, 0, &result);
+ assert_se(r > 0);
assert_se(path_equal(result, "/"));
result = mfree(result);
- r = chase_symlinks("/etc/./.././", "/etc", &result);
- assert_se(r == -EINVAL);
+ r = chase_symlinks("/etc/./.././", "/etc", 0, &result);
+ assert_se(r > 0 && path_equal(result, "/etc"));
result = mfree(result);
- r = chase_symlinks("/etc/machine-id/foo", NULL, &result);
+ r = chase_symlinks("/etc/machine-id/foo", NULL, 0, &result);
assert_se(r == -ENOTDIR);
+ /* Path that loops back to self */
+
result = mfree(result);
p = strjoina(temp, "/recursive-symlink");
assert_se(symlink("recursive-symlink", p) >= 0);
- r = chase_symlinks(p, NULL, &result);
+ r = chase_symlinks(p, NULL, 0, &result);
assert_se(r == -ELOOP);
+ /* Path which doesn't exist */
+
+ p = strjoina(temp, "/idontexist");
+ r = chase_symlinks(p, NULL, 0, &result);
+ assert_se(r == -ENOENT);
+
+ r = chase_symlinks(p, NULL, CHASE_NONEXISTENT, &result);
+ assert_se(r == 0);
+ assert_se(path_equal(result, p));
+ result = mfree(result);
+
+ p = strjoina(temp, "/idontexist/meneither");
+ r = chase_symlinks(p, NULL, 0, &result);
+ assert_se(r == -ENOENT);
+
+ r = chase_symlinks(p, NULL, CHASE_NONEXISTENT, &result);
+ assert_se(r == 0);
+ assert_se(path_equal(result, p));
+ result = mfree(result);
+
+ /* Path which doesn't exist, but contains weird stuff */
+
+ p = strjoina(temp, "/idontexist/..");
+ r = chase_symlinks(p, NULL, 0, &result);
+ assert_se(r == -ENOENT);
+
+ r = chase_symlinks(p, NULL, CHASE_NONEXISTENT, &result);
+ assert_se(r == -ENOENT);
+
+ p = strjoina(temp, "/target");
+ q = strjoina(temp, "/top");
+ assert_se(symlink(q, p) >= 0);
+ p = strjoina(temp, "/target/idontexist");
+ r = chase_symlinks(p, NULL, 0, &result);
+ assert_se(r == -ENOENT);
+
assert_se(rm_rf(temp, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
}
@@ -232,12 +305,23 @@ static void test_var_tmp(void) {
}
}
+static void test_dot_or_dot_dot(void) {
+ assert_se(!dot_or_dot_dot(NULL));
+ assert_se(!dot_or_dot_dot(""));
+ assert_se(!dot_or_dot_dot("xxx"));
+ assert_se(dot_or_dot_dot("."));
+ assert_se(dot_or_dot_dot(".."));
+ assert_se(!dot_or_dot_dot(".foo"));
+ assert_se(!dot_or_dot_dot("..foo"));
+}
+
int main(int argc, char *argv[]) {
test_unlink_noerrno();
test_readlink_and_make_absolute();
test_get_files_in_directory();
test_var_tmp();
test_chase_symlinks();
+ test_dot_or_dot_dot();
return 0;
}
diff --git a/src/test/test-hash.c b/src/test/test-hash.c
new file mode 100644
index 0000000000..1972b94cfe
--- /dev/null
+++ b/src/test/test-hash.c
@@ -0,0 +1,82 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "alloc-util.h"
+#include "log.h"
+#include "string-util.h"
+#include "khash.h"
+
+int main(int argc, char *argv[]) {
+ _cleanup_(khash_unrefp) khash *h = NULL, *copy = NULL;
+ _cleanup_free_ char *s = NULL;
+
+ log_set_max_level(LOG_DEBUG);
+
+ assert_se(khash_new(&h, NULL) == -EINVAL);
+ assert_se(khash_new(&h, "") == -EINVAL);
+ assert_se(khash_new(&h, "foobar") == -EOPNOTSUPP);
+
+ assert_se(khash_new(&h, "sha256") >= 0);
+ assert_se(khash_get_size(h) == 32);
+ assert_se(streq(khash_get_algorithm(h), "sha256"));
+
+ assert_se(khash_digest_string(h, &s) >= 0);
+ assert_se(streq(s, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"));
+ s = mfree(s);
+
+ assert_se(khash_put(h, "foobar", 6) >= 0);
+ assert_se(khash_digest_string(h, &s) >= 0);
+ assert_se(streq(s, "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2"));
+ s = mfree(s);
+
+ assert_se(khash_put(h, "piep", 4) >= 0);
+ assert_se(khash_digest_string(h, &s) >= 0);
+ assert_se(streq(s, "f114d872b5ea075d3be9040d0b7a429514b3f9324a8e8e3dc3fb24c34ee56bea"));
+ s = mfree(s);
+
+ assert_se(khash_put(h, "foo", 3) >= 0);
+ assert_se(khash_dup(h, &copy) >= 0);
+
+ assert_se(khash_put(h, "bar", 3) >= 0);
+ assert_se(khash_put(copy, "bar", 3) >= 0);
+
+ assert_se(khash_digest_string(h, &s) >= 0);
+ assert_se(streq(s, "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2"));
+ s = mfree(s);
+
+ assert_se(khash_digest_string(copy, &s) >= 0);
+ assert_se(streq(s, "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2"));
+ s = mfree(s);
+
+ h = khash_unref(h);
+
+ assert_se(khash_new_with_key(&h, "hmac(sha256)", "quux", 4) >= 0);
+ assert_se(khash_get_size(h) == 32);
+ assert_se(streq(khash_get_algorithm(h), "hmac(sha256)"));
+
+ assert_se(khash_digest_string(h, &s) >= 0);
+ assert_se(streq(s, "abed9f8218ab473f77218a6a7d39abf1d21fa46d0700c4898e330ba88309d5ae"));
+ s = mfree(s);
+
+ assert_se(khash_put(h, "foobar", 6) >= 0);
+ assert_se(khash_digest_string(h, &s) >= 0);
+ assert_se(streq(s, "33f6c70a60db66007d5325d5d1dea37c371354e5b83347a59ad339ce9f4ba3dc"));
+
+ return 0;
+}
diff --git a/src/test/test-hexdecoct.c b/src/test/test-hexdecoct.c
index 276f25d091..fcae427e74 100644
--- a/src/test/test-hexdecoct.c
+++ b/src/test/test-hexdecoct.c
@@ -87,27 +87,19 @@ static void test_undecchar(void) {
}
static void test_unhexmem(void) {
- const char *hex = "efa214921";
+ const char *hex = "efa2149213";
const char *hex_invalid = "efa214921o";
_cleanup_free_ char *hex2 = NULL;
_cleanup_free_ void *mem = NULL;
size_t len;
- assert_se(unhexmem(hex, strlen(hex), &mem, &len) == 0);
- assert_se(unhexmem(hex, strlen(hex) + 1, &mem, &len) == -EINVAL);
assert_se(unhexmem(hex_invalid, strlen(hex_invalid), &mem, &len) == -EINVAL);
+ assert_se(unhexmem(hex, strlen(hex) + 1, &mem, &len) == -EINVAL);
+ assert_se(unhexmem(hex, strlen(hex) - 1, &mem, &len) == -EINVAL);
+ assert_se(unhexmem(hex, strlen(hex), &mem, &len) == 0);
assert_se((hex2 = hexmem(mem, len)));
-
- free(mem);
-
- assert_se(memcmp(hex, hex2, strlen(hex)) == 0);
-
- free(hex2);
-
- assert_se(unhexmem(hex, strlen(hex) - 1, &mem, &len) == 0);
- assert_se((hex2 = hexmem(mem, len)));
- assert_se(memcmp(hex, hex2, strlen(hex) - 1) == 0);
+ assert_se(streq(hex, hex2));
}
/* https://tools.ietf.org/html/rfc4648#section-10 */
diff --git a/src/test/test-id128.c b/src/test/test-id128.c
index 1c8e5549da..ab5a111ba9 100644
--- a/src/test/test-id128.c
+++ b/src/test/test-id128.c
@@ -153,5 +153,11 @@ int main(int argc, char *argv[]) {
assert_se(id128_read_fd(fd, ID128_UUID, &id2) >= 0);
assert_se(sd_id128_equal(id, id2));
+ assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id) >= 0);
+ assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id2) >= 0);
+ assert_se(sd_id128_equal(id, id2));
+ assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(51,df,0b,4b,c3,b0,4c,97,80,e2,99,b9,8c,a3,73,b8), &id2) >= 0);
+ assert_se(!sd_id128_equal(id, id2));
+
return 0;
}
diff --git a/src/test/test-install-root.c b/src/test/test-install-root.c
index a98de76b43..575401cb91 100644
--- a/src/test/test-install-root.c
+++ b/src/test/test-install-root.c
@@ -22,6 +22,7 @@
#include "install.h"
#include "mkdir.h"
#include "rm-rf.h"
+#include "special.h"
#include "string-util.h"
static void test_basic_mask_and_enable(const char *root) {
@@ -338,7 +339,7 @@ static void test_default(const char *root) {
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/test-default-real.target"));
- p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/default.target");
+ p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH "/" SPECIAL_DEFAULT_TARGET);
assert_se(streq(changes[0].path, p));
unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0;
@@ -735,6 +736,28 @@ static void test_preset_order(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-2.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
}
+static void test_static_instance(const char *root) {
+ UnitFileState state;
+ const char *p;
+
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "static-instance@.service", &state) == -ENOENT);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "static-instance@foo.service", &state) == -ENOENT);
+
+ p = strjoina(root, "/usr/lib/systemd/system/static-instance@.service");
+ assert_se(write_string_file(p,
+ "[Install]\n"
+ "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "static-instance@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "static-instance@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
+
+ p = strjoina(root, "/usr/lib/systemd/system/static-instance@foo.service");
+ assert_se(symlink("static-instance@.service", p) >= 0);
+
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "static-instance@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "static-instance@foo.service", &state) >= 0 && state == UNIT_FILE_STATIC);
+}
+
int main(int argc, char *argv[]) {
char root[] = "/tmp/rootXXXXXX";
const char *p;
@@ -765,6 +788,7 @@ int main(int argc, char *argv[]) {
test_preset_and_list(root);
test_preset_order(root);
test_revert(root);
+ test_static_instance(root);
assert_se(rm_rf(root, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
diff --git a/src/test/test-ipcrm.c b/src/test/test-ipcrm.c
index 551eba7215..ce6c7aa18a 100644
--- a/src/test/test-ipcrm.c
+++ b/src/test/test-ipcrm.c
@@ -24,13 +24,15 @@
int main(int argc, char *argv[]) {
uid_t uid;
int r;
- const char* name = argv[1] ?: "nfsnobody";
+ const char* name = argv[1] ?: NOBODY_USER_NAME;
r = get_user_creds(&name, &uid, NULL, NULL, NULL);
if (r < 0) {
- log_error_errno(r, "Failed to resolve \"%s\": %m", name);
- return EXIT_FAILURE;
+ log_full_errno(r == -ESRCH ? LOG_NOTICE : LOG_ERR,
+ r, "Failed to resolve \"%s\": %m", name);
+ return r == -ESRCH ? EXIT_TEST_SKIP : EXIT_FAILURE;
}
- return clean_ipc_by_uid(uid) < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+ r = clean_ipc_by_uid(uid);
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/src/test/test-journal-importer.c b/src/test/test-journal-importer.c
new file mode 100644
index 0000000000..a61212ce7b
--- /dev/null
+++ b/src/test/test-journal-importer.c
@@ -0,0 +1,90 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Zbigniew Jędrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "log.h"
+#include "journal-importer.h"
+#include "string-util.h"
+#include "tests.h"
+
+static void assert_iovec_entry(const struct iovec *iovec, const char* content) {
+ assert_se(strlen(content) == iovec->iov_len);
+ assert_se(memcmp(content, iovec->iov_base, iovec->iov_len) == 0);
+}
+
+#define COREDUMP_PROC_GROUP \
+ "COREDUMP_PROC_CGROUP=1:name=systemd:/\n" \
+ "0::/user.slice/user-1002.slice/user@1002.service/gnome-terminal-server.service\n"
+
+static void test_basic_parsing(void) {
+ _cleanup_(journal_importer_cleanup) JournalImporter imp = {};
+ int r;
+
+ imp.fd = open(get_testdata_dir("/journal-data/journal-1.txt"), O_RDONLY|O_CLOEXEC);
+ assert_se(imp.fd >= 0);
+
+ do
+ r = journal_importer_process_data(&imp);
+ while (r == 0 && !journal_importer_eof(&imp));
+ assert_se(r == 1);
+
+ /* We read one entry, so we should get EOF on next read, but not yet */
+ assert_se(!journal_importer_eof(&imp));
+
+ assert_se(imp.iovw.count == 6);
+ assert_iovec_entry(&imp.iovw.iovec[0], "_BOOT_ID=1531fd22ec84429e85ae888b12fadb91");
+ assert_iovec_entry(&imp.iovw.iovec[1], "_TRANSPORT=journal");
+ assert_iovec_entry(&imp.iovw.iovec[2], COREDUMP_PROC_GROUP);
+ assert_iovec_entry(&imp.iovw.iovec[3], "COREDUMP_RLIMIT=-1");
+ assert_iovec_entry(&imp.iovw.iovec[4], COREDUMP_PROC_GROUP);
+ assert_iovec_entry(&imp.iovw.iovec[5], "_SOURCE_REALTIME_TIMESTAMP=1478389147837945");
+
+ /* Let's check if we get EOF now */
+ r = journal_importer_process_data(&imp);
+ assert_se(r == 0);
+ assert_se(journal_importer_eof(&imp));
+}
+
+static void test_bad_input(void) {
+ _cleanup_(journal_importer_cleanup) JournalImporter imp = {};
+ int r;
+
+ imp.fd = open(get_testdata_dir("/journal-data/journal-2.txt"), O_RDONLY|O_CLOEXEC);
+ assert_se(imp.fd >= 0);
+
+ do
+ r = journal_importer_process_data(&imp);
+ while (!journal_importer_eof(&imp));
+ assert_se(r == 0); /* If we don't have enough input, 0 is returned */
+
+ assert_se(journal_importer_eof(&imp));
+}
+
+int main(int argc, char **argv) {
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+
+ test_basic_parsing();
+ test_bad_input();
+
+ return 0;
+}
diff --git a/src/test/test-log.c b/src/test/test-log.c
index 55a2f9d23b..ae9e113efb 100644
--- a/src/test/test-log.c
+++ b/src/test/test-log.c
@@ -20,7 +20,7 @@
#include <stddef.h>
#include <unistd.h>
-#include "formats-util.h"
+#include "format-util.h"
#include "log.h"
#include "util.h"
diff --git a/src/test/test-loopback.c b/src/test/test-loopback.c
index 7b67337331..8ebd0e0e01 100644
--- a/src/test/test-loopback.c
+++ b/src/test/test-loopback.c
@@ -31,7 +31,7 @@ int main(int argc, char* argv[]) {
r = loopback_setup();
if (r < 0)
- log_error("loopback: %m");
+ log_error_errno(r, "loopback: %m");
return r >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/test/test-mount-util.c b/src/test/test-mount-util.c
new file mode 100644
index 0000000000..7c5929d009
--- /dev/null
+++ b/src/test/test-mount-util.c
@@ -0,0 +1,57 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/mount.h>
+
+#include "log.h"
+#include "mount-util.h"
+#include "string-util.h"
+
+static void test_mount_propagation_flags(const char *name, int ret, unsigned long expected) {
+ long unsigned flags;
+
+ assert(mount_propagation_flags_from_string(name, &flags) == ret);
+
+ if (ret >= 0) {
+ const char *c;
+
+ assert_se(flags == expected);
+
+ c = mount_propagation_flags_to_string(flags);
+ if (isempty(name))
+ assert_se(isempty(c));
+ else
+ assert_se(streq(c, name));
+ }
+}
+
+int main(int argc, char *argv[]) {
+
+ log_set_max_level(LOG_DEBUG);
+
+ test_mount_propagation_flags("shared", 0, MS_SHARED);
+ test_mount_propagation_flags("slave", 0, MS_SLAVE);
+ test_mount_propagation_flags("private", 0, MS_PRIVATE);
+ test_mount_propagation_flags(NULL, 0, 0);
+ test_mount_propagation_flags("", 0, 0);
+ test_mount_propagation_flags("xxxx", -EINVAL, 0);
+ test_mount_propagation_flags(" ", -EINVAL, 0);
+
+ return 0;
+}
diff --git a/src/test/test-namespace.c b/src/test/test-namespace.c
index ff9f35cecd..de7be1f9cc 100644
--- a/src/test/test-namespace.c
+++ b/src/test/test-namespace.c
@@ -132,14 +132,14 @@ int main(int argc, char *argv[]) {
assert_se(sd_id128_get_boot(&bid) >= 0);
sd_id128_to_string(bid, boot_id);
- x = strjoin("/tmp/systemd-private-", boot_id, "-abcd.service-", NULL);
- y = strjoin("/var/tmp/systemd-private-", boot_id, "-abcd.service-", NULL);
+ x = strjoin("/tmp/systemd-private-", boot_id, "-abcd.service-");
+ y = strjoin("/var/tmp/systemd-private-", boot_id, "-abcd.service-");
assert_se(x && y);
test_tmpdir("abcd.service", x, y);
- z = strjoin("/tmp/systemd-private-", boot_id, "-sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device-", NULL);
- zz = strjoin("/var/tmp/systemd-private-", boot_id, "-sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device-", NULL);
+ z = strjoin("/tmp/systemd-private-", boot_id, "-sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device-");
+ zz = strjoin("/var/tmp/systemd-private-", boot_id, "-sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device-");
assert_se(z && zz);
diff --git a/src/test/test-ns.c b/src/test/test-ns.c
index da7a8b0565..0125d905a6 100644
--- a/src/test/test-ns.c
+++ b/src/test/test-ns.c
@@ -77,14 +77,17 @@ int main(int argc, char *argv[]) {
log_info("Not chrooted");
r = setup_namespace(root_directory,
+ NULL,
&ns_info,
(char **) writable,
(char **) readonly,
(char **) inaccessible,
+ &(BindMount) { .source = (char*) "/usr/bin", .destination = (char*) "/etc/systemd", .read_only = true }, 1,
tmp_dir,
var_tmp_dir,
PROTECT_HOME_NO,
PROTECT_SYSTEM_NO,
+ 0,
0);
if (r < 0) {
log_error_errno(r, "Failed to setup namespace: %m");
diff --git a/src/test/test-nss.c b/src/test/test-nss.c
index c43bda5917..b59cb7aa69 100644
--- a/src/test/test-nss.c
+++ b/src/test/test-nss.c
@@ -77,7 +77,8 @@ static void* open_handle(const char* dir, const char* module, int flags) {
path = strjoina("libnss_", module, ".so.2");
handle = dlopen(path, flags);
- assert_se(handle);
+ if (!handle)
+ log_error("Failed to load module %s: %s", module, dlerror());
return handle;
}
@@ -379,75 +380,158 @@ static void test_byaddr(void *handle,
puts("");
}
+static int make_addresses(struct local_address **addresses) {
+ int n;
+ size_t n_alloc;
+ _cleanup_free_ struct local_address *addrs = NULL;
+
+ n = local_addresses(NULL, 0, AF_UNSPEC, &addrs);
+ if (n < 0)
+ log_info_errno(n, "Failed to query local addresses: %m");
+
+ n_alloc = n; /* we _can_ do that */
+ if (!GREEDY_REALLOC(addrs, n_alloc, n + 3))
+ return log_oom();
+
+ addrs[n++] = (struct local_address) { .family = AF_INET,
+ .address.in = { htobe32(0x7F000001) } };
+ addrs[n++] = (struct local_address) { .family = AF_INET,
+ .address.in = { htobe32(0x7F000002) } };
+ addrs[n++] = (struct local_address) { .family = AF_INET6,
+ .address.in6 = in6addr_loopback };
+ return 0;
+}
+
+static int test_one_module(const char* dir,
+ const char *module,
+ char **names,
+ struct local_address *addresses,
+ int n_addresses) {
+ void *handle;
+ char **name;
+ int i;
+
+
+ log_info("======== %s ========", module);
+
+ handle = open_handle(streq(module, "dns") ? NULL : dir,
+ module,
+ RTLD_LAZY|RTLD_NODELETE);
+ if (!handle)
+ return -EINVAL;
+
+ STRV_FOREACH(name, names)
+ test_byname(handle, module, *name);
+
+ for (i = 0; i < n_addresses; i++)
+ test_byaddr(handle, module,
+ &addresses[i].address,
+ FAMILY_ADDRESS_SIZE(addresses[i].family),
+ addresses[i].family);
+
+ log_info(" ");
+ dlclose(handle);
+ return 0;
+}
+
+static int parse_argv(int argc, char **argv,
+ char ***the_modules,
+ char ***the_names,
+ struct local_address **the_addresses, int *n_addresses) {
+
+ int r, n = 0;
+ _cleanup_strv_free_ char **modules = NULL, **names = NULL;
+ _cleanup_free_ struct local_address *addrs = NULL;
+ size_t n_allocated = 0;
+
+ if (argc > 1)
+ modules = strv_new(argv[1], NULL);
+ else
+ modules = strv_new(
#ifdef HAVE_MYHOSTNAME
-# define MODULE1 "myhostname\0"
-#else
-# define MODULE1
+ "myhostname",
#endif
#ifdef HAVE_RESOLVED
-# define MODULE2 "resolve\0"
-#else
-# define MODULE2
+ "resolve",
#endif
#ifdef HAVE_MACHINED
-# define MODULE3 "mymachines\0"
-#else
-# define MODULE3
+ "mymachines",
#endif
-#define MODULE4 "dns\0"
-
-int main(int argc, char **argv) {
- _cleanup_free_ char *dir = NULL, *hostname = NULL;
- const char *module;
-
- const uint32_t local_address_ipv4 = htobe32(0x7F000001);
- const uint32_t local_address_ipv4_2 = htobe32(0x7F000002);
- _cleanup_free_ struct local_address *addresses = NULL;
- int n_addresses;
-
- log_set_max_level(LOG_INFO);
- log_parse_environment();
+ "dns",
+ NULL);
+ if (!modules)
+ return -ENOMEM;
+
+ if (argc > 2) {
+ char **name;
+ int family;
+ union in_addr_union address;
+
+ STRV_FOREACH(name, argv + 2) {
+ r = in_addr_from_string_auto(*name, &family, &address);
+ if (r < 0) {
+ /* assume this is a name */
+ r = strv_extend(&names, *name);
+ if (r < 0)
+ return r;
+ } else {
+ if (!GREEDY_REALLOC0(addrs, n_allocated, n + 1))
+ return -ENOMEM;
+
+ addrs[n++] = (struct local_address) { .family = family,
+ .address = address };
+ }
+ }
+ } else {
+ _cleanup_free_ char *hostname;
- dir = dirname_malloc(argv[0]);
- assert_se(dir);
+ hostname = gethostname_malloc();
+ if (!hostname)
+ return -ENOMEM;
- hostname = gethostname_malloc();
- assert_se(hostname);
+ names = strv_new("localhost", "gateway", "foo_no_such_host", hostname, NULL);
+ if (!names)
+ return -ENOMEM;
- n_addresses = local_addresses(NULL, 0, AF_UNSPEC, &addresses);
- if (n_addresses < 0) {
- log_info_errno(n_addresses, "Failed to query local addresses: %m");
- n_addresses = 0;
+ n = make_addresses(&addrs);
+ if (n < 0)
+ return n;
}
- NULSTR_FOREACH(module, MODULE1 MODULE2 MODULE3 MODULE4) {
- void *handle;
- const char *name;
- int i;
-
- log_info("======== %s ========", module);
-
- handle = open_handle(streq(module, "dns") ? NULL : dir,
- module,
- RTLD_LAZY|RTLD_NODELETE);
- NULSTR_FOREACH(name, "localhost\0" "gateway\0" "foo_no_such_host\0")
- test_byname(handle, module, name);
+ *the_modules = modules;
+ *the_names = names;
+ modules = names = NULL;
+ *the_addresses = addrs;
+ *n_addresses = n;
+ addrs = NULL;
+ return 0;
+}
- test_byname(handle, module, hostname);
+int main(int argc, char **argv) {
+ _cleanup_free_ char *dir = NULL;
+ _cleanup_strv_free_ char **modules = NULL, **names = NULL;
+ _cleanup_free_ struct local_address *addresses = NULL;
+ int n_addresses = 0;
+ char **module;
+ int r;
- test_byaddr(handle, module, &local_address_ipv4, sizeof local_address_ipv4, AF_INET);
- test_byaddr(handle, module, &local_address_ipv4_2, sizeof local_address_ipv4_2, AF_INET);
- test_byaddr(handle, module, &in6addr_loopback, sizeof in6addr_loopback, AF_INET6);
+ log_set_max_level(LOG_INFO);
+ log_parse_environment();
- for (i = 0; i < n_addresses; i++)
- test_byaddr(handle, module,
- &addresses[i].address,
- FAMILY_ADDRESS_SIZE(addresses[i].family),
- addresses[i].family);
+ r = parse_argv(argc, argv, &modules, &names, &addresses, &n_addresses);
+ if (r < 0) {
+ log_error_errno(r, "Failed to parse arguments: %m");
+ return EXIT_FAILURE;
+ }
- dlclose(handle);
+ dir = dirname_malloc(argv[0]);
+ if (!dir)
+ return EXIT_FAILURE;
- log_info(" ");
+ STRV_FOREACH(module, modules) {
+ r = test_one_module(dir, *module, names, addresses, n_addresses);
+ if (r < 0)
+ return EXIT_FAILURE;
}
return EXIT_SUCCESS;
diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c
index a6a09a0031..22df20a1eb 100644
--- a/src/test/test-path-util.c
+++ b/src/test/test-path-util.c
@@ -337,17 +337,17 @@ static void test_path_is_mount_point(void) {
_cleanup_free_ char *dir1 = NULL, *dir1file = NULL, *dirlink1 = NULL, *dirlink1file = NULL;
_cleanup_free_ char *dir2 = NULL, *dir2file = NULL;
- assert_se(path_is_mount_point("/", AT_SYMLINK_FOLLOW) > 0);
- assert_se(path_is_mount_point("/", 0) > 0);
+ assert_se(path_is_mount_point("/", NULL, AT_SYMLINK_FOLLOW) > 0);
+ assert_se(path_is_mount_point("/", NULL, 0) > 0);
- assert_se(path_is_mount_point("/proc", AT_SYMLINK_FOLLOW) > 0);
- assert_se(path_is_mount_point("/proc", 0) > 0);
+ assert_se(path_is_mount_point("/proc", NULL, AT_SYMLINK_FOLLOW) > 0);
+ assert_se(path_is_mount_point("/proc", NULL, 0) > 0);
- assert_se(path_is_mount_point("/proc/1", AT_SYMLINK_FOLLOW) == 0);
- assert_se(path_is_mount_point("/proc/1", 0) == 0);
+ assert_se(path_is_mount_point("/proc/1", NULL, AT_SYMLINK_FOLLOW) == 0);
+ assert_se(path_is_mount_point("/proc/1", NULL, 0) == 0);
- assert_se(path_is_mount_point("/sys", AT_SYMLINK_FOLLOW) > 0);
- assert_se(path_is_mount_point("/sys", 0) > 0);
+ assert_se(path_is_mount_point("/sys", NULL, AT_SYMLINK_FOLLOW) > 0);
+ assert_se(path_is_mount_point("/sys", NULL, 0) > 0);
/* we'll create a hierarchy of different kinds of dir/file/link
* layouts:
@@ -381,10 +381,10 @@ static void test_path_is_mount_point(void) {
assert_se(link1);
assert_se(symlink("file2", link2) == 0);
- assert_se(path_is_mount_point(file1, AT_SYMLINK_FOLLOW) == 0);
- assert_se(path_is_mount_point(file1, 0) == 0);
- assert_se(path_is_mount_point(link1, AT_SYMLINK_FOLLOW) == 0);
- assert_se(path_is_mount_point(link1, 0) == 0);
+ assert_se(path_is_mount_point(file1, NULL, AT_SYMLINK_FOLLOW) == 0);
+ assert_se(path_is_mount_point(file1, NULL, 0) == 0);
+ assert_se(path_is_mount_point(link1, NULL, AT_SYMLINK_FOLLOW) == 0);
+ assert_se(path_is_mount_point(link1, NULL, 0) == 0);
/* directory mountpoints */
dir1 = path_join(NULL, tmp_dir, "dir1");
@@ -400,10 +400,10 @@ static void test_path_is_mount_point(void) {
assert_se(dir2);
assert_se(mkdir(dir2, 0755) == 0);
- assert_se(path_is_mount_point(dir1, AT_SYMLINK_FOLLOW) == 0);
- assert_se(path_is_mount_point(dir1, 0) == 0);
- assert_se(path_is_mount_point(dirlink1, AT_SYMLINK_FOLLOW) == 0);
- assert_se(path_is_mount_point(dirlink1, 0) == 0);
+ assert_se(path_is_mount_point(dir1, NULL, AT_SYMLINK_FOLLOW) == 0);
+ assert_se(path_is_mount_point(dir1, NULL, 0) == 0);
+ assert_se(path_is_mount_point(dirlink1, NULL, AT_SYMLINK_FOLLOW) == 0);
+ assert_se(path_is_mount_point(dirlink1, NULL, 0) == 0);
/* file in subdirectory mountpoints */
dir1file = path_join(NULL, dir1, "file");
@@ -412,10 +412,10 @@ static void test_path_is_mount_point(void) {
assert_se(fd > 0);
close(fd);
- assert_se(path_is_mount_point(dir1file, AT_SYMLINK_FOLLOW) == 0);
- assert_se(path_is_mount_point(dir1file, 0) == 0);
- assert_se(path_is_mount_point(dirlink1file, AT_SYMLINK_FOLLOW) == 0);
- assert_se(path_is_mount_point(dirlink1file, 0) == 0);
+ assert_se(path_is_mount_point(dir1file, NULL, AT_SYMLINK_FOLLOW) == 0);
+ assert_se(path_is_mount_point(dir1file, NULL, 0) == 0);
+ assert_se(path_is_mount_point(dirlink1file, NULL, AT_SYMLINK_FOLLOW) == 0);
+ assert_se(path_is_mount_point(dirlink1file, NULL, 0) == 0);
/* these tests will only work as root */
if (mount(file1, file2, NULL, MS_BIND, NULL) >= 0) {
@@ -423,10 +423,10 @@ static void test_path_is_mount_point(void) {
/* files */
/* capture results in vars, to avoid dangling mounts on failure */
- rf = path_is_mount_point(file2, 0);
- rt = path_is_mount_point(file2, AT_SYMLINK_FOLLOW);
- rlf = path_is_mount_point(link2, 0);
- rlt = path_is_mount_point(link2, AT_SYMLINK_FOLLOW);
+ rf = path_is_mount_point(file2, NULL, 0);
+ rt = path_is_mount_point(file2, NULL, AT_SYMLINK_FOLLOW);
+ rlf = path_is_mount_point(link2, NULL, 0);
+ rlt = path_is_mount_point(link2, NULL, AT_SYMLINK_FOLLOW);
assert_se(umount(file2) == 0);
@@ -444,13 +444,13 @@ static void test_path_is_mount_point(void) {
assert_se(mount(dir2, dir1, NULL, MS_BIND, NULL) >= 0);
- rf = path_is_mount_point(dir1, 0);
- rt = path_is_mount_point(dir1, AT_SYMLINK_FOLLOW);
- rlf = path_is_mount_point(dirlink1, 0);
- rlt = path_is_mount_point(dirlink1, AT_SYMLINK_FOLLOW);
+ rf = path_is_mount_point(dir1, NULL, 0);
+ rt = path_is_mount_point(dir1, NULL, AT_SYMLINK_FOLLOW);
+ rlf = path_is_mount_point(dirlink1, NULL, 0);
+ rlt = path_is_mount_point(dirlink1, NULL, AT_SYMLINK_FOLLOW);
/* its parent is a mount point, but not /file itself */
- rl1f = path_is_mount_point(dirlink1file, 0);
- rl1t = path_is_mount_point(dirlink1file, AT_SYMLINK_FOLLOW);
+ rl1f = path_is_mount_point(dirlink1file, NULL, 0);
+ rl1t = path_is_mount_point(dirlink1file, NULL, AT_SYMLINK_FOLLOW);
assert_se(umount(dir1) == 0);
diff --git a/src/test/test-path.c b/src/test/test-path.c
index 4d3f0e9948..70ac6b3df3 100644
--- a/src/test/test-path.c
+++ b/src/test/test-path.c
@@ -56,7 +56,7 @@ static int setup_test(Manager **m) {
STRV_FOREACH(test_path, tests_path) {
_cleanup_free_ char *p = NULL;
- p = strjoin("/tmp/test-path_", *test_path, NULL);
+ p = strjoin("/tmp/test-path_", *test_path);
assert_se(p);
(void) rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL);
@@ -262,8 +262,8 @@ int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
+ assert_se(set_unit_path(get_testdata_dir("/test-path")) >= 0);
assert_se(runtime_dir = setup_fake_runtime_dir());
- assert_se(set_unit_path(TEST_DIR "/test-path/") >= 0);
for (test = tests; test && *test; test++) {
int r;
diff --git a/src/test/test-proc-cmdline.c b/src/test/test-proc-cmdline.c
index 4101678f19..12dac8585b 100644
--- a/src/test/test-proc-cmdline.c
+++ b/src/test/test-proc-cmdline.c
@@ -35,8 +35,8 @@ static int parse_item(const char *key, const char *value, void *data) {
return 0;
}
-static void test_parse_proc_cmdline(void) {
- assert_se(parse_proc_cmdline(parse_item, &obj, true) >= 0);
+static void test_proc_cmdline_parse(void) {
+ assert_se(proc_cmdline_parse(parse_item, &obj, true) >= 0);
}
static void test_runlevel_to_target(void) {
@@ -55,11 +55,101 @@ static void test_runlevel_to_target(void) {
assert_se(streq_ptr(runlevel_to_target("rd.rescue"), SPECIAL_RESCUE_TARGET));
}
+static void test_proc_cmdline_get_key(void) {
+ _cleanup_free_ char *value = NULL;
+
+ putenv((char*) "SYSTEMD_PROC_CMDLINE=foo_bar=quux wuff-piep=tuet zumm");
+
+ assert_se(proc_cmdline_get_key("", 0, &value) == -EINVAL);
+ assert_se(proc_cmdline_get_key("abc", 0, NULL) == 0);
+ assert_se(proc_cmdline_get_key("abc", 0, &value) == 0 && value == NULL);
+ assert_se(proc_cmdline_get_key("abc", PROC_CMDLINE_VALUE_OPTIONAL, &value) == 0 && value == NULL);
+
+ assert_se(proc_cmdline_get_key("foo_bar", 0, &value) > 0 && streq_ptr(value, "quux"));
+ value = mfree(value);
+ assert_se(proc_cmdline_get_key("foo_bar", PROC_CMDLINE_VALUE_OPTIONAL, &value) > 0 && streq_ptr(value, "quux"));
+ value = mfree(value);
+ assert_se(proc_cmdline_get_key("foo-bar", 0, &value) > 0 && streq_ptr(value, "quux"));
+ value = mfree(value);
+ assert_se(proc_cmdline_get_key("foo-bar", PROC_CMDLINE_VALUE_OPTIONAL, &value) > 0 && streq_ptr(value, "quux"));
+ value = mfree(value);
+ assert_se(proc_cmdline_get_key("foo-bar", 0, NULL) == 0);
+ assert_se(proc_cmdline_get_key("foo-bar", PROC_CMDLINE_VALUE_OPTIONAL, NULL) == -EINVAL);
+
+ assert_se(proc_cmdline_get_key("wuff-piep", 0, &value) > 0 && streq_ptr(value, "tuet"));
+ value = mfree(value);
+ assert_se(proc_cmdline_get_key("wuff-piep", PROC_CMDLINE_VALUE_OPTIONAL, &value) > 0 && streq_ptr(value, "tuet"));
+ value = mfree(value);
+ assert_se(proc_cmdline_get_key("wuff_piep", 0, &value) > 0 && streq_ptr(value, "tuet"));
+ value = mfree(value);
+ assert_se(proc_cmdline_get_key("wuff_piep", PROC_CMDLINE_VALUE_OPTIONAL, &value) > 0 && streq_ptr(value, "tuet"));
+ value = mfree(value);
+ assert_se(proc_cmdline_get_key("wuff_piep", 0, NULL) == 0);
+ assert_se(proc_cmdline_get_key("wuff_piep", PROC_CMDLINE_VALUE_OPTIONAL, NULL) == -EINVAL);
+
+ assert_se(proc_cmdline_get_key("zumm", 0, &value) == 0 && value == NULL);
+ assert_se(proc_cmdline_get_key("zumm", PROC_CMDLINE_VALUE_OPTIONAL, &value) > 0 && value == NULL);
+ assert_se(proc_cmdline_get_key("zumm", 0, NULL) > 0);
+}
+
+static void test_proc_cmdline_get_bool(void) {
+ bool value = false;
+
+ putenv((char*) "SYSTEMD_PROC_CMDLINE=foo_bar bar-waldo=1 x_y-z=0 quux=miep");
+
+ assert_se(proc_cmdline_get_bool("", &value) == -EINVAL);
+ assert_se(proc_cmdline_get_bool("abc", &value) == 0 && value == false);
+ assert_se(proc_cmdline_get_bool("foo_bar", &value) > 0 && value == true);
+ assert_se(proc_cmdline_get_bool("foo-bar", &value) > 0 && value == true);
+ assert_se(proc_cmdline_get_bool("bar-waldo", &value) > 0 && value == true);
+ assert_se(proc_cmdline_get_bool("bar_waldo", &value) > 0 && value == true);
+ assert_se(proc_cmdline_get_bool("x_y-z", &value) > 0 && value == false);
+ assert_se(proc_cmdline_get_bool("x-y-z", &value) > 0 && value == false);
+ assert_se(proc_cmdline_get_bool("x-y_z", &value) > 0 && value == false);
+ assert_se(proc_cmdline_get_bool("x_y_z", &value) > 0 && value == false);
+ assert_se(proc_cmdline_get_bool("quux", &value) == -EINVAL && value == false);
+}
+
+static void test_proc_cmdline_key_streq(void) {
+
+ assert_se(proc_cmdline_key_streq("", ""));
+ assert_se(proc_cmdline_key_streq("a", "a"));
+ assert_se(!proc_cmdline_key_streq("", "a"));
+ assert_se(!proc_cmdline_key_streq("a", ""));
+ assert_se(proc_cmdline_key_streq("a", "a"));
+ assert_se(!proc_cmdline_key_streq("a", "b"));
+ assert_se(proc_cmdline_key_streq("x-y-z", "x-y-z"));
+ assert_se(proc_cmdline_key_streq("x-y-z", "x_y_z"));
+ assert_se(proc_cmdline_key_streq("x-y-z", "x-y_z"));
+ assert_se(proc_cmdline_key_streq("x-y-z", "x_y-z"));
+ assert_se(proc_cmdline_key_streq("x_y-z", "x-y_z"));
+ assert_se(!proc_cmdline_key_streq("x_y-z", "x-z_z"));
+}
+
+static void test_proc_cmdline_key_startswith(void) {
+
+ assert_se(proc_cmdline_key_startswith("", ""));
+ assert_se(proc_cmdline_key_startswith("x", ""));
+ assert_se(!proc_cmdline_key_startswith("", "x"));
+ assert_se(proc_cmdline_key_startswith("x", "x"));
+ assert_se(!proc_cmdline_key_startswith("x", "y"));
+ assert_se(!proc_cmdline_key_startswith("foo-bar", "quux"));
+ assert_se(proc_cmdline_key_startswith("foo-bar", "foo"));
+ assert_se(proc_cmdline_key_startswith("foo-bar", "foo-bar"));
+ assert_se(proc_cmdline_key_startswith("foo-bar", "foo_bar"));
+ assert_se(proc_cmdline_key_startswith("foo-bar", "foo_"));
+ assert_se(!proc_cmdline_key_startswith("foo-bar", "foo_xx"));
+}
+
int main(void) {
log_parse_environment();
log_open();
- test_parse_proc_cmdline();
+ test_proc_cmdline_parse();
+ test_proc_cmdline_key_streq();
+ test_proc_cmdline_key_startswith();
+ test_proc_cmdline_get_key();
+ test_proc_cmdline_get_bool();
test_runlevel_to_target();
return 0;
diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c
index 9ada46b1e9..c5edbcc5d2 100644
--- a/src/test/test-process-util.c
+++ b/src/test/test-process-util.c
@@ -193,7 +193,14 @@ static void test_get_process_cmdline_harder(void) {
fd = mkostemp(path, O_CLOEXEC);
assert_se(fd >= 0);
- assert_se(mount(path, "/proc/self/cmdline", "bind", MS_BIND, NULL) >= 0);
+
+ if (mount(path, "/proc/self/cmdline", "bind", MS_BIND, NULL) < 0) {
+ /* This happens under selinux… Abort the test in this case. */
+ log_warning_errno(errno, "mount(..., \"/proc/self/cmdline\", \"bind\", ...) failed: %m");
+ assert(errno == EACCES);
+ return;
+ }
+
assert_se(unlink(path) >= 0);
assert_se(prctl(PR_SET_NAME, "testa") >= 0);
@@ -348,10 +355,70 @@ static void test_get_process_cmdline_harder(void) {
_exit(0);
}
+static void test_rename_process_one(const char *p, int ret) {
+ _cleanup_free_ char *comm = NULL, *cmdline = NULL;
+ pid_t pid;
+ int r;
+
+ pid = fork();
+ assert_se(pid >= 0);
+
+ if (pid > 0) {
+ siginfo_t si;
+
+ assert_se(wait_for_terminate(pid, &si) >= 0);
+ assert_se(si.si_code == CLD_EXITED);
+ assert_se(si.si_status == EXIT_SUCCESS);
+
+ return;
+ }
+
+ /* child */
+ r = rename_process(p);
+
+ assert_se(r == ret ||
+ (ret == 0 && r >= 0) ||
+ (ret > 0 && r > 0));
+
+ if (r < 0)
+ goto finish;
+
+#ifdef HAVE_VALGRIND_VALGRIND_H
+ /* see above, valgrind is weird, we can't verify what we are doing here */
+ if (RUNNING_ON_VALGRIND)
+ goto finish;
+#endif
+
+ assert_se(get_process_comm(0, &comm) >= 0);
+ log_info("comm = <%s>", comm);
+ assert_se(strneq(comm, p, 15));
+
+ assert_se(get_process_cmdline(0, 0, false, &cmdline) >= 0);
+ log_info("cmdline = <%s>", cmdline);
+ assert_se(strneq(p, cmdline, strlen("test-process-util")));
+ assert_se(startswith(p, cmdline));
+
+finish:
+ _exit(EXIT_SUCCESS);
+}
+
+static void test_rename_process(void) {
+ test_rename_process_one(NULL, -EINVAL);
+ test_rename_process_one("", -EINVAL);
+ test_rename_process_one("foo", 1); /* should always fit */
+ test_rename_process_one("this is a really really long process name, followed by some more words", 0); /* unlikely to fit */
+ test_rename_process_one("1234567", 1); /* should always fit */
+}
+
int main(int argc, char *argv[]) {
+
+ log_set_max_level(LOG_DEBUG);
log_parse_environment();
log_open();
+ saved_argc = argc;
+ saved_argv = argv;
+
if (argc > 1) {
pid_t pid = 0;
@@ -366,6 +433,7 @@ int main(int argc, char *argv[]) {
test_pid_is_alive();
test_personality();
test_get_process_cmdline_harder();
+ test_rename_process();
return 0;
}
diff --git a/src/test/test-replace-var.c b/src/test/test-replace-var.c
index 297effce79..60e05d04c9 100644
--- a/src/test/test-replace-var.c
+++ b/src/test/test-replace-var.c
@@ -25,7 +25,7 @@
#include "util.h"
static char *lookup(const char *variable, void *userdata) {
- return strjoin("<<<", variable, ">>>", NULL);
+ return strjoin("<<<", variable, ">>>");
}
int main(int argc, char *argv[]) {
diff --git a/src/test/test-sched-prio.c b/src/test/test-sched-prio.c
index 7b37910c33..81d9abc2d5 100644
--- a/src/test/test-sched-prio.c
+++ b/src/test/test-sched-prio.c
@@ -34,10 +34,9 @@ int main(int argc, char *argv[]) {
FDSet *fdset = NULL;
int r;
- assert_se(runtime_dir = setup_fake_runtime_dir());
-
/* prepare the test */
- assert_se(set_unit_path(TEST_DIR) >= 0);
+ assert_se(set_unit_path(get_testdata_dir("")) >= 0);
+ assert_se(runtime_dir = setup_fake_runtime_dir());
r = manager_new(UNIT_FILE_USER, true, &m);
if (MANAGER_SKIP_TEST(r)) {
log_notice_errno(r, "Skipping test: manager_new: %m");
diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c
index 43d1567288..34a1275162 100644
--- a/src/test/test-seccomp.c
+++ b/src/test/test-seccomp.c
@@ -17,16 +17,25 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <sched.h>
#include <stdlib.h>
#include <sys/eventfd.h>
+#include <sys/mman.h>
#include <unistd.h>
+#include <sys/poll.h>
+#include "alloc-util.h"
#include "fd-util.h"
#include "macro.h"
+#include "missing.h"
+#include "nsflags.h"
#include "process-util.h"
+#include "raw-clone.h"
#include "seccomp-util.h"
+#include "set.h"
#include "string-util.h"
#include "util.h"
+#include "virt.h"
static void test_seccomp_arch_to_string(void) {
uint32_t a, b;
@@ -87,7 +96,6 @@ static void test_filter_sets(void) {
if (!is_seccomp_available())
return;
-
if (geteuid() != 0)
return;
@@ -103,16 +111,16 @@ static void test_filter_sets(void) {
int fd;
if (i == SYSCALL_FILTER_SET_DEFAULT) /* if we look at the default set, whitelist instead of blacklist */
- r = seccomp_load_filter_set(SCMP_ACT_ERRNO(EPERM), syscall_filter_sets + i, SCMP_ACT_ALLOW);
+ r = seccomp_load_syscall_filter_set(SCMP_ACT_ERRNO(EUCLEAN), syscall_filter_sets + i, SCMP_ACT_ALLOW);
else
- r = seccomp_load_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + i, SCMP_ACT_ERRNO(EPERM));
+ r = seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + i, SCMP_ACT_ERRNO(EUCLEAN));
if (r < 0)
_exit(EXIT_FAILURE);
/* Test the sycall filter with one random system call */
fd = eventfd(0, EFD_NONBLOCK|EFD_CLOEXEC);
if (IN_SET(i, SYSCALL_FILTER_SET_IO_EVENT, SYSCALL_FILTER_SET_DEFAULT))
- assert_se(fd < 0 && errno == EPERM);
+ assert_se(fd < 0 && errno == EUCLEAN);
else {
assert_se(fd >= 0);
safe_close(fd);
@@ -125,12 +133,385 @@ static void test_filter_sets(void) {
}
}
+static void test_restrict_namespace(void) {
+ _cleanup_free_ char *s = NULL;
+ unsigned long ul;
+ pid_t pid;
+
+ assert_se(namespace_flag_to_string(0) == NULL);
+ assert_se(streq(namespace_flag_to_string(CLONE_NEWNS), "mnt"));
+ assert_se(namespace_flag_to_string(CLONE_NEWNS|CLONE_NEWIPC) == NULL);
+ assert_se(streq(namespace_flag_to_string(CLONE_NEWCGROUP), "cgroup"));
+
+ assert_se(namespace_flag_from_string("mnt") == CLONE_NEWNS);
+ assert_se(namespace_flag_from_string(NULL) == 0);
+ assert_se(namespace_flag_from_string("") == 0);
+ assert_se(namespace_flag_from_string("uts") == CLONE_NEWUTS);
+ assert_se(namespace_flag_from_string(namespace_flag_to_string(CLONE_NEWUTS)) == CLONE_NEWUTS);
+ assert_se(streq(namespace_flag_to_string(namespace_flag_from_string("ipc")), "ipc"));
+
+ assert_se(namespace_flag_from_string_many(NULL, &ul) == 0 && ul == 0);
+ assert_se(namespace_flag_from_string_many("", &ul) == 0 && ul == 0);
+ assert_se(namespace_flag_from_string_many("mnt uts ipc", &ul) == 0 && ul == (CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWIPC));
+
+ assert_se(namespace_flag_to_string_many(NAMESPACE_FLAGS_ALL, &s) == 0);
+ assert_se(streq(s, "cgroup ipc net mnt pid user uts"));
+ assert_se(namespace_flag_from_string_many(s, &ul) == 0 && ul == NAMESPACE_FLAGS_ALL);
+
+#if SECCOMP_RESTRICT_NAMESPACES_BROKEN == 0
+
+ if (!is_seccomp_available())
+ return;
+ if (geteuid() != 0)
+ return;
+
+ pid = fork();
+ assert_se(pid >= 0);
+
+ if (pid == 0) {
+
+ assert_se(seccomp_restrict_namespaces(CLONE_NEWNS|CLONE_NEWNET) >= 0);
+
+ assert_se(unshare(CLONE_NEWNS) == 0);
+ assert_se(unshare(CLONE_NEWNET) == 0);
+ assert_se(unshare(CLONE_NEWUTS) == -1);
+ assert_se(errno == EPERM);
+ assert_se(unshare(CLONE_NEWIPC) == -1);
+ assert_se(errno == EPERM);
+ assert_se(unshare(CLONE_NEWNET|CLONE_NEWUTS) == -1);
+ assert_se(errno == EPERM);
+
+ /* We use fd 0 (stdin) here, which of course will fail with EINVAL on setns(). Except of course our
+ * seccomp filter worked, and hits first and makes it return EPERM */
+ assert_se(setns(0, CLONE_NEWNS) == -1);
+ assert_se(errno == EINVAL);
+ assert_se(setns(0, CLONE_NEWNET) == -1);
+ assert_se(errno == EINVAL);
+ assert_se(setns(0, CLONE_NEWUTS) == -1);
+ assert_se(errno == EPERM);
+ assert_se(setns(0, CLONE_NEWIPC) == -1);
+ assert_se(errno == EPERM);
+ assert_se(setns(0, CLONE_NEWNET|CLONE_NEWUTS) == -1);
+ assert_se(errno == EPERM);
+ assert_se(setns(0, 0) == -1);
+ assert_se(errno == EPERM);
+
+ pid = raw_clone(CLONE_NEWNS);
+ assert_se(pid >= 0);
+ if (pid == 0)
+ _exit(EXIT_SUCCESS);
+ pid = raw_clone(CLONE_NEWNET);
+ assert_se(pid >= 0);
+ if (pid == 0)
+ _exit(EXIT_SUCCESS);
+ pid = raw_clone(CLONE_NEWUTS);
+ assert_se(pid < 0);
+ assert_se(errno == EPERM);
+ pid = raw_clone(CLONE_NEWIPC);
+ assert_se(pid < 0);
+ assert_se(errno == EPERM);
+ pid = raw_clone(CLONE_NEWNET|CLONE_NEWUTS);
+ assert_se(pid < 0);
+ assert_se(errno == EPERM);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ assert_se(wait_for_terminate_and_warn("nsseccomp", pid, true) == EXIT_SUCCESS);
+#endif
+}
+
+static void test_protect_sysctl(void) {
+ pid_t pid;
+
+ if (!is_seccomp_available())
+ return;
+ if (geteuid() != 0)
+ return;
+
+ if (detect_container() > 0) /* in containers _sysctl() is likely missing anyway */
+ return;
+
+ pid = fork();
+ assert_se(pid >= 0);
+
+ if (pid == 0) {
+ assert_se(syscall(__NR__sysctl, NULL) < 0);
+ assert_se(errno == EFAULT);
+
+ assert_se(seccomp_protect_sysctl() >= 0);
+
+ assert_se(syscall(__NR__sysctl, 0, 0, 0) < 0);
+ assert_se(errno == EPERM);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ assert_se(wait_for_terminate_and_warn("sysctlseccomp", pid, true) == EXIT_SUCCESS);
+}
+
+static void test_restrict_address_families(void) {
+ pid_t pid;
+
+ if (!is_seccomp_available())
+ return;
+ if (geteuid() != 0)
+ return;
+
+ pid = fork();
+ assert_se(pid >= 0);
+
+ if (pid == 0) {
+ int fd;
+ Set *s;
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ assert_se(fd >= 0);
+ safe_close(fd);
+
+ fd = socket(AF_UNIX, SOCK_DGRAM, 0);
+ assert_se(fd >= 0);
+ safe_close(fd);
+
+ fd = socket(AF_NETLINK, SOCK_DGRAM, 0);
+ assert_se(fd >= 0);
+ safe_close(fd);
+
+ assert_se(s = set_new(NULL));
+ assert_se(set_put(s, INT_TO_PTR(AF_UNIX)) >= 0);
+
+ assert_se(seccomp_restrict_address_families(s, false) >= 0);
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ assert_se(fd >= 0);
+ safe_close(fd);
+
+#if SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN
+ fd = socket(AF_UNIX, SOCK_DGRAM, 0);
+ assert_se(fd >= 0);
+ safe_close(fd);
+#else
+ assert_se(socket(AF_UNIX, SOCK_DGRAM, 0) < 0);
+ assert_se(errno == EAFNOSUPPORT);
+#endif
+
+ fd = socket(AF_NETLINK, SOCK_DGRAM, 0);
+ assert_se(fd >= 0);
+ safe_close(fd);
+
+ set_clear(s);
+
+ assert_se(set_put(s, INT_TO_PTR(AF_INET)) >= 0);
+
+ assert_se(seccomp_restrict_address_families(s, true) >= 0);
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ assert_se(fd >= 0);
+ safe_close(fd);
+
+#if SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN
+ fd = socket(AF_UNIX, SOCK_DGRAM, 0);
+ assert_se(fd >= 0);
+ safe_close(fd);
+
+ fd = socket(AF_NETLINK, SOCK_DGRAM, 0);
+ assert_se(fd >= 0);
+ safe_close(fd);
+#else
+ assert_se(socket(AF_UNIX, SOCK_DGRAM, 0) < 0);
+ assert_se(errno == EAFNOSUPPORT);
+
+ assert_se(socket(AF_NETLINK, SOCK_DGRAM, 0) < 0);
+ assert_se(errno == EAFNOSUPPORT);
+#endif
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ assert_se(wait_for_terminate_and_warn("socketseccomp", pid, true) == EXIT_SUCCESS);
+}
+
+static void test_restrict_realtime(void) {
+ pid_t pid;
+
+ if (!is_seccomp_available())
+ return;
+ if (geteuid() != 0)
+ return;
+
+ if (detect_container() > 0) /* in containers RT privs are likely missing anyway */
+ return;
+
+ pid = fork();
+ assert_se(pid >= 0);
+
+ if (pid == 0) {
+ assert_se(sched_setscheduler(0, SCHED_FIFO, &(struct sched_param) { .sched_priority = 1 }) >= 0);
+ assert_se(sched_setscheduler(0, SCHED_RR, &(struct sched_param) { .sched_priority = 1 }) >= 0);
+ assert_se(sched_setscheduler(0, SCHED_IDLE, &(struct sched_param) { .sched_priority = 0 }) >= 0);
+ assert_se(sched_setscheduler(0, SCHED_BATCH, &(struct sched_param) { .sched_priority = 0 }) >= 0);
+ assert_se(sched_setscheduler(0, SCHED_OTHER, &(struct sched_param) {}) >= 0);
+
+ assert_se(seccomp_restrict_realtime() >= 0);
+
+ assert_se(sched_setscheduler(0, SCHED_IDLE, &(struct sched_param) { .sched_priority = 0 }) >= 0);
+ assert_se(sched_setscheduler(0, SCHED_BATCH, &(struct sched_param) { .sched_priority = 0 }) >= 0);
+ assert_se(sched_setscheduler(0, SCHED_OTHER, &(struct sched_param) {}) >= 0);
+
+ assert_se(sched_setscheduler(0, SCHED_FIFO, &(struct sched_param) { .sched_priority = 1 }) < 0);
+ assert_se(errno == EPERM);
+ assert_se(sched_setscheduler(0, SCHED_RR, &(struct sched_param) { .sched_priority = 1 }) < 0);
+ assert_se(errno == EPERM);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ assert_se(wait_for_terminate_and_warn("realtimeseccomp", pid, true) == EXIT_SUCCESS);
+}
+
+static void test_memory_deny_write_execute(void) {
+ pid_t pid;
+
+ if (!is_seccomp_available())
+ return;
+ if (geteuid() != 0)
+ return;
+
+ pid = fork();
+ assert_se(pid >= 0);
+
+ if (pid == 0) {
+ void *p;
+
+ p = mmap(NULL, page_size(), PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1,0);
+ assert_se(p != MAP_FAILED);
+ assert_se(munmap(p, page_size()) >= 0);
+
+ p = mmap(NULL, page_size(), PROT_WRITE|PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1,0);
+ assert_se(p != MAP_FAILED);
+ assert_se(munmap(p, page_size()) >= 0);
+
+ assert_se(seccomp_memory_deny_write_execute() >= 0);
+
+#if SECCOMP_MEMORY_DENY_WRITE_EXECUTE_BROKEN
+ p = mmap(NULL, page_size(), PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1,0);
+ assert_se(p != MAP_FAILED);
+ assert_se(munmap(p, page_size()) >= 0);
+#else
+ p = mmap(NULL, page_size(), PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1,0);
+ assert_se(p == MAP_FAILED);
+ assert_se(errno == EPERM);
+#endif
+
+ p = mmap(NULL, page_size(), PROT_WRITE|PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1,0);
+ assert_se(p != MAP_FAILED);
+ assert_se(munmap(p, page_size()) >= 0);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ assert_se(wait_for_terminate_and_warn("memoryseccomp", pid, true) == EXIT_SUCCESS);
+}
+
+static void test_restrict_archs(void) {
+ pid_t pid;
+
+ if (!is_seccomp_available())
+ return;
+ if (geteuid() != 0)
+ return;
+
+ pid = fork();
+ assert_se(pid >= 0);
+
+ if (pid == 0) {
+ _cleanup_set_free_ Set *s = NULL;
+
+ assert_se(access("/", F_OK) >= 0);
+
+ assert_se(s = set_new(NULL));
+
+#ifdef __x86_64__
+ assert_se(set_put(s, UINT32_TO_PTR(SCMP_ARCH_X86+1)) >= 0);
+#endif
+ assert_se(seccomp_restrict_archs(s) >= 0);
+
+ assert_se(access("/", F_OK) >= 0);
+ assert_se(seccomp_restrict_archs(NULL) >= 0);
+
+ assert_se(access("/", F_OK) >= 0);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ assert_se(wait_for_terminate_and_warn("archseccomp", pid, true) == EXIT_SUCCESS);
+}
+
+static void test_load_syscall_filter_set_raw(void) {
+ pid_t pid;
+
+ if (!is_seccomp_available())
+ return;
+ if (geteuid() != 0)
+ return;
+
+ pid = fork();
+ assert_se(pid >= 0);
+
+ if (pid == 0) {
+ _cleanup_set_free_ Set *s = NULL;
+
+ assert_se(access("/", F_OK) >= 0);
+ assert_se(poll(NULL, 0, 0) == 0);
+
+ assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, NULL, SCMP_ACT_KILL) >= 0);
+ assert_se(access("/", F_OK) >= 0);
+ assert_se(poll(NULL, 0, 0) == 0);
+
+ assert_se(s = set_new(NULL));
+ assert_se(set_put(s, UINT32_TO_PTR(__NR_access + 1)) >= 0);
+
+ assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN)) >= 0);
+
+ assert_se(access("/", F_OK) < 0);
+ assert_se(errno == EUCLEAN);
+
+ assert_se(poll(NULL, 0, 0) == 0);
+
+ s = set_free(s);
+
+ assert_se(s = set_new(NULL));
+ assert_se(set_put(s, UINT32_TO_PTR(__NR_poll + 1)) >= 0);
+
+ assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUNATCH)) >= 0);
+
+ assert_se(access("/", F_OK) < 0);
+ assert_se(errno == EUCLEAN);
+
+ assert_se(poll(NULL, 0, 0) < 0);
+ assert_se(errno == EUNATCH);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ assert_se(wait_for_terminate_and_warn("syscallrawseccomp", pid, true) == EXIT_SUCCESS);
+}
+
int main(int argc, char *argv[]) {
+ log_set_max_level(LOG_DEBUG);
+
test_seccomp_arch_to_string();
test_architecture_table();
test_syscall_filter_set_find();
test_filter_sets();
+ test_restrict_namespace();
+ test_protect_sysctl();
+ test_restrict_address_families();
+ test_restrict_realtime();
+ test_memory_deny_write_execute();
+ test_restrict_archs();
+ test_load_syscall_filter_set_raw();
return 0;
}
diff --git a/src/test/test-selinux.c b/src/test/test-selinux.c
index 7545ad3764..b676c25913 100644
--- a/src/test/test-selinux.c
+++ b/src/test/test-selinux.c
@@ -56,7 +56,7 @@ static void test_loading(void) {
n1 = now(CLOCK_MONOTONIC);
r = mac_selinux_init();
n2 = now(CLOCK_MONOTONIC);
- log_info_errno(r, "mac_selinux_init → %d (%m) %.2fs", r, (n2 - n1)/1e6);
+ log_info_errno(r, "mac_selinux_init → %d %.2fs (%m)", r, (n2 - n1)/1e6);
}
static void test_cleanup(void) {
@@ -78,18 +78,18 @@ static void test_misc(const char* fname) {
log_info("============ %s ==========", __func__);
r = mac_selinux_get_our_label(&label);
- log_info_errno(r, "mac_selinux_get_our_label → %d (%m), \"%s\"",
+ log_info_errno(r, "mac_selinux_get_our_label → %d, \"%s\" (%m)",
r, strnull(label));
r = mac_selinux_get_create_label_from_exe(fname, &label2);
- log_info_errno(r, "mac_selinux_create_label_from_exe → %d (%m), \"%s\"",
+ log_info_errno(r, "mac_selinux_create_label_from_exe → %d, \"%s\" (%m)",
r, strnull(label2));
fd = socket(AF_INET, SOCK_DGRAM, 0);
assert_se(fd >= 0);
r = mac_selinux_get_child_mls_label(fd, fname, label2, &label3);
- log_info_errno(r, "mac_selinux_get_child_mls_label → %d (%m), \"%s\"",
+ log_info_errno(r, "mac_selinux_get_child_mls_label → %d, \"%s\" (%m)",
r, strnull(label3));
}
diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c
index 1f853a7f16..8ac1d7989f 100644
--- a/src/test/test-socket-util.c
+++ b/src/test/test-socket-util.c
@@ -92,6 +92,14 @@ static void test_socket_address_parse(void) {
assert_se(socket_address_parse(&a, "@abstract") >= 0);
assert_se(a.sockaddr.sa.sa_family == AF_UNIX);
+
+ assert_se(socket_address_parse(&a, "vsock::1234") >= 0);
+ assert_se(a.sockaddr.sa.sa_family == AF_VSOCK);
+ assert_se(socket_address_parse(&a, "vsock:2:1234") >= 0);
+ assert_se(a.sockaddr.sa.sa_family == AF_VSOCK);
+ assert_se(socket_address_parse(&a, "vsock:2:1234x") < 0);
+ assert_se(socket_address_parse(&a, "vsock:2x:1234") < 0);
+ assert_se(socket_address_parse(&a, "vsock:2") < 0);
}
static void test_socket_address_parse_netlink(void) {
@@ -145,6 +153,14 @@ static void test_socket_address_equal(void) {
assert_se(socket_address_parse_netlink(&a, "firewall") >= 0);
assert_se(socket_address_parse_netlink(&b, "firewall") >= 0);
assert_se(socket_address_equal(&a, &b));
+
+ assert_se(socket_address_parse(&a, "vsock:2:1234") >= 0);
+ assert_se(socket_address_parse(&b, "vsock:2:1234") >= 0);
+ assert_se(socket_address_equal(&a, &b));
+ assert_se(socket_address_parse(&b, "vsock:2:1235") >= 0);
+ assert_se(!socket_address_equal(&a, &b));
+ assert_se(socket_address_parse(&b, "vsock:3:1234") >= 0);
+ assert_se(!socket_address_equal(&a, &b));
}
static void test_socket_address_get_path(void) {
@@ -161,6 +177,9 @@ static void test_socket_address_get_path(void) {
assert_se(socket_address_parse(&a, "/foo/bar") >= 0);
assert_se(streq(socket_address_get_path(&a), "/foo/bar"));
+
+ assert_se(socket_address_parse(&a, "vsock:2:1234") >= 0);
+ assert_se(!socket_address_get_path(&a));
}
static void test_socket_address_is(void) {
@@ -408,11 +427,18 @@ static void test_sockaddr_equal(void) {
.in6.sin6_port = 0,
.in6.sin6_addr = IN6ADDR_ANY_INIT,
};
+ union sockaddr_union e = {
+ .vm.svm_family = AF_VSOCK,
+ .vm.svm_port = 0,
+ .vm.svm_cid = VMADDR_CID_ANY,
+ };
assert_se(sockaddr_equal(&a, &a));
assert_se(sockaddr_equal(&a, &b));
assert_se(sockaddr_equal(&d, &d));
+ assert_se(sockaddr_equal(&e, &e));
assert_se(!sockaddr_equal(&a, &c));
assert_se(!sockaddr_equal(&b, &c));
+ assert_se(!sockaddr_equal(&a, &e));
}
static void test_sockaddr_un_len(void) {
@@ -430,6 +456,23 @@ static void test_sockaddr_un_len(void) {
assert_se(SOCKADDR_UN_LEN(abstract) == offsetof(struct sockaddr_un, sun_path) + 1 + strlen(abstract.sun_path + 1));
}
+static void test_in_addr_is_multicast(void) {
+ union in_addr_union a, b;
+ int f;
+
+ assert_se(in_addr_from_string_auto("192.168.3.11", &f, &a) >= 0);
+ assert_se(in_addr_is_multicast(f, &a) == 0);
+
+ assert_se(in_addr_from_string_auto("224.0.0.1", &f, &a) >= 0);
+ assert_se(in_addr_is_multicast(f, &a) == 1);
+
+ assert_se(in_addr_from_string_auto("FF01:0:0:0:0:0:0:1", &f, &b) >= 0);
+ assert_se(in_addr_is_multicast(f, &b) == 1);
+
+ assert_se(in_addr_from_string_auto("2001:db8::c:69b:aeff:fe53:743e", &f, &b) >= 0);
+ assert_se(in_addr_is_multicast(f, &b) == 0);
+}
+
int main(int argc, char *argv[]) {
log_set_max_level(LOG_DEBUG);
@@ -456,5 +499,7 @@ int main(int argc, char *argv[]) {
test_sockaddr_un_len();
+ test_in_addr_is_multicast();
+
return 0;
}
diff --git a/src/test/test-stat-util.c b/src/test/test-stat-util.c
index 6c34250a01..3ff2aadea4 100644
--- a/src/test/test-stat-util.c
+++ b/src/test/test-stat-util.c
@@ -18,12 +18,15 @@
***/
#include <fcntl.h>
+#include <linux/magic.h>
#include <unistd.h>
#include "alloc-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "macro.h"
+#include "missing.h"
+#include "mount-util.h"
#include "stat-util.h"
static void test_files_same(void) {
@@ -60,9 +63,38 @@ static void test_is_symlink(void) {
unlink(name_link);
}
+static void test_path_is_os_tree(void) {
+ assert_se(path_is_os_tree("/") > 0);
+ assert_se(path_is_os_tree("/etc") == 0);
+ assert_se(path_is_os_tree("/idontexist") == -ENOENT);
+}
+
+static void test_path_check_fstype(void) {
+ /* run might not be a mount point in build chroots */
+ if (path_is_mount_point("/run", NULL, AT_SYMLINK_FOLLOW) > 0) {
+ assert_se(path_check_fstype("/run", TMPFS_MAGIC) > 0);
+ assert_se(path_check_fstype("/run", BTRFS_SUPER_MAGIC) == 0);
+ }
+ assert_se(path_check_fstype("/proc", PROC_SUPER_MAGIC) > 0);
+ assert_se(path_check_fstype("/proc", BTRFS_SUPER_MAGIC) == 0);
+ assert_se(path_check_fstype("/proc", BTRFS_SUPER_MAGIC) == 0);
+ assert_se(path_check_fstype("/i-dont-exist", BTRFS_SUPER_MAGIC) == -ENOENT);
+}
+
+static void test_path_is_temporary_fs(void) {
+ /* run might not be a mount point in build chroots */
+ if (path_is_mount_point("/run", NULL, AT_SYMLINK_FOLLOW) > 0)
+ assert_se(path_is_temporary_fs("/run") > 0);
+ assert_se(path_is_temporary_fs("/proc") == 0);
+ assert_se(path_is_temporary_fs("/i-dont-exist") == -ENOENT);
+}
+
int main(int argc, char *argv[]) {
test_files_same();
test_is_symlink();
+ test_path_is_os_tree();
+ test_path_check_fstype();
+ test_path_is_temporary_fs();
return 0;
}
diff --git a/src/test/test-string-util.c b/src/test/test-string-util.c
index d0f84d70bc..4b3e924cfb 100644
--- a/src/test/test-string-util.c
+++ b/src/test/test-string-util.c
@@ -29,31 +29,20 @@ static void test_string_erase(void) {
assert_se(streq(string_erase(x), ""));
x = strdupa("1");
- assert_se(streq(string_erase(x), "x"));
-
- x = strdupa("12");
- assert_se(streq(string_erase(x), "xx"));
-
- x = strdupa("123");
- assert_se(streq(string_erase(x), "xxx"));
-
- x = strdupa("1234");
- assert_se(streq(string_erase(x), "xxxx"));
-
- x = strdupa("12345");
- assert_se(streq(string_erase(x), "xxxxx"));
-
- x = strdupa("123456");
- assert_se(streq(string_erase(x), "xxxxxx"));
-
- x = strdupa("1234567");
- assert_se(streq(string_erase(x), "xxxxxxx"));
-
- x = strdupa("12345678");
- assert_se(streq(string_erase(x), "xxxxxxxx"));
+ assert_se(streq(string_erase(x), ""));
x = strdupa("123456789");
- assert_se(streq(string_erase(x), "xxxxxxxxx"));
+ assert_se(streq(string_erase(x), ""));
+
+ assert_se(x[1] == '\0');
+ assert_se(x[2] == '\0');
+ assert_se(x[3] == '\0');
+ assert_se(x[4] == '\0');
+ assert_se(x[5] == '\0');
+ assert_se(x[6] == '\0');
+ assert_se(x[7] == '\0');
+ assert_se(x[8] == '\0');
+ assert_se(x[9] == '\0');
}
static void test_ascii_strcasecmp_n(void) {
@@ -232,21 +221,25 @@ static void test_foreach_word(void) {
}
static void check(const char *test, char** expected, bool trailing) {
- const char *word, *state;
- size_t l;
- int i = 0;
+ int i = 0, r;
printf("<<<%s>>>\n", test);
- FOREACH_WORD_QUOTED(word, l, test, state) {
- _cleanup_free_ char *t = NULL;
-
- assert_se(t = strndup(word, l));
- assert_se(strneq(expected[i++], word, l));
- printf("<%s>\n", t);
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
+
+ r = extract_first_word(&test, &word, NULL, EXTRACT_QUOTES);
+ if (r == 0) {
+ assert_se(!trailing);
+ break;
+ } else if (r < 0) {
+ assert_se(trailing);
+ break;
+ }
+
+ assert_se(streq(word, expected[i++]));
+ printf("<%s>\n", word);
}
- printf("<<<%s>>>\n", state);
assert_se(expected[i] == NULL);
- assert_se(isempty(state) == !trailing);
}
static void test_foreach_word_quoted(void) {
diff --git a/src/test/test-time.c b/src/test/test-time.c
index 7078a0374d..911282bf0c 100644
--- a/src/test/test-time.c
+++ b/src/test/test-time.c
@@ -17,9 +17,10 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include "random-util.h"
+#include "string-util.h"
#include "strv.h"
#include "time-util.h"
-#include "random-util.h"
static void test_parse_sec(void) {
usec_t u;
@@ -42,6 +43,10 @@ static void test_parse_sec(void) {
assert_se(u == 2500 * USEC_PER_MSEC);
assert_se(parse_sec(".7", &u) >= 0);
assert_se(u == 700 * USEC_PER_MSEC);
+ assert_se(parse_sec("23us", &u) >= 0);
+ assert_se(u == 23);
+ assert_se(parse_sec("23µs", &u) >= 0);
+ assert_se(u == 23);
assert_se(parse_sec("infinity", &u) >= 0);
assert_se(u == USEC_INFINITY);
assert_se(parse_sec(" infinity ", &u) >= 0);
@@ -244,6 +249,30 @@ static void test_format_timestamp(void) {
}
}
+static void test_format_timestamp_utc_one(usec_t t, const char *result) {
+ char buf[FORMAT_TIMESTAMP_MAX];
+
+ assert_se(!format_timestamp_utc(buf, sizeof(buf), t) == !result);
+
+ if (result)
+ assert_se(streq(result, buf));
+}
+
+static void test_format_timestamp_utc(void) {
+ test_format_timestamp_utc_one(0, NULL);
+ test_format_timestamp_utc_one(1, "Thu 1970-01-01 00:00:00 UTC");
+ test_format_timestamp_utc_one(USEC_PER_SEC, "Thu 1970-01-01 00:00:01 UTC");
+
+#if SIZEOF_TIME_T == 8
+ test_format_timestamp_utc_one(USEC_TIMESTAMP_FORMATTABLE_MAX, "Thu 9999-12-30 23:59:59 UTC");
+#elif SIZEOF_TIME_T == 4
+ test_format_timestamp_utc_one(USEC_TIMESTAMP_FORMATTABLE_MAX, "Tue 2038-01-19 03:14:07 UTC");
+#endif
+
+ test_format_timestamp_utc_one(USEC_TIMESTAMP_FORMATTABLE_MAX+1, NULL);
+ test_format_timestamp_utc_one(USEC_INFINITY, NULL);
+}
+
int main(int argc, char *argv[]) {
uintmax_t x;
@@ -258,6 +287,7 @@ int main(int argc, char *argv[]) {
test_usec_add();
test_usec_sub();
test_format_timestamp();
+ test_format_timestamp_utc();
/* Ensure time_t is signed */
assert_cc((time_t) -1 < (time_t) 1);
diff --git a/src/test/test-tmpfiles.c b/src/test/test-tmpfiles.c
index f35e6793b7..a7c86d155a 100644
--- a/src/test/test-tmpfiles.c
+++ b/src/test/test-tmpfiles.c
@@ -25,7 +25,7 @@
#include "alloc-util.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "fs-util.h"
#include "log.h"
#include "string-util.h"
diff --git a/src/test/test-util.c b/src/test/test-util.c
index 1b5cba86c1..f8bf0cb875 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -195,50 +195,6 @@ static void test_log2i(void) {
assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
}
-static void test_execute_directory(void) {
- char template_lo[] = "/tmp/test-readlink_and_make_absolute-lo.XXXXXXX";
- char template_hi[] = "/tmp/test-readlink_and_make_absolute-hi.XXXXXXX";
- const char * dirs[] = {template_hi, template_lo, NULL};
- const char *name, *name2, *name3, *overridden, *override, *masked, *mask;
-
- assert_se(mkdtemp(template_lo));
- assert_se(mkdtemp(template_hi));
-
- name = strjoina(template_lo, "/script");
- name2 = strjoina(template_hi, "/script2");
- name3 = strjoina(template_lo, "/useless");
- overridden = strjoina(template_lo, "/overridden");
- override = strjoina(template_hi, "/overridden");
- masked = strjoina(template_lo, "/masked");
- mask = strjoina(template_hi, "/masked");
-
- assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works", WRITE_STRING_FILE_CREATE) == 0);
- assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works2", WRITE_STRING_FILE_CREATE) == 0);
- assert_se(write_string_file(overridden, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed", WRITE_STRING_FILE_CREATE) == 0);
- assert_se(write_string_file(override, "#!/bin/sh\necho 'Executing '$0", WRITE_STRING_FILE_CREATE) == 0);
- assert_se(write_string_file(masked, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed", WRITE_STRING_FILE_CREATE) == 0);
- assert_se(symlink("/dev/null", mask) == 0);
- assert_se(chmod(name, 0755) == 0);
- assert_se(chmod(name2, 0755) == 0);
- assert_se(chmod(overridden, 0755) == 0);
- assert_se(chmod(override, 0755) == 0);
- assert_se(chmod(masked, 0755) == 0);
- assert_se(touch(name3) >= 0);
-
- execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL);
-
- assert_se(chdir(template_lo) == 0);
- assert_se(access("it_works", F_OK) >= 0);
- assert_se(access("failed", F_OK) < 0);
-
- assert_se(chdir(template_hi) == 0);
- assert_se(access("it_works2", F_OK) >= 0);
- assert_se(access("failed", F_OK) < 0);
-
- (void) rm_rf(template_lo, REMOVE_ROOT|REMOVE_PHYSICAL);
- (void) rm_rf(template_hi, REMOVE_ROOT|REMOVE_PHYSICAL);
-}
-
static void test_raw_clone(void) {
pid_t parent, pid, pid2;
@@ -359,7 +315,6 @@ int main(int argc, char *argv[]) {
test_protect_errno();
test_in_set();
test_log2i();
- test_execute_directory();
test_raw_clone();
test_physical_memory();
test_physical_memory_scale();
diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c
index 553ef67011..281b1534a3 100644
--- a/src/timedate/timedatectl.c
+++ b/src/timedate/timedatectl.c
@@ -165,6 +165,8 @@ static int show_status(sd_bus *bus, char **args, unsigned n) {
{ "RTCTimeUSec", "t", NULL, offsetof(StatusInfo, rtc_time) },
{}
};
+
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
int r;
assert(bus);
@@ -173,9 +175,10 @@ static int show_status(sd_bus *bus, char **args, unsigned n) {
"org.freedesktop.timedate1",
"/org/freedesktop/timedate1",
map,
+ &error,
&info);
if (r < 0)
- return log_error_errno(r, "Failed to query server: %m");
+ return log_error_errno(r, "Failed to query server: %s", bus_error_message(&error, r));
print_status_info(&info);
diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c
index 490929e93b..1061b094d3 100644
--- a/src/timedate/timedated.c
+++ b/src/timedate/timedated.c
@@ -413,7 +413,7 @@ static int method_set_timezone(sd_bus_message *m, void *userdata, sd_bus_error *
}
log_struct(LOG_INFO,
- LOG_MESSAGE_ID(SD_MESSAGE_TIMEZONE_CHANGE),
+ "MESSAGE_ID=" SD_MESSAGE_TIMEZONE_CHANGE_STR,
"TIMEZONE=%s", c->zone,
LOG_MESSAGE("Changed time zone to '%s'.", c->zone),
NULL);
@@ -591,7 +591,7 @@ static int method_set_time(sd_bus_message *m, void *userdata, sd_bus_error *erro
clock_set_hwclock(tm);
log_struct(LOG_INFO,
- LOG_MESSAGE_ID(SD_MESSAGE_TIME_CHANGE),
+ "MESSAGE_ID=" SD_MESSAGE_TIME_CHANGE_STR,
"REALTIME="USEC_FMT, timespec_load(&ts),
LOG_MESSAGE("Changed local time to %s", ctime(&ts.tv_sec)),
NULL);
diff --git a/src/timesync/timesyncd-conf.c b/src/timesync/timesyncd-conf.c
index bf25b112e1..b4a4f19976 100644
--- a/src/timesync/timesyncd-conf.c
+++ b/src/timesync/timesyncd-conf.c
@@ -34,6 +34,9 @@ int manager_parse_server_string(Manager *m, ServerType type, const char *string)
first = type == SERVER_FALLBACK ? m->fallback_servers : m->system_servers;
+ if (type == SERVER_FALLBACK)
+ m->have_fallbacks = true;
+
for (;;) {
_cleanup_free_ char *word = NULL;
bool found = false;
@@ -63,6 +66,13 @@ int manager_parse_server_string(Manager *m, ServerType type, const char *string)
return 0;
}
+int manager_parse_fallback_string(Manager *m, const char *string) {
+ if (m->have_fallbacks)
+ return 0;
+
+ return manager_parse_server_string(m, SERVER_FALLBACK, string);
+}
+
int config_parse_servers(
const char *unit,
const char *filename,
diff --git a/src/timesync/timesyncd-conf.h b/src/timesync/timesyncd-conf.h
index 0280697e9c..0c4b44e707 100644
--- a/src/timesync/timesyncd-conf.h
+++ b/src/timesync/timesyncd-conf.h
@@ -29,3 +29,4 @@ int manager_parse_server_string(Manager *m, ServerType type, const char *string)
int config_parse_servers(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int manager_parse_config_file(Manager *m);
+int manager_parse_fallback_string(Manager *m, const char *string);
diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
index d5e16db3a0..a24c821bdc 100644
--- a/src/timesync/timesyncd-manager.c
+++ b/src/timesync/timesyncd-manager.c
@@ -330,11 +330,13 @@ static int manager_adjust_clock(Manager *m, double offset, int leap_sec) {
tmx.esterror = 0;
log_debug(" adjust (slew): %+.3f sec", offset);
} else {
- tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_SETOFFSET;
+ tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_SETOFFSET | ADJ_MAXERROR | ADJ_ESTERROR;
/* ADJ_NANO uses nanoseconds in the microseconds field */
tmx.time.tv_sec = (long)offset;
tmx.time.tv_usec = (offset - tmx.time.tv_sec) * NSEC_PER_SEC;
+ tmx.maxerror = 0;
+ tmx.esterror = 0;
/* the kernel expects -0.3s as {-1, 7000.000.000} */
if (tmx.time.tv_usec < 0) {
@@ -376,12 +378,12 @@ static int manager_adjust_clock(Manager *m, double offset, int leap_sec) {
m->drift_ppm = tmx.freq / 65536;
log_debug(" status : %04i %s\n"
- " time now : %li.%03llu\n"
- " constant : %li\n"
+ " time now : %"PRI_TIME".%03"PRI_USEC"\n"
+ " constant : %"PRI_TIMEX"\n"
" offset : %+.3f sec\n"
- " freq offset : %+li (%i ppm)\n",
+ " freq offset : %+"PRI_TIMEX" (%i ppm)\n",
tmx.status, tmx.status & STA_UNSYNC ? "unsync" : "sync",
- tmx.time.tv_sec, (unsigned long long) (tmx.time.tv_usec / NSEC_PER_MSEC),
+ tmx.time.tv_sec, tmx.time.tv_usec / NSEC_PER_MSEC,
tmx.constant,
(double)tmx.offset / NSEC_PER_SEC,
tmx.freq, m->drift_ppm);
@@ -1122,10 +1124,6 @@ int manager_new(Manager **ret) {
RATELIMIT_INIT(m->ratelimit, RATELIMIT_INTERVAL_USEC, RATELIMIT_BURST);
- r = manager_parse_server_string(m, SERVER_FALLBACK, NTP_SERVERS);
- if (r < 0)
- return r;
-
r = sd_event_default(&m->event);
if (r < 0)
return r;
diff --git a/src/timesync/timesyncd-manager.h b/src/timesync/timesyncd-manager.h
index efe3e60d3e..cf681f6098 100644
--- a/src/timesync/timesyncd-manager.h
+++ b/src/timesync/timesyncd-manager.h
@@ -38,6 +38,8 @@ struct Manager {
LIST_HEAD(ServerName, link_servers);
LIST_HEAD(ServerName, fallback_servers);
+ bool have_fallbacks:1;
+
RateLimit ratelimit;
bool exhausted_servers;
diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c
index b67d672a6a..ff90f04070 100644
--- a/src/timesync/timesyncd.c
+++ b/src/timesync/timesyncd.c
@@ -132,6 +132,12 @@ int main(int argc, char *argv[]) {
if (r < 0)
log_warning_errno(r, "Failed to parse configuration file: %m");
+ r = manager_parse_fallback_string(m, NTP_SERVERS);
+ if (r < 0) {
+ log_error_errno(r, "Failed to parse fallback server strings: %m");
+ goto finish;
+ }
+
log_debug("systemd-timesyncd running as pid " PID_FMT, getpid());
sd_notify(false,
"READY=1\n"
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index 954f4aa985..ed6a9adaa6 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -18,7 +18,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <fnmatch.h>
@@ -44,10 +43,11 @@
#include "conf-files.h"
#include "copy.h"
#include "def.h"
+#include "dirent-util.h"
#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "fs-util.h"
#include "glob-util.h"
#include "io-util.h"
@@ -380,12 +380,12 @@ static int dir_cleanup(
bool deleted = false;
int r = 0;
- while ((dent = readdir(d))) {
+ FOREACH_DIRENT_ALL(dent, d, break) {
struct stat s;
usec_t age;
_cleanup_free_ char *sub_path = NULL;
- if (STR_IN_SET(dent->d_name, ".", ".."))
+ if (dot_or_dot_dot(dent->d_name))
continue;
if (fstatat(dirfd(d), dent->d_name, &s, AT_SYMLINK_NOFOLLOW) < 0) {
@@ -422,7 +422,7 @@ static int dir_cleanup(
continue;
}
- sub_path = strjoin(p, "/", dent->d_name, NULL);
+ sub_path = strjoin(p, "/", dent->d_name);
if (!sub_path) {
r = log_oom();
goto finish;
@@ -649,7 +649,7 @@ static int path_set_perms(Item *i, const char *path) {
else {
log_debug("chmod \"%s\" to mode %o", path, m);
if (chmod(fn, m) < 0)
- return log_error_errno(errno, "chmod(%s) failed: %m", path);
+ return log_error_errno(errno, "chmod() of %s via %s failed: %m", path, fn);
}
}
@@ -662,7 +662,7 @@ static int path_set_perms(Item *i, const char *path) {
if (chown(fn,
i->uid_set ? i->uid : UID_INVALID,
i->gid_set ? i->gid : GID_INVALID) < 0)
- return log_error_errno(errno, "chown(%s) failed: %m", path);
+ return log_error_errno(errno, "chown() of %s via %s failed: %m", path, fn);
}
}
@@ -872,7 +872,7 @@ static int parse_attribute_from_arg(Item *item) {
{ 's', FS_SECRM_FL }, /* Secure deletion */
{ 'u', FS_UNRM_FL }, /* Undelete */
{ 't', FS_NOTAIL_FL }, /* file tail should not be merged */
- { 'T', FS_TOPDIR_FL }, /* Top of directory hierarchies*/
+ { 'T', FS_TOPDIR_FL }, /* Top of directory hierarchies */
{ 'C', FS_NOCOW_FL }, /* Do not cow file */
};
@@ -973,7 +973,7 @@ static int path_set_attribute(Item *item, const char *path) {
r = chattr_fd(fd, f, item->attribute_mask);
if (r < 0)
- log_full_errno(r == -ENOTTY ? LOG_DEBUG : LOG_WARNING,
+ log_full_errno(r == -ENOTTY || r == -EOPNOTSUPP ? LOG_DEBUG : LOG_WARNING,
r,
"Cannot set file attribute for '%s', value=0x%08x, mask=0x%08x: %m",
path, item->attribute_value, item->attribute_mask);
@@ -1053,6 +1053,7 @@ typedef int (*action_t)(Item *, const char *);
static int item_do_children(Item *i, const char *path, action_t action) {
_cleanup_closedir_ DIR *d;
+ struct dirent *de;
int r = 0;
assert(i);
@@ -1065,24 +1066,14 @@ static int item_do_children(Item *i, const char *path, action_t action) {
if (!d)
return errno == ENOENT || errno == ENOTDIR ? 0 : -errno;
- for (;;) {
+ FOREACH_DIRENT_ALL(de, d, r = -errno) {
_cleanup_free_ char *p = NULL;
- struct dirent *de;
int q;
- errno = 0;
- de = readdir(d);
- if (!de) {
- if (errno > 0 && r == 0)
- r = -errno;
-
- break;
- }
-
- if (STR_IN_SET(de->d_name, ".", ".."))
+ if (dot_or_dot_dot(de->d_name))
continue;
- p = strjoin(path, "/", de->d_name, NULL);
+ p = strjoin(path, "/", de->d_name);
if (!p)
return -ENOMEM;
@@ -1179,7 +1170,7 @@ static int create_item(Item *i) {
return log_error_errno(r, "Failed to substitute specifiers in copy source %s: %m", i->argument);
log_debug("Copying tree \"%s\" to \"%s\".", resolved, i->path);
- r = copy_tree(resolved, i->path, false);
+ r = copy_tree(resolved, i->path, i->uid_set ? i->uid : UID_INVALID, i->gid_set ? i->gid : GID_INVALID, COPY_REFLINK);
if (r == -EROFS && stat(i->path, &st) == 0)
r = -EEXIST;
diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c
index b45490be1a..a17c006d57 100644
--- a/src/tty-ask-password-agent/tty-ask-password-agent.c
+++ b/src/tty-ask-password-agent/tty-ask-password-agent.c
@@ -243,7 +243,7 @@ static int ask_password_plymouth(
r = 0;
finish:
- memory_erase(buffer, sizeof(buffer));
+ explicit_bzero(buffer, sizeof(buffer));
return r;
}
@@ -283,7 +283,7 @@ static int send_passwords(const char *socket_name, char **passwords) {
r = log_debug_errno(errno, "sendto(): %m");
finish:
- memory_erase(packet, packet_length);
+ explicit_bzero(packet, packet_length);
return r;
}
diff --git a/src/udev/net/ethtool-util.c b/src/udev/net/ethtool-util.c
index 708a665576..d7edbb396b 100644
--- a/src/udev/net/ethtool-util.c
+++ b/src/udev/net/ethtool-util.c
@@ -29,6 +29,7 @@
#include "string-table.h"
#include "strxcpyx.h"
#include "util.h"
+#include "missing.h"
static const char* const duplex_table[_DUP_MAX] = {
[DUP_FULL] = "full",
@@ -323,3 +324,211 @@ int ethtool_set_features(int *fd, const char *ifname, NetDevFeature *features) {
return 0;
}
+
+static int get_glinksettings(int *fd, struct ifreq *ifr, struct ethtool_link_usettings **g) {
+ struct ecmd {
+ struct ethtool_link_settings req;
+ __u32 link_mode_data[3 * ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32];
+ } ecmd = {
+ .req.cmd = ETHTOOL_GLINKSETTINGS,
+ };
+ struct ethtool_link_usettings *u;
+ unsigned offset;
+ int r;
+
+ /* The interaction user/kernel via the new API requires a small ETHTOOL_GLINKSETTINGS
+ handshake first to agree on the length of the link mode bitmaps. If kernel doesn't
+ agree with user, it returns the bitmap length it is expecting from user as a negative
+ length (and cmd field is 0). When kernel and user agree, kernel returns valid info in
+ all fields (ie. link mode length > 0 and cmd is ETHTOOL_GLINKSETTINGS). Based on
+ https://github.com/torvalds/linux/commit/3f1ac7a700d039c61d8d8b99f28d605d489a60cf
+ */
+
+ ifr->ifr_data = (void *) &ecmd;
+
+ r = ioctl(*fd, SIOCETHTOOL, ifr);
+ if (r < 0)
+ return -errno;
+
+ if (ecmd.req.link_mode_masks_nwords >= 0 || ecmd.req.cmd != ETHTOOL_GLINKSETTINGS)
+ return -ENOTSUP;
+
+ ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords;
+
+ ifr->ifr_data = (void *) &ecmd;
+
+ r = ioctl(*fd, SIOCETHTOOL, ifr);
+ if (r < 0)
+ return -errno;
+
+ if (ecmd.req.link_mode_masks_nwords <= 0 || ecmd.req.cmd != ETHTOOL_GLINKSETTINGS)
+ return -ENOTSUP;
+
+ u = new0(struct ethtool_link_usettings , 1);
+ if (!u)
+ return -ENOMEM;
+
+ memcpy(&u->base, &ecmd.req, sizeof(struct ethtool_link_settings));
+
+ offset = 0;
+ memcpy(u->link_modes.supported, &ecmd.link_mode_data[offset], 4 * ecmd.req.link_mode_masks_nwords);
+
+ offset += ecmd.req.link_mode_masks_nwords;
+ memcpy(u->link_modes.advertising, &ecmd.link_mode_data[offset], 4 * ecmd.req.link_mode_masks_nwords);
+
+ offset += ecmd.req.link_mode_masks_nwords;
+ memcpy(u->link_modes.lp_advertising, &ecmd.link_mode_data[offset], 4 * ecmd.req.link_mode_masks_nwords);
+
+ *g = u;
+
+ return 0;
+}
+
+static int get_gset(int *fd, struct ifreq *ifr, struct ethtool_link_usettings **u) {
+ struct ethtool_link_usettings *e;
+ struct ethtool_cmd ecmd = {
+ .cmd = ETHTOOL_GSET,
+ };
+ int r;
+
+ ifr->ifr_data = (void *) &ecmd;
+
+ r = ioctl(*fd, SIOCETHTOOL, ifr);
+ if (r < 0)
+ return -errno;
+
+ e = new0(struct ethtool_link_usettings, 1);
+ if (!e)
+ return -ENOMEM;
+
+ e->base.cmd = ETHTOOL_GSET;
+
+ e->base.link_mode_masks_nwords = 1;
+ e->base.speed = ethtool_cmd_speed(&ecmd);
+ e->base.duplex = ecmd.duplex;
+ e->base.port = ecmd.port;
+ e->base.phy_address = ecmd.phy_address;
+ e->base.autoneg = ecmd.autoneg;
+ e->base.mdio_support = ecmd.mdio_support;
+
+ e->link_modes.supported[0] = ecmd.supported;
+ e->link_modes.advertising[0] = ecmd.advertising;
+ e->link_modes.lp_advertising[0] = ecmd.lp_advertising;
+
+ *u = e;
+
+ return 0;
+}
+
+static int set_slinksettings(int *fd, struct ifreq *ifr, const struct ethtool_link_usettings *u) {
+ struct {
+ struct ethtool_link_settings req;
+ __u32 link_mode_data[3 * ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32];
+ } ecmd = {
+ .req.cmd = ETHTOOL_SLINKSETTINGS,
+ };
+ unsigned int offset;
+ int r;
+
+ if (u->base.cmd != ETHTOOL_GLINKSETTINGS || u->base.link_mode_masks_nwords <= 0)
+ return -EINVAL;
+
+ offset = 0;
+ memcpy(&ecmd.link_mode_data[offset], u->link_modes.supported, 4 * ecmd.req.link_mode_masks_nwords);
+
+ offset += ecmd.req.link_mode_masks_nwords;
+ memcpy(&ecmd.link_mode_data[offset], u->link_modes.advertising, 4 * ecmd.req.link_mode_masks_nwords);
+
+ offset += ecmd.req.link_mode_masks_nwords;
+ memcpy(&ecmd.link_mode_data[offset], u->link_modes.lp_advertising, 4 * ecmd.req.link_mode_masks_nwords);
+
+ ifr->ifr_data = (void *) &ecmd;
+
+ r = ioctl(*fd, SIOCETHTOOL, ifr);
+ if (r < 0)
+ return -errno;
+
+ return 0;
+}
+
+static int set_sset(int *fd, struct ifreq *ifr, const struct ethtool_link_usettings *u) {
+ struct ethtool_cmd ecmd = {
+ .cmd = ETHTOOL_SSET,
+ };
+ int r;
+
+ if (u->base.cmd != ETHTOOL_GSET || u->base.link_mode_masks_nwords <= 0)
+ return -EINVAL;
+
+ ecmd.supported = u->link_modes.supported[0];
+ ecmd.advertising = u->link_modes.advertising[0];
+ ecmd.lp_advertising = u->link_modes.lp_advertising[0];
+
+ ethtool_cmd_speed_set(&ecmd, u->base.speed);
+
+ ecmd.duplex = u->base.duplex;
+ ecmd.port = u->base.port;
+ ecmd.phy_address = u->base.phy_address;
+ ecmd.autoneg = u->base.autoneg;
+ ecmd.mdio_support = u->base.mdio_support;
+
+ ifr->ifr_data = (void *) &ecmd;
+
+ r = ioctl(*fd, SIOCETHTOOL, ifr);
+ if (r < 0)
+ return -errno;
+
+ return 0;
+}
+
+/* If autonegotiation is disabled, the speed and duplex represent the fixed link
+ * mode and are writable if the driver supports multiple link modes. If it is
+ * enabled then they are read-only. If the link is up they represent the negotiated
+ * link mode; if the link is down, the speed is 0, %SPEED_UNKNOWN or the highest
+ * enabled speed and @duplex is %DUPLEX_UNKNOWN or the best enabled duplex mode.
+ */
+
+int ethtool_set_glinksettings(int *fd, const char *ifname, unsigned int speed, Duplex duplex, int autonegotiation) {
+ _cleanup_free_ struct ethtool_link_usettings *u = NULL;
+ struct ifreq ifr = {};
+ int r;
+
+ if (autonegotiation != 0) {
+ log_info("link_config: autonegotiation is unset or enabled, the speed and duplex are not writable.");
+ return 0;
+ }
+
+ if (*fd < 0) {
+ r = ethtool_connect(fd);
+ if (r < 0)
+ return log_warning_errno(r, "link_config: could not connect to ethtool: %m");
+ }
+
+ strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
+
+ r = get_glinksettings(fd, &ifr, &u);
+ if (r < 0) {
+
+ r = get_gset(fd, &ifr, &u);
+ if (r < 0)
+ return log_warning_errno(r, "link_config: Cannot get device settings for %s : %m", ifname);
+ }
+
+ if (speed)
+ u->base.speed = speed;
+
+ if (duplex != _DUP_INVALID)
+ u->base.duplex = duplex;
+
+ u->base.autoneg = autonegotiation;
+
+ if (u->base.cmd == ETHTOOL_GLINKSETTINGS)
+ r = set_slinksettings(fd, &ifr, u);
+ else
+ r = set_sset(fd, &ifr, u);
+
+ if (r < 0)
+ return log_warning_errno(r, "link_config: Cannot set device settings for %s : %m", ifname);
+
+ return r;
+}
diff --git a/src/udev/net/ethtool-util.h b/src/udev/net/ethtool-util.h
index 0744164653..75d6af396b 100644
--- a/src/udev/net/ethtool-util.h
+++ b/src/udev/net/ethtool-util.h
@@ -20,6 +20,9 @@
***/
#include <macro.h>
+#include <linux/ethtool.h>
+
+#include "missing.h"
/* we can't use DUPLEX_ prefix, as it
* clashes with <linux/ethtool.h> */
@@ -48,12 +51,27 @@ typedef enum NetDevFeature {
_NET_DEV_FEAT_INVALID = -1
} NetDevFeature;
+
+#define ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32 (SCHAR_MAX)
+
+/* layout of the struct passed from/to userland */
+struct ethtool_link_usettings {
+ struct ethtool_link_settings base;
+
+ struct {
+ uint32_t supported[ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32];
+ uint32_t advertising[ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32];
+ uint32_t lp_advertising[ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32];
+ } link_modes;
+};
+
int ethtool_connect(int *ret);
int ethtool_get_driver(int *fd, const char *ifname, char **ret);
int ethtool_set_speed(int *fd, const char *ifname, unsigned int speed, Duplex duplex);
int ethtool_set_wol(int *fd, const char *ifname, WakeOnLan wol);
int ethtool_set_features(int *fd, const char *ifname, NetDevFeature *features);
+int ethtool_set_glinksettings(int *fd, const char *ifname, unsigned int speed, Duplex duplex, int autoneg);
const char *duplex_to_string(Duplex d) _const_;
Duplex duplex_from_string(const char *d) _pure_;
diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf
index f8b85cbd13..78e551df22 100644
--- a/src/udev/net/link-config-gperf.gperf
+++ b/src/udev/net/link-config-gperf.gperf
@@ -34,6 +34,7 @@ Link.Alias, config_parse_ifalias, 0,
Link.MTUBytes, config_parse_iec_size, 0, offsetof(link_config, mtu)
Link.BitsPerSecond, config_parse_si_size, 0, offsetof(link_config, speed)
Link.Duplex, config_parse_duplex, 0, offsetof(link_config, duplex)
+Link.AutoNegotiation, config_parse_tristate, 0, offsetof(link_config, autonegotiation)
Link.WakeOnLan, config_parse_wol, 0, offsetof(link_config, wol)
Link.GenericSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_GSO])
Link.TCPSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_TSO])
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index ece9248c2a..3af87f1388 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -167,8 +167,9 @@ static int load_link(link_config_ctx *ctx, const char *filename) {
link->mac_policy = _MACPOLICY_INVALID;
link->wol = _WOL_INVALID;
link->duplex = _DUP_INVALID;
+ link->autonegotiation = -1;
- memset(&link->features, -1, _NET_DEV_FEAT_MAX);
+ memset(&link->features, -1, sizeof(link->features));
r = config_parse(NULL, filename, file,
"Match\0Link\0Ethernet\0",
@@ -191,20 +192,15 @@ static int load_link(link_config_ctx *ctx, const char *filename) {
}
static bool enable_name_policy(void) {
- _cleanup_free_ char *value = NULL;
- int r;
-
- r = get_proc_cmdline_key("net.ifnames=", &value);
- if (r > 0 && streq(value, "0"))
- return false;
+ bool b;
- return true;
+ return proc_cmdline_get_bool("net.ifnames", &b) <= 0 || b;
}
int link_config_load(link_config_ctx *ctx) {
- int r;
_cleanup_strv_free_ char **files;
char **f;
+ int r;
link_configs_free(ctx);
@@ -364,11 +360,12 @@ static int get_mac(struct udev_device *device, bool want_random,
int link_config_apply(link_config_ctx *ctx, link_config *config,
struct udev_device *device, const char **name) {
- const char *old_name;
- const char *new_name = NULL;
+ bool respect_predictable = false;
struct ether_addr generated_mac;
struct ether_addr *mac = NULL;
- bool respect_predictable = false;
+ const char *new_name = NULL;
+ const char *old_name;
+ unsigned speed;
int r, ifindex;
assert(ctx);
@@ -380,11 +377,19 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
if (!old_name)
return -EINVAL;
- r = ethtool_set_speed(&ctx->ethtool_fd, old_name, config->speed / 1024, config->duplex);
- if (r < 0)
- log_warning_errno(r, "Could not set speed or duplex of %s to %zu Mbps (%s): %m",
- old_name, config->speed / 1024,
- duplex_to_string(config->duplex));
+
+ speed = DIV_ROUND_UP(config->speed, 1000000);
+
+ r = ethtool_set_glinksettings(&ctx->ethtool_fd, old_name, speed, config->duplex, config->autonegotiation);
+ if (r < 0) {
+
+ if (r == -EOPNOTSUPP)
+ r = ethtool_set_speed(&ctx->ethtool_fd, old_name, speed, config->duplex);
+
+ if (r < 0)
+ log_warning_errno(r, "Could not set speed or duplex of %s to %u Mbps (%s): %m",
+ old_name, speed, duplex_to_string(config->duplex));
+ }
r = ethtool_set_wol(&ctx->ethtool_fd, old_name, config->wol);
if (r < 0)
diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h
index b0d8ceb76a..5a25cec6fd 100644
--- a/src/udev/net/link-config.h
+++ b/src/udev/net/link-config.h
@@ -69,6 +69,7 @@ struct link_config {
size_t mtu;
size_t speed;
Duplex duplex;
+ int autonegotiation;
WakeOnLan wol;
NetDevFeature features[_NET_DEV_FEAT_MAX];
diff --git a/src/udev/udev-builtin-blkid.c b/src/udev/udev-builtin-blkid.c
index 3c58445836..9037aa1304 100644
--- a/src/udev/udev-builtin-blkid.c
+++ b/src/udev/udev-builtin-blkid.c
@@ -122,7 +122,7 @@ static int find_gpt_root(struct udev_device *dev, blkid_probe pr, bool test) {
errno = 0;
pl = blkid_probe_get_partitions(pr);
if (!pl)
- return errno > 0 ? -errno : -ENOMEM;
+ return -errno ?: -ENOMEM;
nvals = blkid_partlist_numof_partitions(pl);
for (i = 0; i < nvals; i++) {
@@ -193,7 +193,7 @@ static int probe_superblocks(blkid_probe pr) {
int rc;
if (fstat(blkid_probe_get_fd(pr), &st))
- return -1;
+ return -errno;
blkid_probe_enable_partitions(pr, 1);
diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c
index f4a065a97d..acd1d1a6de 100644
--- a/src/udev/udev-builtin-hwdb.c
+++ b/src/udev/udev-builtin-hwdb.c
@@ -43,7 +43,7 @@ int udev_builtin_hwdb_lookup(struct udev_device *dev,
return -ENOENT;
if (prefix) {
- lookup = strjoin(prefix, modalias, NULL);
+ lookup = strjoin(prefix, modalias);
if (!lookup)
return -ENOMEM;
modalias = lookup;
diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c
index 59b9804dc4..51f364bf94 100644
--- a/src/udev/udev-builtin-input_id.c
+++ b/src/udev/udev-builtin-input_id.c
@@ -323,6 +323,9 @@ static int builtin_input_id(struct udev_device *dev, int argc, char *argv[], boo
if (!is_pointer && !is_key && test_bit(EV_REL, bitmask_ev) &&
(test_bit(REL_WHEEL, bitmask_rel) || test_bit(REL_HWHEEL, bitmask_rel)))
udev_builtin_add_property(dev, test, "ID_INPUT_KEY", "1");
+ if (test_bit(EV_SW, bitmask_ev))
+ udev_builtin_add_property(dev, test, "ID_INPUT_SWITCH", "1");
+
}
devnode = udev_device_get_devnode(dev);
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
index fe9d6f4482..bd7b789cad 100644
--- a/src/udev/udev-builtin-net_id.c
+++ b/src/udev/udev-builtin-net_id.c
@@ -34,7 +34,8 @@
*
* Type of names:
* b<number> — BCMA bus core number
- * c<bus_id> — CCW bus group name, without leading zeros [s390]
+ * c<bus_id> — bus id of a grouped CCW or CCW device,
+ * with all leading zeros stripped [s390]
* o<index>[n<phys_port_name>|d<dev_port>]
* — on-board device index number
* s<slot>[f<function>][n<phys_port_name>|d<dev_port>]
@@ -87,6 +88,11 @@
* /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/net/enp0s29u1u2
* ID_NET_NAME_MAC=enxd626b3450fb5
* ID_NET_NAME_PATH=enp0s29u1u2
+ *
+ * s390 grouped CCW interface:
+ * /sys/devices/css0/0.0.0007/0.0.f5f0/group_device/net/encf5f0
+ * ID_NET_NAME_MAC=enx026d3c00000a
+ * ID_NET_NAME_PATH=encf5f0
*/
#include <errno.h>
@@ -100,6 +106,7 @@
#include <unistd.h>
#include <linux/pci_regs.h>
+#include "dirent-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "stdio-util.h"
@@ -114,7 +121,7 @@ enum netname_type{
NET_USB,
NET_BCMA,
NET_VIRTIO,
- NET_CCWGROUP,
+ NET_CCW,
};
struct netnames {
@@ -131,9 +138,21 @@ struct netnames {
char usb_ports[IFNAMSIZ];
char bcma_core[IFNAMSIZ];
- char ccw_group[IFNAMSIZ];
+ char ccw_busid[IFNAMSIZ];
};
+/* skip intermediate virtio devices */
+static struct udev_device *skip_virtio(struct udev_device *dev) {
+ struct udev_device *parent = dev;
+
+ /* there can only ever be one virtio bus per parent device, so we can
+ safely ignore any virtio buses. see
+ <http://lists.linuxfoundation.org/pipermail/virtualization/2015-August/030331.html> */
+ while (parent && streq_ptr("virtio", udev_device_get_subsystem(parent)))
+ parent = udev_device_get_parent(parent);
+ return parent;
+}
+
/* retrieve on-board index number and label from firmware */
static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) {
unsigned dev_port = 0;
@@ -256,7 +275,7 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
goto out;
}
- for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
+ FOREACH_DIRENT_ALL(dent, dir, break) {
int i;
char *rest, *address, str[PATH_MAX];
@@ -307,12 +326,8 @@ static int names_pci(struct udev_device *dev, struct netnames *names) {
assert(names);
parent = udev_device_get_parent(dev);
-
- /* there can only ever be one virtio bus per parent device, so we can
- safely ignore any virtio buses. see
- <http://lists.linuxfoundation.org/pipermail/virtualization/2015-August/030331.html> */
- while (parent && streq_ptr("virtio", udev_device_get_subsystem(parent)))
- parent = udev_device_get_parent(parent);
+ /* skip virtio subsystem if present */
+ parent = skip_virtio(parent);
if (!parent)
return -ENOENT;
@@ -411,8 +426,9 @@ static int names_bcma(struct udev_device *dev, struct netnames *names) {
static int names_ccw(struct udev_device *dev, struct netnames *names) {
struct udev_device *cdev;
- const char *bus_id;
+ const char *bus_id, *subsys;
size_t bus_id_len;
+ size_t bus_id_start;
int rc;
assert(dev);
@@ -420,14 +436,17 @@ static int names_ccw(struct udev_device *dev, struct netnames *names) {
/* Retrieve the associated CCW device */
cdev = udev_device_get_parent(dev);
+ /* skip virtio subsystem if present */
+ cdev = skip_virtio(cdev);
if (!cdev)
return -ENOENT;
- /* Network devices are always grouped CCW devices */
- if (!streq_ptr("ccwgroup", udev_device_get_subsystem(cdev)))
+ /* Network devices are either single or grouped CCW devices */
+ subsys = udev_device_get_subsystem(cdev);
+ if (!STRPTR_IN_SET(subsys, "ccwgroup", "ccw"))
return -ENOENT;
- /* Retrieve bus-ID of the grouped CCW device. The bus-ID uniquely
+ /* Retrieve bus-ID of the CCW device. The bus-ID uniquely
* identifies the network device on the Linux on System z channel
* subsystem. Note that the bus-ID contains lowercase characters.
*/
@@ -446,14 +465,15 @@ static int names_ccw(struct udev_device *dev, struct netnames *names) {
/* Strip leading zeros from the bus id for aesthetic purposes. This
* keeps the ccw names stable, yet much shorter in general case of
* bus_id 0.0.0600 -> 600. This is similar to e.g. how PCI domain is
- * not prepended when it is zero.
+ * not prepended when it is zero. Preserve the last 0 for 0.0.0000.
*/
- bus_id += strspn(bus_id, ".0");
+ bus_id_start = strspn(bus_id, ".0");
+ bus_id += bus_id_start < bus_id_len ? bus_id_start : bus_id_len - 1;
/* Store the CCW bus-ID for use as network device name */
- rc = snprintf(names->ccw_group, sizeof(names->ccw_group), "c%s", bus_id);
- if (rc >= 0 && rc < (int)sizeof(names->ccw_group))
- names->type = NET_CCWGROUP;
+ rc = snprintf(names->ccw_busid, sizeof(names->ccw_busid), "c%s", bus_id);
+ if (rc >= 0 && rc < (int)sizeof(names->ccw_busid))
+ names->type = NET_CCW;
return 0;
}
@@ -563,10 +583,10 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
/* get path names for Linux on System z network devices */
err = names_ccw(dev, &names);
- if (err >= 0 && names.type == NET_CCWGROUP) {
+ if (err >= 0 && names.type == NET_CCW) {
char str[IFNAMSIZ];
- if (snprintf(str, sizeof(str), "%s%s", prefix, names.ccw_group) < (int)sizeof(str))
+ if (snprintf(str, sizeof(str), "%s%s", prefix, names.ccw_busid) < (int)sizeof(str))
udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
goto out;
}
diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c
index 1825ee75a7..8cb330dba1 100644
--- a/src/udev/udev-builtin-path_id.c
+++ b/src/udev/udev-builtin-path_id.c
@@ -20,7 +20,6 @@
*/
#include <ctype.h>
-#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
@@ -31,6 +30,7 @@
#include <unistd.h>
#include "alloc-util.h"
+#include "dirent-util.h"
#include "string-util.h"
#include "udev.h"
@@ -405,7 +405,7 @@ static struct udev_device *handle_scsi_default(struct udev_device *parent, char
parent = NULL;
goto out;
}
- for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
+ FOREACH_DIRENT_ALL(dent, dir, break) {
char *rest;
int i;
@@ -664,11 +664,8 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool
parent = skip_subsystem(parent, "xen");
supported_parent = true;
} else if (streq(subsys, "virtio")) {
- while (parent && streq_ptr("virtio", udev_device_get_subsystem(parent)))
- parent = udev_device_get_parent(parent);
- path_prepend(&path, "virtio-pci-%s", udev_device_get_sysname(parent));
+ parent = skip_subsystem(parent, "virtio");
supported_transport = true;
- supported_parent = true;
} else if (streq(subsys, "scm")) {
path_prepend(&path, "scm-%s", udev_device_get_sysname(parent));
parent = skip_subsystem(parent, "scm");
diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c
index 7717ac7924..dbefbbe175 100644
--- a/src/udev/udev-ctrl.c
+++ b/src/udev/udev-ctrl.c
@@ -20,7 +20,7 @@
#include "alloc-util.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "socket-util.h"
#include "udev.h"
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
index 54cd741bb1..3f9c3ed0cf 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -32,7 +32,7 @@
#include "alloc-util.h"
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "netlink-util.h"
#include "process-util.h"
#include "signal-util.h"
@@ -73,27 +73,219 @@ void udev_event_unref(struct udev_event *event) {
free(event);
}
-size_t udev_event_apply_format(struct udev_event *event, const char *src, char *dest, size_t size) {
+enum subst_type {
+ SUBST_UNKNOWN,
+ SUBST_DEVNODE,
+ SUBST_ATTR,
+ SUBST_ENV,
+ SUBST_KERNEL,
+ SUBST_KERNEL_NUMBER,
+ SUBST_DRIVER,
+ SUBST_DEVPATH,
+ SUBST_ID,
+ SUBST_MAJOR,
+ SUBST_MINOR,
+ SUBST_RESULT,
+ SUBST_PARENT,
+ SUBST_NAME,
+ SUBST_LINKS,
+ SUBST_ROOT,
+ SUBST_SYS,
+};
+
+static size_t subst_format_var(struct udev_event *event, struct udev_device *dev,
+ enum subst_type type, char *attr,
+ char *dest, size_t l) {
+ char *s = dest;
+
+ switch (type) {
+ case SUBST_DEVPATH:
+ l = strpcpy(&s, l, udev_device_get_devpath(dev));
+ break;
+ case SUBST_KERNEL:
+ l = strpcpy(&s, l, udev_device_get_sysname(dev));
+ break;
+ case SUBST_KERNEL_NUMBER:
+ if (udev_device_get_sysnum(dev) == NULL)
+ break;
+ l = strpcpy(&s, l, udev_device_get_sysnum(dev));
+ break;
+ case SUBST_ID:
+ if (event->dev_parent == NULL)
+ break;
+ l = strpcpy(&s, l, udev_device_get_sysname(event->dev_parent));
+ break;
+ case SUBST_DRIVER: {
+ const char *driver;
+
+ if (event->dev_parent == NULL)
+ break;
+
+ driver = udev_device_get_driver(event->dev_parent);
+ if (driver == NULL)
+ break;
+ l = strpcpy(&s, l, driver);
+ break;
+ }
+ case SUBST_MAJOR: {
+ char num[UTIL_PATH_SIZE];
+
+ sprintf(num, "%u", major(udev_device_get_devnum(dev)));
+ l = strpcpy(&s, l, num);
+ break;
+ }
+ case SUBST_MINOR: {
+ char num[UTIL_PATH_SIZE];
+
+ sprintf(num, "%u", minor(udev_device_get_devnum(dev)));
+ l = strpcpy(&s, l, num);
+ break;
+ }
+ case SUBST_RESULT: {
+ char *rest;
+ int i;
+
+ if (event->program_result == NULL)
+ break;
+ /* get part of the result string */
+ i = 0;
+ if (attr != NULL)
+ i = strtoul(attr, &rest, 10);
+ if (i > 0) {
+ char result[UTIL_PATH_SIZE];
+ char tmp[UTIL_PATH_SIZE];
+ char *cpos;
+
+ strscpy(result, sizeof(result), event->program_result);
+ cpos = result;
+ while (--i) {
+ while (cpos[0] != '\0' && !isspace(cpos[0]))
+ cpos++;
+ while (isspace(cpos[0]))
+ cpos++;
+ if (cpos[0] == '\0')
+ break;
+ }
+ if (i > 0) {
+ log_error("requested part of result string not found");
+ break;
+ }
+ strscpy(tmp, sizeof(tmp), cpos);
+ /* %{2+}c copies the whole string from the second part on */
+ if (rest[0] != '+') {
+ cpos = strchr(tmp, ' ');
+ if (cpos)
+ cpos[0] = '\0';
+ }
+ l = strpcpy(&s, l, tmp);
+ } else {
+ l = strpcpy(&s, l, event->program_result);
+ }
+ break;
+ }
+ case SUBST_ATTR: {
+ const char *value = NULL;
+ char vbuf[UTIL_NAME_SIZE];
+ size_t len;
+ int count;
+
+ if (attr == NULL) {
+ log_error("missing file parameter for attr");
+ break;
+ }
+
+ /* try to read the value specified by "[dmi/id]product_name" */
+ if (util_resolve_subsys_kernel(event->udev, attr, vbuf, sizeof(vbuf), 1) == 0)
+ value = vbuf;
+
+ /* try to read the attribute the device */
+ if (value == NULL)
+ value = udev_device_get_sysattr_value(event->dev, attr);
+
+ /* try to read the attribute of the parent device, other matches have selected */
+ if (value == NULL && event->dev_parent != NULL && event->dev_parent != event->dev)
+ value = udev_device_get_sysattr_value(event->dev_parent, attr);
+
+ if (value == NULL)
+ break;
+
+ /* strip trailing whitespace, and replace unwanted characters */
+ if (value != vbuf)
+ strscpy(vbuf, sizeof(vbuf), value);
+ len = strlen(vbuf);
+ while (len > 0 && isspace(vbuf[--len]))
+ vbuf[len] = '\0';
+ count = util_replace_chars(vbuf, UDEV_ALLOWED_CHARS_INPUT);
+ if (count > 0)
+ log_debug("%i character(s) replaced" , count);
+ l = strpcpy(&s, l, vbuf);
+ break;
+ }
+ case SUBST_PARENT: {
+ struct udev_device *dev_parent;
+ const char *devnode;
+
+ dev_parent = udev_device_get_parent(event->dev);
+ if (dev_parent == NULL)
+ break;
+ devnode = udev_device_get_devnode(dev_parent);
+ if (devnode != NULL)
+ l = strpcpy(&s, l, devnode + strlen("/dev/"));
+ break;
+ }
+ case SUBST_DEVNODE:
+ if (udev_device_get_devnode(dev) != NULL)
+ l = strpcpy(&s, l, udev_device_get_devnode(dev));
+ break;
+ case SUBST_NAME:
+ if (event->name != NULL)
+ l = strpcpy(&s, l, event->name);
+ else if (udev_device_get_devnode(dev) != NULL)
+ l = strpcpy(&s, l, udev_device_get_devnode(dev) + strlen("/dev/"));
+ else
+ l = strpcpy(&s, l, udev_device_get_sysname(dev));
+ break;
+ case SUBST_LINKS: {
+ struct udev_list_entry *list_entry;
+
+ list_entry = udev_device_get_devlinks_list_entry(dev);
+ if (list_entry == NULL)
+ break;
+ l = strpcpy(&s, l, udev_list_entry_get_name(list_entry) + strlen("/dev/"));
+ udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry))
+ l = strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry) + strlen("/dev/"), NULL);
+ break;
+ }
+ case SUBST_ROOT:
+ l = strpcpy(&s, l, "/dev");
+ break;
+ case SUBST_SYS:
+ l = strpcpy(&s, l, "/sys");
+ break;
+ case SUBST_ENV:
+ if (attr == NULL) {
+ break;
+ } else {
+ const char *value;
+
+ value = udev_device_get_property_value(event->dev, attr);
+ if (value == NULL)
+ break;
+ l = strpcpy(&s, l, value);
+ break;
+ }
+ default:
+ log_error("unknown substitution type=%i", type);
+ break;
+ }
+
+ return s - dest;
+}
+
+size_t udev_event_apply_format(struct udev_event *event,
+ const char *src, char *dest, size_t size,
+ bool replace_whitespace) {
struct udev_device *dev = event->dev;
- enum subst_type {
- SUBST_UNKNOWN,
- SUBST_DEVNODE,
- SUBST_ATTR,
- SUBST_ENV,
- SUBST_KERNEL,
- SUBST_KERNEL_NUMBER,
- SUBST_DRIVER,
- SUBST_DEVPATH,
- SUBST_ID,
- SUBST_MAJOR,
- SUBST_MINOR,
- SUBST_RESULT,
- SUBST_PARENT,
- SUBST_NAME,
- SUBST_LINKS,
- SUBST_ROOT,
- SUBST_SYS,
- };
static const struct subst_map {
const char *name;
const char fmt;
@@ -132,6 +324,7 @@ size_t udev_event_apply_format(struct udev_event *event, const char *src, char *
enum subst_type type = SUBST_UNKNOWN;
char attrbuf[UTIL_PATH_SIZE];
char *attr = NULL;
+ size_t subst_len;
while (from[0] != '\0') {
if (from[0] == '$') {
@@ -200,186 +393,17 @@ subst:
attr = NULL;
}
- switch (type) {
- case SUBST_DEVPATH:
- l = strpcpy(&s, l, udev_device_get_devpath(dev));
- break;
- case SUBST_KERNEL:
- l = strpcpy(&s, l, udev_device_get_sysname(dev));
- break;
- case SUBST_KERNEL_NUMBER:
- if (udev_device_get_sysnum(dev) == NULL)
- break;
- l = strpcpy(&s, l, udev_device_get_sysnum(dev));
- break;
- case SUBST_ID:
- if (event->dev_parent == NULL)
- break;
- l = strpcpy(&s, l, udev_device_get_sysname(event->dev_parent));
- break;
- case SUBST_DRIVER: {
- const char *driver;
-
- if (event->dev_parent == NULL)
- break;
-
- driver = udev_device_get_driver(event->dev_parent);
- if (driver == NULL)
- break;
- l = strpcpy(&s, l, driver);
- break;
- }
- case SUBST_MAJOR: {
- char num[UTIL_PATH_SIZE];
-
- sprintf(num, "%u", major(udev_device_get_devnum(dev)));
- l = strpcpy(&s, l, num);
- break;
- }
- case SUBST_MINOR: {
- char num[UTIL_PATH_SIZE];
+ subst_len = subst_format_var(event, dev, type, attr, s, l);
- sprintf(num, "%u", minor(udev_device_get_devnum(dev)));
- l = strpcpy(&s, l, num);
- break;
- }
- case SUBST_RESULT: {
- char *rest;
- int i;
+ /* SUBST_RESULT handles spaces itself */
+ if (replace_whitespace && type != SUBST_RESULT)
+ /* util_replace_whitespace can replace in-place,
+ * and does nothing if subst_len == 0
+ */
+ subst_len = util_replace_whitespace(s, s, subst_len);
- if (event->program_result == NULL)
- break;
- /* get part of the result string */
- i = 0;
- if (attr != NULL)
- i = strtoul(attr, &rest, 10);
- if (i > 0) {
- char result[UTIL_PATH_SIZE];
- char tmp[UTIL_PATH_SIZE];
- char *cpos;
-
- strscpy(result, sizeof(result), event->program_result);
- cpos = result;
- while (--i) {
- while (cpos[0] != '\0' && !isspace(cpos[0]))
- cpos++;
- while (isspace(cpos[0]))
- cpos++;
- if (cpos[0] == '\0')
- break;
- }
- if (i > 0) {
- log_error("requested part of result string not found");
- break;
- }
- strscpy(tmp, sizeof(tmp), cpos);
- /* %{2+}c copies the whole string from the second part on */
- if (rest[0] != '+') {
- cpos = strchr(tmp, ' ');
- if (cpos)
- cpos[0] = '\0';
- }
- l = strpcpy(&s, l, tmp);
- } else {
- l = strpcpy(&s, l, event->program_result);
- }
- break;
- }
- case SUBST_ATTR: {
- const char *value = NULL;
- char vbuf[UTIL_NAME_SIZE];
- size_t len;
- int count;
-
- if (attr == NULL) {
- log_error("missing file parameter for attr");
- break;
- }
-
- /* try to read the value specified by "[dmi/id]product_name" */
- if (util_resolve_subsys_kernel(event->udev, attr, vbuf, sizeof(vbuf), 1) == 0)
- value = vbuf;
-
- /* try to read the attribute the device */
- if (value == NULL)
- value = udev_device_get_sysattr_value(event->dev, attr);
-
- /* try to read the attribute of the parent device, other matches have selected */
- if (value == NULL && event->dev_parent != NULL && event->dev_parent != event->dev)
- value = udev_device_get_sysattr_value(event->dev_parent, attr);
-
- if (value == NULL)
- break;
-
- /* strip trailing whitespace, and replace unwanted characters */
- if (value != vbuf)
- strscpy(vbuf, sizeof(vbuf), value);
- len = strlen(vbuf);
- while (len > 0 && isspace(vbuf[--len]))
- vbuf[len] = '\0';
- count = util_replace_chars(vbuf, UDEV_ALLOWED_CHARS_INPUT);
- if (count > 0)
- log_debug("%i character(s) replaced" , count);
- l = strpcpy(&s, l, vbuf);
- break;
- }
- case SUBST_PARENT: {
- struct udev_device *dev_parent;
- const char *devnode;
-
- dev_parent = udev_device_get_parent(event->dev);
- if (dev_parent == NULL)
- break;
- devnode = udev_device_get_devnode(dev_parent);
- if (devnode != NULL)
- l = strpcpy(&s, l, devnode + strlen("/dev/"));
- break;
- }
- case SUBST_DEVNODE:
- if (udev_device_get_devnode(dev) != NULL)
- l = strpcpy(&s, l, udev_device_get_devnode(dev));
- break;
- case SUBST_NAME:
- if (event->name != NULL)
- l = strpcpy(&s, l, event->name);
- else if (udev_device_get_devnode(dev) != NULL)
- l = strpcpy(&s, l, udev_device_get_devnode(dev) + strlen("/dev/"));
- else
- l = strpcpy(&s, l, udev_device_get_sysname(dev));
- break;
- case SUBST_LINKS: {
- struct udev_list_entry *list_entry;
-
- list_entry = udev_device_get_devlinks_list_entry(dev);
- if (list_entry == NULL)
- break;
- l = strpcpy(&s, l, udev_list_entry_get_name(list_entry) + strlen("/dev/"));
- udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry))
- l = strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry) + strlen("/dev/"), NULL);
- break;
- }
- case SUBST_ROOT:
- l = strpcpy(&s, l, "/dev");
- break;
- case SUBST_SYS:
- l = strpcpy(&s, l, "/sys");
- break;
- case SUBST_ENV:
- if (attr == NULL) {
- break;
- } else {
- const char *value;
-
- value = udev_device_get_property_value(event->dev, attr);
- if (value == NULL)
- break;
- l = strpcpy(&s, l, value);
- break;
- }
- default:
- log_error("unknown substitution type=%i", type);
- break;
- }
+ s += subst_len;
+ l -= subst_len;
}
out:
@@ -927,7 +951,7 @@ void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_
const char *cmd = udev_list_entry_get_name(list_entry);
enum udev_builtin_cmd builtin_cmd = udev_list_entry_get_num(list_entry);
- udev_event_apply_format(event, cmd, command, sizeof(command));
+ udev_event_apply_format(event, cmd, command, sizeof(command), false);
if (builtin_cmd < UDEV_BUILTIN_MAX)
udev_builtin_run(event->dev, builtin_cmd, command, false);
diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c
index 43004bc0bc..53cfd9c053 100644
--- a/src/udev/udev-node.c
+++ b/src/udev/udev-node.c
@@ -15,7 +15,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
@@ -25,7 +24,8 @@
#include <sys/stat.h>
#include <unistd.h>
-#include "formats-util.h"
+#include "dirent-util.h"
+#include "format-util.h"
#include "fs-util.h"
#include "selinux-util.h"
#include "smack-util.h"
@@ -129,6 +129,7 @@ exit:
static const char *link_find_prioritized(struct udev_device *dev, bool add, const char *stackdir, char *buf, size_t bufsize) {
struct udev *udev = udev_device_get_udev(dev);
DIR *dir;
+ struct dirent *dent;
int priority = 0;
const char *target = NULL;
@@ -141,12 +142,10 @@ static const char *link_find_prioritized(struct udev_device *dev, bool add, cons
dir = opendir(stackdir);
if (dir == NULL)
return target;
- for (;;) {
+ FOREACH_DIRENT_ALL(dent, dir, break) {
struct udev_device *dev_db;
- struct dirent *dent;
- dent = readdir(dir);
- if (dent == NULL || dent->d_name[0] == '\0')
+ if (dent->d_name[0] == '\0')
break;
if (dent->d_name[0] == '.')
continue;
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index f6c416bf70..4d07b8fce0 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -16,7 +16,6 @@
*/
#include <ctype.h>
-#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <fnmatch.h>
@@ -31,6 +30,7 @@
#include "alloc-util.h"
#include "conf-files.h"
+#include "dirent-util.h"
#include "escape.h"
#include "fd-util.h"
#include "fs-util.h"
@@ -614,7 +614,7 @@ static int import_property_from_string(struct udev_device *dev, char *line) {
/* unquote */
if (val[0] == '"' || val[0] == '\'') {
- if (val[len-1] != val[0]) {
+ if (len == 1 || val[len-1] != val[0]) {
log_debug("inconsistent quoting: '%s', skip", line);
return -1;
}
@@ -703,7 +703,7 @@ static void attr_subst_subdir(char *attr, size_t len) {
if (dir == NULL)
return;
- for (dent = readdir(dir); dent != NULL; dent = readdir(dir))
+ FOREACH_DIRENT_ALL(dent, dir, break)
if (dent->d_name[0] != '.') {
char n[strlen(dent->d_name) + strlen(tail) + 1];
@@ -1676,7 +1676,7 @@ static int match_attr(struct udev_rules *rules, struct udev_device *dev, struct
name = rules_str(rules, cur->key.attr_off);
switch (cur->key.attrsubst) {
case SB_FORMAT:
- udev_event_apply_format(event, name, nbuf, sizeof(nbuf));
+ udev_event_apply_format(event, name, nbuf, sizeof(nbuf), false);
name = nbuf;
/* fall through */
case SB_NONE:
@@ -1838,7 +1838,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
_cleanup_free_ char *value = NULL;
size_t len;
- udev_event_apply_format(event, rules_str(rules, cur->key.attr_off), filename, sizeof(filename));
+ udev_event_apply_format(event, rules_str(rules, cur->key.attr_off), filename, sizeof(filename), false);
sysctl_normalize(filename);
if (sysctl_read(filename, &value) < 0)
goto nomatch;
@@ -1916,7 +1916,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
struct stat statbuf;
int match;
- udev_event_apply_format(event, rules_str(rules, cur->key.value_off), filename, sizeof(filename));
+ udev_event_apply_format(event, rules_str(rules, cur->key.value_off), filename, sizeof(filename), false);
if (util_resolve_subsys_kernel(event->udev, filename, filename, sizeof(filename), 0) != 0) {
if (filename[0] != '/') {
char tmp[UTIL_PATH_SIZE];
@@ -1942,7 +1942,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
char result[UTIL_LINE_SIZE];
event->program_result = mfree(event->program_result);
- udev_event_apply_format(event, rules_str(rules, cur->key.value_off), program, sizeof(program));
+ udev_event_apply_format(event, rules_str(rules, cur->key.value_off), program, sizeof(program), false);
log_debug("PROGRAM '%s' %s:%u",
program,
rules_str(rules, rule->rule.filename_off),
@@ -1969,7 +1969,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
case TK_M_IMPORT_FILE: {
char import[UTIL_PATH_SIZE];
- udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import));
+ udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import), false);
if (import_file_into_properties(event->dev, import) != 0)
if (cur->key.op != OP_NOMATCH)
goto nomatch;
@@ -1978,7 +1978,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
case TK_M_IMPORT_PROG: {
char import[UTIL_PATH_SIZE];
- udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import));
+ udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import), false);
log_debug("IMPORT '%s' %s:%u",
import,
rules_str(rules, rule->rule.filename_off),
@@ -2009,7 +2009,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
event->builtin_run |= (1 << cur->key.builtin_cmd);
}
- udev_event_apply_format(event, rules_str(rules, cur->key.value_off), command, sizeof(command));
+ udev_event_apply_format(event, rules_str(rules, cur->key.value_off), command, sizeof(command), false);
log_debug("IMPORT builtin '%s' %s:%u",
udev_builtin_name(cur->key.builtin_cmd),
rules_str(rules, rule->rule.filename_off),
@@ -2077,7 +2077,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
case TK_M_IMPORT_PARENT: {
char import[UTIL_PATH_SIZE];
- udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import));
+ udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import), false);
if (import_parent_into_properties(event->dev, import) != 0)
if (cur->key.op != OP_NOMATCH)
goto nomatch;
@@ -2115,7 +2115,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
break;
if (cur->key.op == OP_ASSIGN_FINAL)
event->owner_final = true;
- udev_event_apply_format(event, rules_str(rules, cur->key.value_off), owner, sizeof(owner));
+ udev_event_apply_format(event, rules_str(rules, cur->key.value_off), owner, sizeof(owner), false);
event->owner_set = true;
r = get_user_creds(&ow, &event->uid, NULL, NULL, NULL);
if (r < 0) {
@@ -2141,7 +2141,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
break;
if (cur->key.op == OP_ASSIGN_FINAL)
event->group_final = true;
- udev_event_apply_format(event, rules_str(rules, cur->key.value_off), group, sizeof(group));
+ udev_event_apply_format(event, rules_str(rules, cur->key.value_off), group, sizeof(group), false);
event->group_set = true;
r = get_group_creds(&gr, &event->gid);
if (r < 0) {
@@ -2165,7 +2165,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
if (event->mode_final)
break;
- udev_event_apply_format(event, rules_str(rules, cur->key.value_off), mode_str, sizeof(mode_str));
+ udev_event_apply_format(event, rules_str(rules, cur->key.value_off), mode_str, sizeof(mode_str), false);
mode = strtol(mode_str, &endptr, 8);
if (endptr[0] != '\0') {
log_error("ignoring invalid mode '%s'", mode_str);
@@ -2222,7 +2222,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
const char *name, *label;
name = rules_str(rules, cur->key.attr_off);
- udev_event_apply_format(event, rules_str(rules, cur->key.value_off), label_str, sizeof(label_str));
+ udev_event_apply_format(event, rules_str(rules, cur->key.value_off), label_str, sizeof(label_str), false);
if (label_str[0] != '\0')
label = label_str;
else
@@ -2256,10 +2256,10 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
char temp[UTIL_NAME_SIZE];
/* append value separated by space */
- udev_event_apply_format(event, value, temp, sizeof(temp));
+ udev_event_apply_format(event, value, temp, sizeof(temp), false);
strscpyl(value_new, sizeof(value_new), value_old, " ", temp, NULL);
} else
- udev_event_apply_format(event, value, value_new, sizeof(value_new));
+ udev_event_apply_format(event, value, value_new, sizeof(value_new), false);
udev_device_add_property(event->dev, name, value_new);
break;
@@ -2268,7 +2268,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
char tag[UTIL_PATH_SIZE];
const char *p;
- udev_event_apply_format(event, rules_str(rules, cur->key.value_off), tag, sizeof(tag));
+ udev_event_apply_format(event, rules_str(rules, cur->key.value_off), tag, sizeof(tag), false);
if (cur->key.op == OP_ASSIGN || cur->key.op == OP_ASSIGN_FINAL)
udev_device_cleanup_tags_list(event->dev);
for (p = tag; *p != '\0'; p++) {
@@ -2296,7 +2296,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
break;
if (cur->key.op == OP_ASSIGN_FINAL)
event->name_final = true;
- udev_event_apply_format(event, name, name_str, sizeof(name_str));
+ udev_event_apply_format(event, name, name_str, sizeof(name_str), false);
if (esc == ESCAPE_UNSET || esc == ESCAPE_REPLACE) {
count = util_replace_chars(name_str, "/");
if (count > 0)
@@ -2336,7 +2336,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
udev_device_cleanup_devlinks_list(event->dev);
/* allow multiple symlinks separated by spaces */
- udev_event_apply_format(event, rules_str(rules, cur->key.value_off), temp, sizeof(temp));
+ udev_event_apply_format(event, rules_str(rules, cur->key.value_off), temp, sizeof(temp), esc != ESCAPE_NONE);
if (esc == ESCAPE_UNSET)
count = util_replace_chars(temp, "/ ");
else if (esc == ESCAPE_REPLACE)
@@ -2376,7 +2376,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
strscpyl(attr, sizeof(attr), udev_device_get_syspath(event->dev), "/", key_name, NULL);
attr_subst_subdir(attr, sizeof(attr));
- udev_event_apply_format(event, rules_str(rules, cur->key.value_off), value, sizeof(value));
+ udev_event_apply_format(event, rules_str(rules, cur->key.value_off), value, sizeof(value), false);
log_debug("ATTR '%s' writing '%s' %s:%u", attr, value,
rules_str(rules, rule->rule.filename_off),
rule->rule.filename_line);
@@ -2392,9 +2392,9 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
char value[UTIL_NAME_SIZE];
int r;
- udev_event_apply_format(event, rules_str(rules, cur->key.attr_off), filename, sizeof(filename));
+ udev_event_apply_format(event, rules_str(rules, cur->key.attr_off), filename, sizeof(filename), false);
sysctl_normalize(filename);
- udev_event_apply_format(event, rules_str(rules, cur->key.value_off), value, sizeof(value));
+ udev_event_apply_format(event, rules_str(rules, cur->key.value_off), value, sizeof(value), false);
log_debug("SYSCTL '%s' writing '%s' %s:%u", filename, value,
rules_str(rules, rule->rule.filename_off), rule->rule.filename_line);
r = sysctl_write(filename, value);
diff --git a/src/udev/udev-watch.c b/src/udev/udev-watch.c
index bc9096ed0c..aa432bb90a 100644
--- a/src/udev/udev-watch.c
+++ b/src/udev/udev-watch.c
@@ -17,13 +17,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <dirent.h>
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <sys/inotify.h>
#include <unistd.h>
+#include "dirent-util.h"
#include "stdio-util.h"
#include "udev.h"
@@ -57,7 +57,7 @@ void udev_watch_restore(struct udev *udev) {
return;
}
- for (ent = readdir(dir); ent != NULL; ent = readdir(dir)) {
+ FOREACH_DIRENT_ALL(ent, dir, break) {
char device[UTIL_PATH_SIZE];
ssize_t len;
struct udev_device *dev;
diff --git a/src/udev/udev.h b/src/udev/udev.h
index 8433e8d9f2..c0cb7eae84 100644
--- a/src/udev/udev.h
+++ b/src/udev/udev.h
@@ -80,7 +80,9 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules);
/* udev-event.c */
struct udev_event *udev_event_new(struct udev_device *dev);
void udev_event_unref(struct udev_event *event);
-size_t udev_event_apply_format(struct udev_event *event, const char *src, char *dest, size_t size);
+size_t udev_event_apply_format(struct udev_event *event,
+ const char *src, char *dest, size_t size,
+ bool replace_whitespace);
int udev_event_apply_subsys_kernel(struct udev_event *event, const char *string,
char *result, size_t maxsize, int read_value);
int udev_event_spawn(struct udev_event *event,
diff --git a/src/udev/udevadm-hwdb.c b/src/udev/udevadm-hwdb.c
index 1bffe8e8ab..70a5fa4d7a 100644
--- a/src/udev/udevadm-hwdb.c
+++ b/src/udev/udevadm-hwdb.c
@@ -653,7 +653,7 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
log_debug("strings dedup'ed: %8zu bytes (%8zu)",
trie->strings->dedup_len, trie->strings->dedup_count);
- hwdb_bin = strjoin(root, "/", hwdb_bin_dir, "/hwdb.bin", NULL);
+ hwdb_bin = strjoin(root, "/", hwdb_bin_dir, "/hwdb.bin");
if (!hwdb_bin) {
rc = EXIT_FAILURE;
goto out;
diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c
index 6753c52005..90cdfa16c7 100644
--- a/src/udev/udevadm-info.c
+++ b/src/udev/udevadm-info.c
@@ -16,7 +16,6 @@
*/
#include <ctype.h>
-#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
@@ -26,6 +25,7 @@
#include <sys/stat.h>
#include <unistd.h>
+#include "dirent-util.h"
#include "fd-util.h"
#include "string-util.h"
#include "udev-util.h"
@@ -196,7 +196,7 @@ static void cleanup_dir(DIR *dir, mode_t mask, int depth) {
if (depth <= 0)
return;
- for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
+ FOREACH_DIRENT_ALL(dent, dir, break) {
struct stat stats;
if (dent->d_name[0] == '.')
diff --git a/src/udev/udevadm-monitor.c b/src/udev/udevadm-monitor.c
index f656c2198e..94a59186ed 100644
--- a/src/udev/udevadm-monitor.c
+++ b/src/udev/udevadm-monitor.c
@@ -26,7 +26,7 @@
#include <time.h>
#include "fd-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "udev-util.h"
#include "udev.h"
@@ -41,9 +41,9 @@ static void print_device(struct udev_device *device, const char *source, int pro
struct timespec ts;
assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);
- printf("%-6s[%"PRI_TIME".%06ld] %-8s %s (%s)\n",
+ printf("%-6s[%"PRI_TIME".%06"PRI_NSEC"] %-8s %s (%s)\n",
source,
- ts.tv_sec, ts.tv_nsec/1000,
+ ts.tv_sec, (nsec_t)ts.tv_nsec/1000,
udev_device_get_action(device),
udev_device_get_devpath(device),
udev_device_get_subsystem(device));
diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c
index 702dbe5282..07b667f131 100644
--- a/src/udev/udevadm-test.c
+++ b/src/udev/udevadm-test.c
@@ -144,7 +144,7 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) {
udev_list_entry_foreach(entry, udev_list_get_entry(&event->run_list)) {
char program[UTIL_PATH_SIZE];
- udev_event_apply_format(event, udev_list_entry_get_name(entry), program, sizeof(program));
+ udev_event_apply_format(event, udev_list_entry_get_name(entry), program, sizeof(program), false);
printf("run: '%s'\n", program);
}
out:
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index badbab6205..ce2ff89b85 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -49,7 +49,7 @@
#include "dev-setup.h"
#include "fd-util.h"
#include "fileio.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "fs-util.h"
#include "hashmap.h"
#include "io-util.h"
@@ -1210,7 +1210,7 @@ static int on_sigchld(sd_event_source *s, const struct signalfd_siginfo *si, voi
else
log_warning("worker ["PID_FMT"] exited with return code %i", pid, WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
- log_warning("worker ["PID_FMT"] terminated by signal %i (%s)", pid, WTERMSIG(status), strsignal(WTERMSIG(status)));
+ log_warning("worker ["PID_FMT"] terminated by signal %i (%s)", pid, WTERMSIG(status), signal_to_string(WTERMSIG(status)));
} else if (WIFSTOPPED(status)) {
log_info("worker ["PID_FMT"] stopped", pid);
continue;
@@ -1345,7 +1345,7 @@ static int listen_fds(int *rctrl, int *rnetlink) {
return log_error_errno(netlink_fd, "could not get uevent fd: %m");
netlink_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
- if (ctrl_fd < 0)
+ if (netlink_fd < 0)
return log_error_errno(errno, "could not dup netlink fd: %m");
}
@@ -1357,10 +1357,10 @@ static int listen_fds(int *rctrl, int *rnetlink) {
/*
* read the kernel command line, in case we need to get into debug mode
- * udev.log-priority=<level> syslog priority
- * udev.children-max=<number of workers> events are fully serialized if set to 1
- * udev.exec-delay=<number of seconds> delay execution of every executed program
- * udev.event-timeout=<number of seconds> seconds to wait before terminating an event
+ * udev.log_priority=<level> syslog priority
+ * udev.children_max=<number of workers> events are fully serialized if set to 1
+ * udev.exec_delay=<number of seconds> delay execution of every executed program
+ * udev.event_timeout=<number of seconds> seconds to wait before terminating an event
*/
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
int r = 0;
@@ -1370,25 +1370,46 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
if (!value)
return 0;
- if (streq(key, "udev.log-priority") && value) {
+ if (proc_cmdline_key_streq(key, "udev.log_priority")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
r = util_log_priority(value);
if (r >= 0)
log_set_max_level(r);
- } else if (streq(key, "udev.event-timeout") && value) {
+
+ } else if (proc_cmdline_key_streq(key, "udev.event_timeout")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
r = safe_atou64(value, &arg_event_timeout_usec);
if (r >= 0) {
arg_event_timeout_usec *= USEC_PER_SEC;
arg_event_timeout_warn_usec = (arg_event_timeout_usec / 3) ? : 1;
}
- } else if (streq(key, "udev.children-max") && value)
+
+ } else if (proc_cmdline_key_streq(key, "udev.children_max")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
r = safe_atou(value, &arg_children_max);
- else if (streq(key, "udev.exec-delay") && value)
+
+ } else if (proc_cmdline_key_streq(key, "udev.exec_delay")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
r = safe_atoi(value, &arg_exec_delay);
- else if (startswith(key, "udev."))
+
+ } else if (startswith(key, "udev."))
log_warning("Unknown udev kernel command line option \"%s\"", key);
if (r < 0)
log_warning_errno(r, "Failed to parse \"%s=%s\", ignoring: %m", key, value);
+
return 0;
}
@@ -1649,7 +1670,7 @@ int main(int argc, char *argv[]) {
if (r <= 0)
goto exit;
- r = parse_proc_cmdline(parse_proc_cmdline_item, NULL, true);
+ r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
if (r < 0)
log_warning_errno(r, "failed to parse kernel command line, ignoring: %m");
diff --git a/src/update-done/update-done.c b/src/update-done/update-done.c
index 48c2a3fff4..d466e1b759 100644
--- a/src/update-done/update-done.c
+++ b/src/update-done/update-done.c
@@ -26,7 +26,7 @@
#define MESSAGE \
"# This file was created by systemd-update-done. Its only \n" \
"# purpose is to hold a timestamp of the time this directory\n" \
- "# was updated. See systemd-update-done.service(8).\n"
+ "# was updated. See man:systemd-update-done.service(8).\n"
static int apply_timestamp(const char *path, struct timespec *ts) {
struct timespec twice[2] = {
diff --git a/src/update-utmp/update-utmp.c b/src/update-utmp/update-utmp.c
index a8efe8e91f..ae9859ccad 100644
--- a/src/update-utmp/update-utmp.c
+++ b/src/update-utmp/update-utmp.c
@@ -30,7 +30,7 @@
#include "alloc-util.h"
#include "bus-error.h"
#include "bus-util.h"
-#include "formats-util.h"
+#include "format-util.h"
#include "log.h"
#include "macro.h"
#include "special.h"
diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c
index a0ab5990fc..dc63bb530c 100644
--- a/src/vconsole/vconsole-setup.c
+++ b/src/vconsole/vconsole-setup.c
@@ -28,6 +28,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
+#include <sysexits.h>
#include <termios.h>
#include <unistd.h>
@@ -41,6 +42,7 @@
#include "signal-util.h"
#include "stdio-util.h"
#include "string-util.h"
+#include "strv.h"
#include "terminal-util.h"
#include "util.h"
#include "virt.h"
@@ -124,6 +126,7 @@ static int toggle_utf8_sysfs(bool utf8) {
}
static int keyboard_load_and_wait(const char *vc, const char *map, const char *map_toggle, bool utf8) {
+ _cleanup_free_ char *cmd = NULL;
const char *args[8];
int i = 0;
pid_t pid;
@@ -143,6 +146,9 @@ static int keyboard_load_and_wait(const char *vc, const char *map, const char *m
args[i++] = map_toggle;
args[i++] = NULL;
+ log_debug("Executing \"%s\"...",
+ strnull((cmd = strv_join((char**) args, " "))));
+
pid = fork();
if (pid < 0)
return log_error_errno(errno, "Failed to fork: %m");
@@ -159,6 +165,7 @@ static int keyboard_load_and_wait(const char *vc, const char *map, const char *m
}
static int font_load_and_wait(const char *vc, const char *font, const char *map, const char *unimap) {
+ _cleanup_free_ char *cmd = NULL;
const char *args[9];
int i = 0;
pid_t pid;
@@ -182,6 +189,9 @@ static int font_load_and_wait(const char *vc, const char *font, const char *map,
args[i++] = font;
args[i++] = NULL;
+ log_debug("Executing \"%s\"...",
+ strnull((cmd = strv_join((char**) args, " "))));
+
pid = fork();
if (pid < 0)
return log_error_errno(errno, "Failed to fork: %m");
@@ -327,8 +337,8 @@ int main(int argc, char **argv) {
*vc_keymap = NULL, *vc_keymap_toggle = NULL,
*vc_font = NULL, *vc_font_map = NULL, *vc_font_unimap = NULL;
_cleanup_close_ int fd = -1;
- bool utf8, font_copy = false, font_ok, keyboard_ok;
- int r = EXIT_FAILURE;
+ bool utf8, font_copy = false, keyboard_ok;
+ int r;
log_set_target(LOG_TARGET_AUTO);
log_parse_environment();
@@ -373,7 +383,6 @@ int main(int argc, char **argv) {
"FONT_MAP", &vc_font_map,
"FONT_UNIMAP", &vc_font_unimap,
NULL);
-
if (r < 0 && r != -ENOENT)
log_warning_errno(r, "Failed to read /etc/vconsole.conf: %m");
@@ -390,22 +399,27 @@ int main(int argc, char **argv) {
"vconsole.font.map", &vc_font_map,
"vconsole.font.unimap", &vc_font_unimap,
NULL);
-
if (r < 0 && r != -ENOENT)
log_warning_errno(r, "Failed to read /proc/cmdline: %m");
}
toggle_utf8_sysfs(utf8);
toggle_utf8(vc, fd, utf8);
- font_ok = font_load_and_wait(vc, vc_font, vc_font_map, vc_font_unimap) == 0;
+
+ r = font_load_and_wait(vc, vc_font, vc_font_map, vc_font_unimap);
keyboard_ok = keyboard_load_and_wait(vc, vc_keymap, vc_keymap_toggle, utf8) == 0;
if (font_copy) {
- if (font_ok)
+ if (r == 0)
setup_remaining_vcs(fd, utf8);
+ else if (r == EX_OSERR)
+ /* setfont returns EX_OSERR when ioctl(KDFONTOP/PIO_FONTX/PIO_FONTX) fails.
+ * This might mean various things, but in particular lack of a graphical
+ * console. Let's be generous and not treat this as an error. */
+ log_notice("Setting fonts failed with a \"system error\", ignoring.");
else
log_warning("Setting source virtual console failed, ignoring remaining ones");
}
- return font_ok && keyboard_ok ? EXIT_SUCCESS : EXIT_FAILURE;
+ return IN_SET(r, 0, EX_OSERR) && keyboard_ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/veritysetup/Makefile b/src/veritysetup/Makefile
new file mode 120000
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/veritysetup/Makefile
@@ -0,0 +1 @@
+../Makefile \ No newline at end of file
diff --git a/src/veritysetup/veritysetup-generator.c b/src/veritysetup/veritysetup-generator.c
new file mode 100644
index 0000000000..0bb0bd6e8f
--- /dev/null
+++ b/src/veritysetup/veritysetup-generator.c
@@ -0,0 +1,253 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "alloc-util.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "fstab-util.h"
+#include "hexdecoct.h"
+#include "id128-util.h"
+#include "mkdir.h"
+#include "parse-util.h"
+#include "proc-cmdline.h"
+#include "string-util.h"
+#include "unit-name.h"
+
+static char *arg_dest = NULL;
+static bool arg_enabled = true;
+static char *arg_root_hash = NULL;
+static char *arg_data_what = NULL;
+static char *arg_hash_what = NULL;
+
+static int create_device(void) {
+ _cleanup_free_ char *u = NULL, *v = NULL, *d = NULL, *e = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
+ const char *p, *to;
+ int r;
+
+ /* If all three pieces of information are missing, then verity is turned off */
+ if (!arg_root_hash && !arg_data_what && !arg_hash_what)
+ return 0;
+
+ /* if one of them is missing however, the data is simply incomplete and this is an error */
+ if (!arg_root_hash)
+ log_error("Verity information incomplete, root hash unspecified.");
+ if (!arg_data_what)
+ log_error("Verity information incomplete, root data device unspecified.");
+ if (!arg_hash_what)
+ log_error("Verity information incomplete, root hash device unspecified.");
+
+ if (!arg_root_hash || !arg_data_what || !arg_hash_what)
+ return -EINVAL;
+
+ log_debug("Using root verity data device %s,\n"
+ " hash device %s,\n"
+ " and root hash %s.", arg_data_what, arg_hash_what, arg_root_hash);
+
+ p = strjoina(arg_dest, "/systemd-veritysetup@root.service");
+
+ u = fstab_node_to_udev_node(arg_data_what);
+ if (!u)
+ return log_oom();
+ v = fstab_node_to_udev_node(arg_hash_what);
+ if (!v)
+ return log_oom();
+
+ r = unit_name_from_path(u, ".device", &d);
+ if (r < 0)
+ return log_error_errno(r, "Failed to generate unit name: %m");
+ r = unit_name_from_path(v, ".device", &e);
+ if (r < 0)
+ return log_error_errno(r, "Failed to generate unit name: %m");
+
+ f = fopen(p, "wxe");
+ if (!f)
+ return log_error_errno(errno, "Failed to create unit file %s: %m", p);
+
+ fprintf(f,
+ "# Automatically generated by systemd-veritysetup-generator\n\n"
+ "[Unit]\n"
+ "Description=Integrity Protection Setup for %%I\n"
+ "Documentation=man:systemd-veritysetup-generator(8) man:systemd-veritysetup@.service(8)\n"
+ "SourcePath=/proc/cmdline\n"
+ "DefaultDependencies=no\n"
+ "Conflicts=umount.target\n"
+ "BindsTo=%s %s\n"
+ "IgnoreOnIsolate=true\n"
+ "After=cryptsetup-pre.target %s %s\n"
+ "Before=cryptsetup.target umount.target\n"
+ "\n[Service]\n"
+ "Type=oneshot\n"
+ "RemainAfterExit=yes\n"
+ "ExecStart=" ROOTLIBEXECDIR "/systemd-veritysetup attach root '%s' '%s' '%s'\n"
+ "ExecStop=" ROOTLIBEXECDIR "/systemd-veritysetup detach root\n",
+ d, e,
+ d, e,
+ u, v, arg_root_hash);
+
+ r = fflush_and_check(f);
+ if (r < 0)
+ return log_error_errno(r, "Failed to write file %s: %m", p);
+
+ to = strjoina(arg_dest, "/cryptsetup.target.requires/systemd-veritysetup@root.service");
+
+ (void) mkdir_parents(to, 0755);
+ if (symlink("../systemd-veritysetup@root.service", to) < 0)
+ return log_error_errno(errno, "Failed to create symlink %s: %m", to);
+
+ return 0;
+}
+
+static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
+ int r;
+
+ if (streq(key, "systemd.verity")) {
+
+ r = value ? parse_boolean(value) : 1;
+ if (r < 0)
+ log_warning("Failed to parse verity= kernel command line switch %s. Ignoring.", value);
+ else
+ arg_enabled = r;
+
+ } else if (streq(key, "roothash")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
+ r = free_and_strdup(&arg_root_hash, value);
+ if (r < 0)
+ return log_oom();
+
+ } else if (streq(key, "systemd.verity_root_data")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
+ r = free_and_strdup(&arg_data_what, value);
+ if (r < 0)
+ return log_oom();
+
+ } else if (streq(key, "systemd.verity_root_hash")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
+
+ r = free_and_strdup(&arg_hash_what, value);
+ if (r < 0)
+ return log_oom();
+ }
+
+ return 0;
+}
+
+static int determine_devices(void) {
+ _cleanup_free_ void *m = NULL;
+ sd_id128_t root_uuid, verity_uuid;
+ char ids[37];
+ size_t l;
+ int r;
+
+ /* Try to automatically derive the root data and hash device paths from the root hash */
+
+ if (!arg_root_hash)
+ return 0;
+
+ if (arg_data_what && arg_hash_what)
+ return 0;
+
+ r = unhexmem(arg_root_hash, strlen(arg_root_hash), &m, &l);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse root hash: %s", arg_root_hash);
+ if (l < sizeof(sd_id128_t)) {
+ log_debug("Root hash is shorter than 128 bits (32 characters), ignoring for discovering verity partition.");
+ return 0;
+ }
+
+ if (!arg_data_what) {
+ memcpy(&root_uuid, m, sizeof(root_uuid));
+
+ arg_data_what = strjoin("/dev/disk/by-partuuid/", id128_to_uuid_string(root_uuid, ids));
+ if (!arg_data_what)
+ return log_oom();
+ }
+
+ if (!arg_hash_what) {
+ memcpy(&verity_uuid, (uint8_t*) m + l - sizeof(verity_uuid), sizeof(verity_uuid));
+
+ arg_hash_what = strjoin("/dev/disk/by-partuuid/", id128_to_uuid_string(verity_uuid, ids));
+ if (!arg_hash_what)
+ return log_oom();
+ }
+
+ return 1;
+}
+
+int main(int argc, char *argv[]) {
+ int r;
+
+ if (argc > 1 && argc != 4) {
+ log_error("This program takes three or no arguments.");
+ return EXIT_FAILURE;
+ }
+
+ if (argc > 1)
+ arg_dest = argv[1];
+
+ log_set_target(LOG_TARGET_SAFE);
+ log_parse_environment();
+ log_open();
+
+ umask(0022);
+
+ r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
+ if (r < 0) {
+ log_warning_errno(r, "Failed to parse kernel command line: %m");
+ goto finish;
+ }
+
+ /* For now we only support the root device on verity. Later on we might want to add support for /etc/veritytab
+ * or similar to define additional mappings */
+
+ if (!arg_enabled) {
+ r = 0;
+ goto finish;
+ }
+
+ r = determine_devices();
+ if (r < 0)
+ goto finish;
+
+ r = create_device();
+ if (r < 0)
+ goto finish;
+
+ r = 0;
+
+finish:
+ free(arg_root_hash);
+ free(arg_data_what);
+ free(arg_hash_what);
+
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/veritysetup/veritysetup.c b/src/veritysetup/veritysetup.c
new file mode 100644
index 0000000000..f809d51638
--- /dev/null
+++ b/src/veritysetup/veritysetup.c
@@ -0,0 +1,154 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <libcryptsetup.h>
+#include <stdio.h>
+#include <sys/stat.h>
+
+#include "log.h"
+#include "hexdecoct.h"
+#include "string-util.h"
+#include "alloc-util.h"
+
+static char *arg_root_hash = NULL;
+static char *arg_data_what = NULL;
+static char *arg_hash_what = NULL;
+
+static int help(void) {
+ printf("%s attach VOLUME DATADEVICE HASHDEVICE ROOTHASH\n"
+ "%s detach VOLUME\n\n"
+ "Attaches or detaches an integrity protected block device.\n",
+ program_invocation_short_name,
+ program_invocation_short_name);
+
+ return 0;
+}
+
+static void log_glue(int level, const char *msg, void *usrptr) {
+ log_debug("%s", msg);
+}
+
+int main(int argc, char *argv[]) {
+ struct crypt_device *cd = NULL;
+ int r;
+
+ if (argc <= 1) {
+ r = help();
+ goto finish;
+ }
+
+ if (argc < 3) {
+ log_error("This program requires at least two arguments.");
+ r = -EINVAL;
+ goto finish;
+ }
+
+ log_set_target(LOG_TARGET_AUTO);
+ log_parse_environment();
+ log_open();
+
+ umask(0022);
+
+ if (streq(argv[1], "attach")) {
+ _cleanup_free_ void *m = NULL;
+ crypt_status_info status;
+ size_t l;
+
+ if (argc < 6) {
+ log_error("attach requires at least two arguments.");
+ r = -EINVAL;
+ goto finish;
+ }
+
+ r = unhexmem(argv[5], strlen(argv[5]), &m, &l);
+ if (r < 0) {
+ log_error("Failed to parse root hash.");
+ goto finish;
+ }
+
+ r = crypt_init(&cd, argv[4]);
+ if (r < 0) {
+ log_error_errno(r, "Failed to open verity device %s: %m", argv[4]);
+ goto finish;
+ }
+
+ crypt_set_log_callback(cd, log_glue, NULL);
+
+ status = crypt_status(cd, argv[2]);
+ if (status == CRYPT_ACTIVE || status == CRYPT_BUSY) {
+ log_info("Volume %s already active.", argv[2]);
+ r = 0;
+ goto finish;
+ }
+
+ r = crypt_load(cd, CRYPT_VERITY, NULL);
+ if (r < 0) {
+ log_error_errno(r, "Failed to load verity superblock: %m");
+ goto finish;
+ }
+
+ r = crypt_set_data_device(cd, argv[3]);
+ if (r < 0) {
+ log_error_errno(r, "Failed to configure data device: %m");
+ goto finish;
+ }
+
+ r = crypt_activate_by_volume_key(cd, argv[2], m, l, CRYPT_ACTIVATE_READONLY);
+ if (r < 0) {
+ log_error_errno(r, "Failed to set up verity device: %m");
+ goto finish;
+ }
+
+ } else if (streq(argv[1], "detach")) {
+
+ r = crypt_init_by_name(&cd, argv[2]);
+ if (r == -ENODEV) {
+ log_info("Volume %s already inactive.", argv[2]);
+ goto finish;
+ } else if (r < 0) {
+ log_error_errno(r, "crypt_init_by_name() failed: %m");
+ goto finish;
+ }
+
+ crypt_set_log_callback(cd, log_glue, NULL);
+
+ r = crypt_deactivate(cd, argv[2]);
+ if (r < 0) {
+ log_error_errno(r, "Failed to deactivate: %m");
+ goto finish;
+ }
+
+ } else {
+ log_error("Unknown verb %s.", argv[1]);
+ r = -EINVAL;
+ goto finish;
+ }
+
+ r = 0;
+
+finish:
+ if (cd)
+ crypt_free(cd);
+
+ free(arg_root_hash);
+ free(arg_data_what);
+ free(arg_hash_what);
+
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/volatile-root/Makefile b/src/volatile-root/Makefile
new file mode 120000
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/volatile-root/Makefile
@@ -0,0 +1 @@
+../Makefile \ No newline at end of file
diff --git a/src/volatile-root/volatile-root.c b/src/volatile-root/volatile-root.c
new file mode 100644
index 0000000000..3c0b6fa1de
--- /dev/null
+++ b/src/volatile-root/volatile-root.c
@@ -0,0 +1,157 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/mount.h>
+
+#include "alloc-util.h"
+#include "fs-util.h"
+#include "mkdir.h"
+#include "mount-util.h"
+#include "stat-util.h"
+#include "volatile-util.h"
+#include "string-util.h"
+#include "path-util.h"
+
+static int make_volatile(const char *path) {
+ _cleanup_free_ char *old_usr = NULL;
+ int r;
+
+ r = path_is_mount_point(path, NULL, AT_SYMLINK_FOLLOW);
+ if (r < 0)
+ return log_error_errno(r, "Couldn't determine whether %s is a mount point: %m", path);
+ if (r == 0) {
+ log_error("%s is not a mount point.", path);
+ return -EINVAL;
+ }
+
+ r = path_is_temporary_fs(path);
+ if (r < 0)
+ return log_error_errno(r, "Couldn't determine whether %s is a temporary file system: %m", path);
+ if (r > 0) {
+ log_info("%s already is a temporary file system.", path);
+ return 0;
+ }
+
+ r = chase_symlinks("/usr", path, CHASE_PREFIX_ROOT, &old_usr);
+ if (r < 0)
+ return log_error_errno(r, "/usr not available in old root: %m");
+
+ r = mkdir_p("/run/systemd/volatile-sysroot", 0700);
+ if (r < 0)
+ return log_error_errno(r, "Couldn't generate volatile sysroot directory: %m");
+
+ r = mount_verbose(LOG_ERR, "tmpfs", "/run/systemd/volatile-sysroot", "tmpfs", MS_STRICTATIME, "mode=755");
+ if (r < 0)
+ goto finish_rmdir;
+
+ if (mkdir("/run/systemd/volatile-sysroot/usr", 0755) < 0) {
+ r = -errno;
+ goto finish_umount;
+ }
+
+ r = mount_verbose(LOG_ERR, old_usr, "/run/systemd/volatile-sysroot/usr", NULL, MS_BIND|MS_REC, NULL);
+ if (r < 0)
+ goto finish_umount;
+
+ r = bind_remount_recursive("/run/systemd/volatile-sysroot/usr", true, NULL);
+ if (r < 0)
+ goto finish_umount;
+
+ r = umount_recursive(path, 0);
+ if (r < 0) {
+ log_error_errno(r, "Failed to unmount %s: %m", path);
+ goto finish_umount;
+ }
+
+ if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0)
+ log_warning_errno(errno, "Failed to remount %s MS_SLAVE|MS_REC: %m", path);
+
+ r = mount_verbose(LOG_ERR, "/run/systemd/volatile-sysroot", path, NULL, MS_MOVE, NULL);
+
+finish_umount:
+ (void) umount_recursive("/run/systemd/volatile-sysroot", 0);
+
+finish_rmdir:
+ (void) rmdir("/run/systemd/volatile-sysroot");
+
+ return r;
+}
+
+int main(int argc, char *argv[]) {
+ VolatileMode m = _VOLATILE_MODE_INVALID;
+ const char *path;
+ int r;
+
+ log_set_target(LOG_TARGET_AUTO);
+ log_parse_environment();
+ log_open();
+
+ if (argc > 3) {
+ log_error("Too many arguments. Expected directory and mode.");
+ r = -EINVAL;
+ goto finish;
+ }
+
+ r = query_volatile_mode(&m);
+ if (r < 0) {
+ log_error_errno(r, "Failed to determine volatile mode from kernel command line.");
+ goto finish;
+ }
+ if (r == 0 && argc >= 2) {
+ /* The kernel command line always wins. However if nothing was set there, the argument passed here wins instead. */
+ m = volatile_mode_from_string(argv[1]);
+ if (m < 0) {
+ log_error("Couldn't parse volatile mode: %s", argv[1]);
+ r = -EINVAL;
+ goto finish;
+ }
+ }
+
+ if (argc < 3)
+ path = "/sysroot";
+ else {
+ path = argv[2];
+
+ if (isempty(path)) {
+ log_error("Directory name cannot be empty.");
+ r = -EINVAL;
+ goto finish;
+ }
+ if (!path_is_absolute(path)) {
+ log_error("Directory must be specified as absolute path.");
+ r = -EINVAL;
+ goto finish;
+ }
+ if (path_equal(path, "/")) {
+ log_error("Directory cannot be the root directory.");
+ r = -EINVAL;
+ goto finish;
+ }
+ }
+
+ if (m != VOLATILE_YES) {
+ r = 0;
+ goto finish;
+ }
+
+ r = make_volatile(path);
+
+finish:
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/sysctl.d/50-default.conf b/sysctl.d/50-default.conf
index f08f32e849..aff99300d9 100644
--- a/sysctl.d/50-default.conf
+++ b/sysctl.d/50-default.conf
@@ -14,7 +14,8 @@
# System Request functionality of the kernel (SYNC)
#
# Use kernel.sysrq = 1 to allow all keys.
-# See http://fedoraproject.org/wiki/QA/Sysrq for a list of values and keys.
+# See https://www.kernel.org/doc/html/latest/admin-guide/sysrq.html for a list
+# of values and keys.
kernel.sysrq = 16
# Append the PID to the core filename
diff --git a/system-preset/90-systemd.preset b/system-preset/90-systemd.preset
index 6b5349dc8d..3ba4bb760d 100644
--- a/system-preset/90-systemd.preset
+++ b/system-preset/90-systemd.preset
@@ -15,7 +15,6 @@ 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 debug-shell.service
diff --git a/test/TEST-03-JOBS/test-jobs.sh b/test/TEST-03-JOBS/test-jobs.sh
index fa6cf4181a..48926290a6 100755
--- a/test/TEST-03-JOBS/test-jobs.sh
+++ b/test/TEST-03-JOBS/test-jobs.sh
@@ -68,7 +68,7 @@ START_SEC=$(date -u '+%s')
systemctl start --wait wait2.service || exit 1
END_SEC=$(date -u '+%s')
ELAPSED=$(($END_SEC-$START_SEC))
-[[ "$ELAPSED" -ge 2 ]] && [[ "$ELAPSED" -le 3 ]] || exit 1
+[[ "$ELAPSED" -ge 2 ]] && [[ "$ELAPSED" -le 4 ]] || exit 1
# wait5fail fails, so systemctl should fail
START_SEC=$(date -u '+%s')
diff --git a/test/TEST-13-NSPAWN-SMOKE/test.sh b/test/TEST-13-NSPAWN-SMOKE/test.sh
index e6977a7f1c..75b99236a3 100755
--- a/test/TEST-13-NSPAWN-SMOKE/test.sh
+++ b/test/TEST-13-NSPAWN-SMOKE/test.sh
@@ -39,10 +39,13 @@ test_setup() {
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
- dracut_install busybox chmod rmdir
+ dracut_install busybox chmod rmdir unshare
cp create-busybox-container $initdir/
+ ./create-busybox-container $initdir/nc-container
+ initdir="$initdir/nc-container" dracut_install nc
+
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
@@ -78,6 +81,26 @@ if [[ -f /proc/1/ns/cgroup ]]; then
is_cgns_supported=yes
fi
+is_user_ns_supported=no
+if unshare -U sh -c :; then
+ is_user_ns_supported=yes
+fi
+
+function check_bind_tmp_path {
+ # https://github.com/systemd/systemd/issues/4789
+ local _root="/var/lib/machines/bind-tmp-path"
+ /create-busybox-container "$_root"
+ >/tmp/bind
+ systemd-nspawn --register=no -D "$_root" --bind=/tmp/bind /bin/sh -c 'test -e /tmp/bind'
+}
+
+function check_notification_socket {
+ # https://github.com/systemd/systemd/issues/4944
+ local _cmd='echo a | $(busybox which nc) -U -u -w 1 /run/systemd/nspawn/notify'
+ systemd-nspawn --register=no -D /nc-container /bin/sh -x -c "$_cmd"
+ systemd-nspawn --register=no -D /nc-container -U /bin/sh -x -c "$_cmd"
+}
+
function run {
if [[ "$1" = "yes" && "$is_v2_supported" = "no" ]]; then
printf "Unified cgroup hierarchy is not supported. Skipping.\n" >&2
@@ -88,20 +111,36 @@ function run {
return 0
fi
- local _root="/var/lib/machines/unified-$1-cgns-$2"
+ local _root="/var/lib/machines/unified-$1-cgns-$2-api-vfs-writable-$3"
/create-busybox-container "$_root"
- UNIFIED_CGROUP_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" systemd-nspawn --register=no -D "$_root" -b
- UNIFIED_CGROUP_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" systemd-nspawn --register=no -D "$_root" --private-network -b
- UNIFIED_CGROUP_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" systemd-nspawn --register=no -D "$_root" -U -b
- UNIFIED_CGROUP_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" systemd-nspawn --register=no -D "$_root" --private-network -U -b
+ UNIFIED_CGROUP_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" -b
+ UNIFIED_CGROUP_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" --private-network -b
+
+ if UNIFIED_CGROUP_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" -U -b; then
+ [[ "$is_user_ns_supported" = "yes" && "$3" = "network" ]] && return 1
+ else
+ [[ "$is_user_ns_supported" = "no" && "$3" = "network" ]] && return 1
+ fi
+
+ if UNIFIED_CGROUP_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" --private-network -U -b; then
+ [[ "$is_user_ns_supported" = "yes" && "$3" = "yes" ]] && return 1
+ else
+ [[ "$is_user_ns_supported" = "no" && "$3" = "yes" ]] && return 1
+ fi
return 0
}
-run no no
-run yes no
-run no yes
-run yes yes
+check_bind_tmp_path
+
+check_notification_socket
+
+for api_vfs_writable in yes no network; do
+ run no no $api_vfs_writable
+ run yes no $api_vfs_writable
+ run no yes $api_vfs_writable
+ run yes yes $api_vfs_writable
+done
touch /testok
EOF
diff --git a/test/TEST-14-MACHINE-ID/Makefile b/test/TEST-14-MACHINE-ID/Makefile
new file mode 100644
index 0000000000..5e89a29eff
--- /dev/null
+++ b/test/TEST-14-MACHINE-ID/Makefile
@@ -0,0 +1,10 @@
+all:
+ @make -s --no-print-directory -C ../.. all
+ @basedir=../.. TEST_BASE_DIR=../ ./test.sh --all
+setup:
+ @make --no-print-directory -C ../.. all
+ @basedir=../.. TEST_BASE_DIR=../ ./test.sh --setup
+clean:
+ @basedir=../.. TEST_BASE_DIR=../ ./test.sh --clean
+run:
+ @basedir=../.. TEST_BASE_DIR=../ ./test.sh --run
diff --git a/test/TEST-14-MACHINE-ID/test.sh b/test/TEST-14-MACHINE-ID/test.sh
new file mode 100755
index 0000000000..35106e39d2
--- /dev/null
+++ b/test/TEST-14-MACHINE-ID/test.sh
@@ -0,0 +1,119 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+TEST_DESCRIPTION="Basic systemd setup"
+SKIP_INITRD=yes
+. $TEST_BASE_DIR/test-functions
+
+check_result_qemu() {
+ ret=1
+ mkdir -p $TESTDIR/root
+ mount ${LOOPDEV}p1 $TESTDIR/root
+ [[ -e $TESTDIR/root/testok ]] && ret=0
+ [[ -f $TESTDIR/root/failed ]] && cp -a $TESTDIR/root/failed $TESTDIR
+ cp -a $TESTDIR/root/var/log/journal $TESTDIR
+ umount $TESTDIR/root
+ [[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed
+ ls -l $TESTDIR/journal/*/*.journal
+ test -s $TESTDIR/failed && ret=$(($ret+1))
+ return $ret
+}
+
+test_run() {
+ if run_qemu; then
+ check_result_qemu || return 1
+ else
+ dwarn "can't run QEMU, skipping"
+ fi
+ return 0
+}
+
+test_setup() {
+ create_empty_image
+ mkdir -p $TESTDIR/root
+ mount ${LOOPDEV}p1 $TESTDIR/root
+
+ # Create what will eventually be our root filesystem onto an overlay
+ (
+ LOG_LEVEL=5
+ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
+
+ setup_basic_environment
+ printf "556f48e837bc4424a710fa2e2c9d3e3c\ne3d\n" >$initdir/etc/machine-id
+ dracut_install mount cmp
+
+ # setup the testsuite service
+ cat >$initdir/etc/systemd/system/testsuite.service <<EOF
+[Unit]
+Description=Testsuite service
+After=multi-user.target
+
+[Service]
+ExecStart=/bin/sh -e -x -c '/test-machine-id-setup.sh; systemctl --state=failed --no-legend --no-pager > /failed ; echo OK > /testok'
+Type=oneshot
+EOF
+
+cat >$initdir/test-machine-id-setup.sh <<'EOF'
+#!/bin/bash
+
+set -e
+set -x
+
+function setup_root {
+ local _root="$1"
+ mkdir -p "$_root"
+ mount -t tmpfs tmpfs "$_root"
+ mkdir -p "$_root/etc" "$_root/run"
+}
+
+function check {
+ printf "Expected\n"
+ cat "$1"
+ printf "\nGot\n"
+ cat "$2"
+ cmp "$1" "$2"
+}
+
+r="$(pwd)/overwrite-broken-machine-id"
+setup_root "$r"
+systemd-machine-id-setup --print --root "$r"
+echo abc >>"$r/etc/machine-id"
+id=$(systemd-machine-id-setup --print --root "$r")
+echo $id >expected
+check expected "$r/etc/machine-id"
+
+r="$(pwd)/transient-machine-id"
+setup_root "$r"
+systemd-machine-id-setup --print --root "$r"
+echo abc >>"$r/etc/machine-id"
+mount -o remount,ro "$r"
+mount -t tmpfs tmpfs "$r/run"
+transient_id=$(systemd-machine-id-setup --print --root "$r")
+mount -o remount,rw "$r"
+commited_id=$(systemd-machine-id-setup --print --commit --root "$r")
+[[ "$transient_id" = "$commited_id" ]]
+check "$r/etc/machine-id" "$r/run/machine-id"
+EOF
+chmod +x $initdir/test-machine-id-setup.sh
+
+ setup_testsuite
+ ) || return 1
+
+ # mask some services that we do not want to run in these tests
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.service
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-resolved.service
+
+ ddebug "umount $TESTDIR/root"
+ umount $TESTDIR/root
+}
+
+test_cleanup() {
+ umount $TESTDIR/root 2>/dev/null
+ [[ $LOOPDEV ]] && losetup -d $LOOPDEV
+ return 0
+}
+
+do_test "$@"
diff --git a/test/TEST-15-DROPIN/Makefile b/test/TEST-15-DROPIN/Makefile
new file mode 120000
index 0000000000..e9f93b1104
--- /dev/null
+++ b/test/TEST-15-DROPIN/Makefile
@@ -0,0 +1 @@
+../TEST-01-BASIC/Makefile \ No newline at end of file
diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh
new file mode 100755
index 0000000000..9d8af99ac4
--- /dev/null
+++ b/test/TEST-15-DROPIN/test-dropin.sh
@@ -0,0 +1,274 @@
+#! /bin/bash
+
+set -e
+set -x
+
+_clear_service () {
+ systemctl stop $1.service 2>/dev/null || :
+ rm -f /{etc,run,usr/lib}/systemd/system/$1.service
+ rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.d
+ rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.{wants,requires}
+}
+
+clear_services () {
+ for u in $*; do
+ _clear_service $u
+ done
+ systemctl daemon-reload
+}
+
+create_service () {
+ clear_services $1
+
+ cat >/etc/systemd/system/$1.service<<EOF
+[Unit]
+Description=$1 unit
+
+[Service]
+ExecStart=/bin/sleep 100000
+EOF
+ mkdir -p /{etc,run,usr/lib}/systemd/system/$1.service.d
+ mkdir -p /etc/systemd/system/$1.service.{wants,requires}
+ mkdir -p /run/systemd/system/$1.service.{wants,requires}
+ mkdir -p /usr/lib/systemd/system/$1.service.{wants,requires}
+}
+
+create_services () {
+ for u in $*; do
+ create_service $u
+ done
+}
+
+check_ok () {
+ [ $# -eq 3 ] || return
+
+ x="$(systemctl show --value -p $2 $1)"
+ case "$x" in
+ *$3*) return 0 ;;
+ *) return 1
+ esac
+}
+
+check_ko () {
+ ! check_ok "$@"
+}
+
+test_basic_dropins () {
+ echo "Testing basic dropins..."
+
+ echo "*** test a wants b wants c"
+ create_services a b c
+ ln -s ../b.service /etc/systemd/system/a.service.wants/
+ ln -s ../c.service /etc/systemd/system/b.service.wants/
+ check_ok a Wants b.service
+ check_ok b Wants c.service
+
+ echo "*** test a wants,requires b"
+ create_services a b c
+ ln -s ../b.service /etc/systemd/system/a.service.wants/
+ ln -s ../b.service /etc/systemd/system/a.service.requires/
+ check_ok a Wants b.service
+ check_ok a Requires b.service
+
+ echo "*** test a wants nonexistent"
+ create_service a
+ ln -s ../nonexistent.service /etc/systemd/system/a.service.wants/
+ check_ok a Wants nonexistent.service
+ systemctl start a
+ systemctl stop a
+
+ echo "*** test a requires nonexistent"
+ ln -sf ../nonexistent.service /etc/systemd/system/a.service.requires/
+ systemctl daemon-reload
+ check_ok a Requires nonexistent.service
+
+ # 'b' is already loaded when 'c' pulls it in via a dropin.
+ echo "*** test a,c require b"
+ create_services a b c
+ ln -sf ../b.service /etc/systemd/system/a.service.requires/
+ ln -sf ../b.service /etc/systemd/system/c.service.requires/
+ systemctl start a
+ check_ok c Requires b.service
+ systemctl stop a b
+
+ # 'b' is already loaded when 'c' pulls it in via an alias dropin.
+ echo "*** test a wants alias"
+ create_services a b c
+ ln -sf c.service /etc/systemd/system/c1.service
+ ln -sf ../c.service /etc/systemd/system/a.service.wants/
+ ln -sf ../c1.service /etc/systemd/system/b.service.wants/
+ systemctl start a
+ check_ok a Wants c.service
+ check_ok b Wants c.service
+ systemctl stop a c
+
+ clear_services a b c
+}
+
+test_template_dropins () {
+ echo "Testing template dropins..."
+
+ create_services foo bar@ yup@
+
+ ln -s /etc/systemd/system/bar@.service /etc/systemd/system/foo.service.wants/bar@1.service
+ check_ok foo Wants bar@1.service
+
+ clear_services foo bar@ yup@
+}
+
+test_alias_dropins () {
+ echo "Testing alias dropins..."
+
+ echo "*** test a wants b1 alias of b"
+ create_services a b
+ ln -sf b.service /etc/systemd/system/b1.service
+ ln -sf ../b1.service /etc/systemd/system/a.service.wants/
+ check_ok a Wants b.service
+ systemctl start a
+ systemctl --quiet is-active b
+ systemctl stop a b
+ rm /etc/systemd/system/b1.service
+ clear_services a b
+
+ # A weird behavior: the dependencies for 'a' may vary. It can be
+ # changed by loading an alias...
+ #
+ # [1] 'a1' is loaded and then "renamed" into 'a'. 'a1' is therefore
+ # part of the names set so all its specific dropins are loaded.
+ #
+ # [2] 'a' is already loaded. 'a1' is simply only merged into 'a' so
+ # none of its dropins are loaded ('y' is missing from the deps).
+ echo "*** test 2"
+ create_services a x y
+ mkdir -p /etc/systemd/system/a1.service.wants/
+ ln -sf a.service /etc/systemd/system/a1.service
+ ln -sf ../x.service /etc/systemd/system/a.service.wants/
+ ln -sf ../y.service /etc/systemd/system/a1.service.wants/
+ check_ok a1 Wants x.service # see [1]
+ check_ok a1 Wants y.service
+ systemctl start a
+ check_ok a1 Wants x.service # see [2]
+ check_ko a1 Wants y.service
+ systemctl stop a x y
+ rm /etc/systemd/system/a1.service
+
+ clear_services a x y
+}
+
+test_masked_dropins () {
+ echo "Testing masked dropins..."
+
+ create_services a b
+
+ # 'b' is masked for both deps
+ echo "*** test a wants,requires b is masked"
+ ln -sf /dev/null /etc/systemd/system/a.service.wants/b.service
+ ln -sf /dev/null /etc/systemd/system/a.service.requires/b.service
+ check_ko a Wants b.service
+ check_ko a Requires b.service
+
+ # 'a' wants 'b' and 'b' is masked at a lower level
+ echo "*** test a wants b, mask override"
+ ln -sf ../b.service /etc/systemd/system/a.service.wants/b.service
+ ln -sf /dev/null /usr/lib/systemd/system/a.service.wants/b.service
+ check_ok a Wants b.service
+
+ # 'a' wants 'b' and 'b' is masked at a higher level
+ echo "*** test a wants b, mask"
+ ln -sf /dev/null /etc/systemd/system/a.service.wants/b.service
+ ln -sf ../b.service /usr/lib/systemd/system/a.service.wants/b.service
+ check_ko a Wants b.service
+
+ # 'b1' is an alias for 'b': masking 'b' dep should not influence 'b1' dep
+ echo "*** test a wants b, b1, and one is masked"
+ create_services a b
+ ln -sf b.service /etc/systemd/system/b1.service
+ ln -sf /dev/null /etc/systemd/system/a.service.wants/b.service
+ ln -sf ../b1.service /usr/lib/systemd/system/a.service.wants/b1.service
+ systemctl cat a
+ systemctl show -p Wants,Requires a
+ systemctl cat b1
+ systemctl show -p Wants,Requires b1
+ check_ok a Wants b.service
+ check_ko a Wants b1.service # the alias does not show up in the list of units
+ rm /etc/systemd/system/b1.service
+
+ # 'b1' is an alias for 'b': masking 'b1' should not influence 'b' dep
+ echo "*** test a wants b, alias dep is masked"
+ create_services a b
+ ln -sf b.service /etc/systemd/system/b1.service
+ ln -sf /dev/null /etc/systemd/system/a.service.wants/b1.service
+ ln -sf ../b.service /usr/lib/systemd/system/a.service.wants/b.service
+ check_ok a Wants b.service
+ check_ko a Wants b1.service # the alias does not show up in the list of units
+ rm /etc/systemd/system/b1.service
+
+ # 'a' has Wants=b.service but also has a masking
+ # dropin 'b': 'b' should still be pulled in.
+ echo "*** test a wants b both ways"
+ create_services a b
+ ln -sf /dev/null /etc/systemd/system/a.service.wants/b.service
+ cat >/usr/lib/systemd/system/a.service.d/wants-b.conf<<EOF
+[Unit]
+Wants=b.service
+EOF
+ check_ok a Wants b.service
+
+ # mask a dropin that points to an nonexistent unit.
+ echo "*** test a wants nonexistent is masked"
+ create_services a
+ ln -sf /dev/null /etc/systemd/system/a.service.requires/nonexistent.service
+ ln -sf ../nonexistent.service /usr/lib/systemd/system/a.service.requires/
+ check_ko a Requires nonexistent.service
+
+ # 'b' is already loaded when 'c' pulls it in via a dropin but 'b' is
+ # masked at a higher level.
+ echo "*** test a wants b is masked"
+ create_services a b c
+ ln -sf ../b.service /etc/systemd/system/a.service.requires/
+ ln -sf ../b.service /run/systemd/system/c.service.requires/
+ ln -sf /dev/null /etc/systemd/system/c.service.requires/b.service
+ systemctl start a
+ check_ko c Requires b.service
+ systemctl stop a b
+
+ # 'b' is already loaded when 'c' pulls it in via a dropin but 'b' is
+ # masked at a lower level.
+ echo "*** test a requires b is masked"
+ create_services a b c
+ ln -sf ../b.service /etc/systemd/system/a.service.requires/
+ ln -sf ../b.service /etc/systemd/system/c.service.requires/
+ ln -sf /dev/null /run/systemd/system/c.service.requires/b.service
+ systemctl start a
+ check_ok c Requires b.service
+ systemctl stop a b
+
+ # 'a' requires 2 aliases of 'b' and one of them is a mask.
+ echo "*** test a requires alias of b, other alias masked"
+ create_services a b
+ ln -sf b.service /etc/systemd/system/b1.service
+ ln -sf b.service /etc/systemd/system/b2.service
+ ln -sf /dev/null /etc/systemd/system/a.service.requires/b1.service
+ ln -sf ../b1.service /run/systemd/system/a.service.requires/
+ ln -sf ../b2.service /usr/lib/systemd/system/a.service.requires/
+ check_ok a Requires b
+
+ # Same as above but now 'b' is masked.
+ echo "*** test a requires alias of b, b dep masked"
+ create_services a b
+ ln -sf b.service /etc/systemd/system/b1.service
+ ln -sf b.service /etc/systemd/system/b2.service
+ ln -sf ../b1.service /run/systemd/system/a.service.requires/
+ ln -sf ../b2.service /usr/lib/systemd/system/a.service.requires/
+ ln -sf /dev/null /etc/systemd/system/a.service.requires/b.service
+ check_ok a Requires b
+
+ clear_services a b
+}
+
+test_basic_dropins
+test_template_dropins
+test_alias_dropins
+test_masked_dropins
+
+touch /testok
diff --git a/test/TEST-15-DROPIN/test.sh b/test/TEST-15-DROPIN/test.sh
new file mode 100755
index 0000000000..1b460db7b1
--- /dev/null
+++ b/test/TEST-15-DROPIN/test.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+
+TEST_DESCRIPTION="Dropin tests"
+
+. $TEST_BASE_DIR/test-functions
+
+
+test_run_nspawn() {
+ if ! run_nspawn; then
+ dwarn "can't run systemd-nspawn, skipping"
+ return 0
+ fi
+ check_result_nspawn
+}
+
+test_run() {
+ test_run_nspawn || return
+}
+
+test_setup() {
+ # create the basic filesystem layout
+ setup_basic_environment >/dev/null
+
+ # mask some services that we do not want to run in these tests
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.service
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-resolved.service
+
+ # import the test scripts in the rootfs and plug them in systemd
+ cp testsuite.service $initdir/etc/systemd/system/
+ cp test-dropin.sh $initdir/
+ setup_testsuite
+
+ # create dedicated rootfs for nspawn (located in $TESTDIR/nspawn-root)
+ setup_nspawn_root
+}
+
+test_cleanup() {
+ return 0
+}
+
+do_test "$@"
diff --git a/test/TEST-15-DROPIN/testsuite.service b/test/TEST-15-DROPIN/testsuite.service
new file mode 100644
index 0000000000..d9790c2610
--- /dev/null
+++ b/test/TEST-15-DROPIN/testsuite.service
@@ -0,0 +1,7 @@
+[Unit]
+Description=Testsuite service
+After=multi-user.target
+
+[Service]
+ExecStart=/test-dropin.sh
+Type=oneshot
diff --git a/test/create-sys-script.py b/test/create-sys-script.py
new file mode 100755
index 0000000000..4b7abd24ae
--- /dev/null
+++ b/test/create-sys-script.py
@@ -0,0 +1,183 @@
+#!/usr/bin/python3
+
+OUTFILE_HEADER = """#!/usr/bin/python3
+#
+# create-sys-script.py
+#
+# (C) 2017 Canonical Ltd.
+# Author: Dan Streetman <dan.streetman@canonical.com>
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+#
+"""
+
+# Use this only to (re-)create the test/sys-script.py script,
+# after adding or modifying anything in the test/sys/ directory
+
+
+import os, sys, stat, tempfile, filecmp
+
+
+OUTFILE = "sys-script.py"
+OUTFILE_MODE = 0o775
+
+OUTFILE_FUNCS = r"""
+import os, sys
+
+def d(path, mode):
+ os.mkdir(path, mode)
+
+def l(path, src):
+ os.symlink(src, path)
+
+def f(path, mode, contents):
+ with open(path, "wb") as f:
+ f.write(contents)
+ os.chmod(path, mode)
+
+"""
+
+OUTFILE_MAIN = """
+if len(sys.argv) < 2:
+ exit("Usage: {} <target dir>".format(sys.argv[0]))
+
+if not os.path.isdir(sys.argv[1]):
+ exit("Target dir {} not found".format(sys.argv[1]))
+
+os.chdir(sys.argv[1])
+
+"""
+
+
+def handle_dir(outfile, path):
+ m = os.lstat(path).st_mode & 0o777
+ outfile.write("d('{}', {:#o})\n".format(path, m))
+
+
+def handle_link(outfile, path):
+ src = os.readlink(path)
+ outfile.write("l('{}', '{}')\n".format(path, src))
+
+
+def escape_single_quotes(b):
+ # remove the b'' wrapping each line repr
+ r = repr(b)[2:-1]
+ # python escapes all ' only if there are ' and " in the string
+ if '"' not in r:
+ r = r.replace("'", r"\'")
+ # return line with all ' escaped
+ return r
+
+
+def handle_file(outfile, path):
+ m = os.lstat(path).st_mode & 0o777
+ with open(path, "rb") as f:
+ b = f.read()
+ if b.count(b"\n") > 1:
+ r = "\n".join([ escape_single_quotes(l) for l in b.split(b"\n") ])
+ r = "b'''{r}'''".format(r=r)
+ else:
+ r = repr(b)
+ outfile.write("f('{}', {:#o}, {})\n".format(path, m, r))
+
+
+def process_sysdir(outfile):
+ for (dirpath, dirnames, filenames) in os.walk("sys"):
+ handle_dir(outfile, dirpath)
+ for d in dirnames:
+ path = os.path.join(dirpath, d)
+ if stat.S_ISLNK(os.lstat(path).st_mode):
+ handle_link(outfile, path)
+ for f in filenames:
+ path = os.path.join(dirpath, f)
+ mode = os.lstat(path).st_mode
+ if stat.S_ISLNK(mode):
+ handle_link(outfile, path)
+ elif stat.S_ISREG(mode):
+ handle_file(outfile, path)
+
+
+def verify_dir(tmpd, path_a):
+ path_b = os.path.join(tmpd, path_a)
+ mode_a = os.lstat(path_a).st_mode
+ mode_b = os.lstat(path_b).st_mode
+ if not stat.S_ISDIR(mode_b):
+ raise Exception("Not directory")
+ if (mode_a & 0o777) != (mode_b & 0o777):
+ raise Exception("Permissions mismatch")
+
+
+def verify_link(tmpd, path_a):
+ path_b = os.path.join(tmpd, path_a)
+ if not stat.S_ISLNK(os.lstat(path_b).st_mode):
+ raise Exception("Not symlink")
+ if os.readlink(path_a) != os.readlink(path_b):
+ raise Exception("Symlink dest mismatch")
+
+
+def verify_file(tmpd, path_a):
+ path_b = os.path.join(tmpd, path_a)
+ mode_a = os.lstat(path_a).st_mode
+ mode_b = os.lstat(path_b).st_mode
+ if not stat.S_ISREG(mode_b):
+ raise Exception("Not file")
+ if (mode_a & 0o777) != (mode_b & 0o777):
+ raise Exception("Permissions mismatch")
+ if not filecmp.cmp(path_a, path_b, shallow=False):
+ raise Exception("File contents mismatch")
+
+
+def verify_script(tmpd):
+ for (dirpath, dirnames, filenames) in os.walk("sys"):
+ try:
+ path = dirpath
+ verify_dir(tmpd, path)
+ for d in dirnames:
+ path = os.path.join(dirpath, d)
+ if stat.S_ISLNK(os.lstat(path).st_mode):
+ verify_link(tmpd, path)
+ for f in filenames:
+ path = os.path.join(dirpath, f)
+ mode = os.lstat(path).st_mode
+ if stat.S_ISLNK(mode):
+ verify_link(tmpd, path)
+ elif stat.S_ISREG(mode):
+ verify_file(tmpd, path)
+ except Exception:
+ print("FAIL on '{}'".format(path), file=sys.stderr)
+ raise
+
+
+if __name__ == "__main__":
+ # Always operate in the dir where this script is
+ os.chdir(os.path.dirname(sys.argv[0]))
+
+ if not os.path.isdir("sys"):
+ exit("No sys/ directory; please create before running this")
+
+ print("Creating {} using contents of sys/".format(OUTFILE))
+
+ with open(OUTFILE, "w") as f:
+ os.chmod(OUTFILE, OUTFILE_MODE)
+ f.write(OUTFILE_HEADER.replace(os.path.basename(sys.argv[0]), OUTFILE))
+ f.write(OUTFILE_FUNCS)
+ f.write(OUTFILE_MAIN)
+ process_sysdir(f)
+
+ with tempfile.TemporaryDirectory() as tmpd:
+ print("Recreating sys/ using {} at {}".format(OUTFILE, tmpd))
+ os.system("./{script} {tmpd}".format(script=OUTFILE, tmpd=tmpd))
+ verify_script(tmpd)
+
+ print("Verification successful, {} is correct".format(OUTFILE))
diff --git a/test/hwdb-test.sh b/test/hwdb-test.sh
new file mode 100755
index 0000000000..5373930df4
--- /dev/null
+++ b/test/hwdb-test.sh
@@ -0,0 +1,72 @@
+#!/bin/sh
+# call built systemd-hwdb update on our hwdb files to ensure that they parse
+# without error
+#
+# (C) 2016 Canonical Ltd.
+# Author: Martin Pitt <martin.pitt@ubuntu.com>
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+set -e
+
+ROOTDIR=$(dirname $(dirname $(readlink -f $0)))
+SYSTEMD_HWDB=${builddir:-.}/systemd-hwdb
+
+if [ ! -x "$SYSTEMD_HWDB" ]; then
+ echo "$SYSTEMD_HWDB does not exist, please build first"
+ exit 1
+fi
+
+D=$(mktemp --directory)
+trap "rm -rf '$D'" EXIT INT QUIT PIPE
+mkdir -p "$D/etc/udev"
+ln -s "$ROOTDIR/hwdb" "$D/etc/udev/hwdb.d"
+
+# Test "good" properties" — no warnings or errors allowed
+err=$("$SYSTEMD_HWDB" update --root "$D" 2>&1 >/dev/null) && rc= || rc=$?
+if [ -n "$err" ]; then
+ echo "$err"
+ exit ${rc:-1}
+fi
+if [ -n "$rc" ]; then
+ echo "$SYSTEMD_HWDB returned $rc"
+ exit $rc
+fi
+
+if [ ! -e "$D/etc/udev/hwdb.bin" ]; then
+ echo "$D/etc/udev/hwdb.bin was not generated"
+ exit 1
+fi
+
+# Test "bad" properties" — warnings required, errors not allowed
+rm -f "$D/etc/udev/hwdb.bin" "$D/etc/udev/hwdb.d"
+
+ln -s "$ROOTDIR/test/hwdb" "$D/etc/udev/hwdb.d"
+err=$("$SYSTEMD_HWDB" update --root "$D" 2>&1 >/dev/null) && rc= || rc=$?
+if [ -n "$rc" ]; then
+ echo "$SYSTEMD_HWDB returned $rc"
+ exit $rc
+fi
+if [ -n "$err" ]; then
+ echo "Expected warnings"
+ echo "$err"
+else
+ echo "$SYSTEMD_HWDB unexpectedly printed no warnings"
+ exit 1
+fi
+
+if [ ! -e "$D/etc/udev/hwdb.bin" ]; then
+ echo "$D/etc/udev/hwdb.bin was not generated"
+ exit 1
+fi
diff --git a/test/hwdb/10-bad.hwdb b/test/hwdb/10-bad.hwdb
new file mode 100644
index 0000000000..0e1e147323
--- /dev/null
+++ b/test/hwdb/10-bad.hwdb
@@ -0,0 +1,26 @@
+BAD:1:no properties
+
+BAD:2:no properties
+BAD:2:no properties
+
+BAD:3:no properties
+BAD:3:no properties
+BAD:3:no properties
+
+GOOD:5:bad property
+ NO_VALUE
+
+GOOD:6:bad property
+ =NO_NAME
+ NO_VALUE=
+
+BAD:7:match at wrong place
+ X=Y
+BAD:7:match at wrong place
+
+BAD:8:match at wrong place
+ X=Y
+BAD:8:match at wrong place
+ Z=z
+
+BAD:8:match at EOF
diff --git a/test/journal-data/journal-1.txt b/test/journal-data/journal-1.txt
new file mode 100644
index 0000000000..92a9199a93
--- /dev/null
+++ b/test/journal-data/journal-1.txt
Binary files differ
diff --git a/test/journal-data/journal-2.txt b/test/journal-data/journal-2.txt
new file mode 100644
index 0000000000..4f582a0e88
--- /dev/null
+++ b/test/journal-data/journal-2.txt
Binary files differ
diff --git a/test/networkd-test.py b/test/networkd-test.py
index 3091722fc1..e0dddeb053 100755
--- a/test/networkd-test.py
+++ b/test/networkd-test.py
@@ -30,6 +30,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+import errno
import os
import sys
import time
@@ -37,37 +38,131 @@ import unittest
import tempfile
import subprocess
import shutil
+import socket
-networkd_active = subprocess.call(['systemctl', 'is-active', '--quiet',
- 'systemd-networkd']) == 0
-have_dnsmasq = shutil.which('dnsmasq')
+HAVE_DNSMASQ = shutil.which('dnsmasq') is not None
+
+NETWORK_UNITDIR = '/run/systemd/network'
+
+NETWORKD_WAIT_ONLINE = shutil.which('systemd-networkd-wait-online',
+ path='/usr/lib/systemd:/lib/systemd')
RESOLV_CONF = '/run/systemd/resolve/resolv.conf'
-@unittest.skipIf(networkd_active,
- 'networkd is already active')
-class ClientTestBase:
+def setUpModule():
+ """Initialize the environment, and perform sanity checks on it."""
+ if NETWORKD_WAIT_ONLINE is None:
+ raise OSError(errno.ENOENT, 'systemd-networkd-wait-online not found')
+
+ # Do not run any tests if the system is using networkd already.
+ if subprocess.call(['systemctl', 'is-active', '--quiet',
+ 'systemd-networkd.service']) == 0:
+ raise unittest.SkipTest('networkd is already active')
+
+ # Avoid "Failed to open /dev/tty" errors in containers.
+ os.environ['SYSTEMD_LOG_TARGET'] = 'journal'
+
+ # Ensure the unit directory exists so tests can dump files into it.
+ os.makedirs(NETWORK_UNITDIR, exist_ok=True)
+
+
+class NetworkdTestingUtilities:
+ """Provide a set of utility functions to facilitate networkd tests.
+
+ This class must be inherited along with unittest.TestCase to define
+ some required methods.
+ """
+
+ def add_veth_pair(self, veth, peer, veth_options=(), peer_options=()):
+ """Add a veth interface pair, and queue them to be removed."""
+ subprocess.check_call(['ip', 'link', 'add', 'name', veth] +
+ list(veth_options) +
+ ['type', 'veth', 'peer', 'name', peer] +
+ list(peer_options))
+ self.addCleanup(subprocess.call, ['ip', 'link', 'del', 'dev', peer])
+
+ def write_network(self, unit_name, contents):
+ """Write a network unit file, and queue it to be removed."""
+ unit_path = os.path.join(NETWORK_UNITDIR, unit_name)
+
+ with open(unit_path, 'w') as unit:
+ unit.write(contents)
+ self.addCleanup(os.remove, unit_path)
+
+ def write_network_dropin(self, unit_name, dropin_name, contents):
+ """Write a network unit drop-in, and queue it to be removed."""
+ dropin_dir = os.path.join(NETWORK_UNITDIR, "%s.d" % unit_name)
+ dropin_path = os.path.join(dropin_dir, "%s.conf" % dropin_name)
+
+ os.makedirs(dropin_dir, exist_ok=True)
+ with open(dropin_path, 'w') as dropin:
+ dropin.write(contents)
+ self.addCleanup(os.remove, dropin_path)
+
+ def assert_link_states(self, **kwargs):
+ """Match networkctl link states to the given ones.
+
+ Each keyword argument should be the name of a network interface
+ with its expected value of the "SETUP" column in output from
+ networkctl. The interfaces have five seconds to come online
+ before the check is performed. Every specified interface must
+ be present in the output, and any other interfaces found in the
+ output are ignored.
+
+ A special interface state "managed" is supported, which matches
+ any value in the "SETUP" column other than "unmanaged".
+ """
+ if not kwargs:
+ return
+ interfaces = set(kwargs)
+
+ # Wait for the requested interfaces, but don't fail for them.
+ subprocess.call([NETWORKD_WAIT_ONLINE, '--timeout=5'] +
+ ['--interface=%s' % iface for iface in kwargs])
+
+ # Validate each link state found in the networkctl output.
+ out = subprocess.check_output(['networkctl', '--no-legend']).rstrip()
+ for line in out.decode('utf-8').split('\n'):
+ fields = line.split()
+ if len(fields) >= 5 and fields[1] in kwargs:
+ iface = fields[1]
+ expected = kwargs[iface]
+ actual = fields[-1]
+ if (actual != expected and
+ not (expected == 'managed' and actual != 'unmanaged')):
+ self.fail("Link %s expects state %s, found %s" %
+ (iface, expected, actual))
+ interfaces.remove(iface)
+
+ # Ensure that all requested interfaces have been covered.
+ if interfaces:
+ self.fail("Missing links in status output: %s" % interfaces)
+
+
+class ClientTestBase(NetworkdTestingUtilities):
+ """Provide common methods for testing networkd against servers."""
+
+ @classmethod
+ def setUpClass(klass):
+ klass.orig_log_level = subprocess.check_output(
+ ['systemctl', 'show', '--value', '--property', 'LogLevel'],
+ universal_newlines=True).strip()
+ subprocess.check_call(['systemd-analyze', 'set-log-level', 'debug'])
+
+ @classmethod
+ def tearDownClass(klass):
+ subprocess.check_call(['systemd-analyze', 'set-log-level', klass.orig_log_level])
+
def setUp(self):
self.iface = 'test_eth42'
self.if_router = 'router_eth42'
self.workdir_obj = tempfile.TemporaryDirectory()
self.workdir = self.workdir_obj.name
- self.config = '/run/systemd/network/test_eth42.network'
-
- # avoid "Failed to open /dev/tty" errors in containers
- os.environ['SYSTEMD_LOG_TARGET'] = 'journal'
-
- # determine path to systemd-networkd-wait-online
- for p in ['/usr/lib/systemd/systemd-networkd-wait-online',
- '/lib/systemd/systemd-networkd-wait-online']:
- if os.path.exists(p):
- self.networkd_wait_online = p
- break
- else:
- self.fail('systemd-networkd-wait-online not found')
+ self.config = 'test_eth42.network'
# get current journal cursor
+ subprocess.check_output(['journalctl', '--sync'])
out = subprocess.check_output(['journalctl', '-b', '--quiet',
'--no-pager', '-n0', '--show-cursor'],
universal_newlines=True)
@@ -77,17 +172,14 @@ class ClientTestBase:
def tearDown(self):
self.shutdown_iface()
subprocess.call(['systemctl', 'stop', 'systemd-networkd'])
-
- def writeConfig(self, fname, contents):
- os.makedirs(os.path.dirname(fname), exist_ok=True)
- with open(fname, 'w') as f:
- f.write(contents)
- self.addCleanup(os.remove, fname)
+ subprocess.call(['ip', 'link', 'del', 'dummy0'],
+ stderr=subprocess.DEVNULL)
def show_journal(self, unit):
'''Show journal of given unit since start of the test'''
print('---- %s ----' % unit)
+ subprocess.check_output(['journalctl', '--sync'])
sys.stdout.flush()
subprocess.call(['journalctl', '-b', '--no-pager', '--quiet',
'--cursor', self.journal_cursor, '-u', unit])
@@ -109,8 +201,12 @@ class ClientTestBase:
def do_test(self, coldplug=True, ipv6=False, extra_opts='',
online_timeout=10, dhcp_mode='yes'):
- subprocess.check_call(['systemctl', 'start', 'systemd-resolved'])
- self.writeConfig(self.config, '''\
+ try:
+ subprocess.check_call(['systemctl', 'start', 'systemd-resolved'])
+ except subprocess.CalledProcessError:
+ self.show_journal('systemd-resolved.service')
+ raise
+ self.write_network(self.config, '''\
[Match]
Name=%s
[Network]
@@ -121,20 +217,23 @@ DHCP=%s
# create interface first, then start networkd
self.create_iface(ipv6=ipv6)
subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
- else:
+ elif coldplug is not None:
# start networkd first, then create interface
subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
self.create_iface(ipv6=ipv6)
+ else:
+ # "None" means test sets up interface by itself
+ subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
try:
- subprocess.check_call([self.networkd_wait_online, '--interface',
+ subprocess.check_call([NETWORKD_WAIT_ONLINE, '--interface',
self.iface, '--timeout=%i' % online_timeout])
if ipv6:
# check iface state and IP 6 address; FIXME: we need to wait a bit
# longer, as the iface is "configured" already with IPv4 *or*
# IPv6, but we want to wait for both
- for timeout in range(10):
+ for _ in range(10):
out = subprocess.check_output(['ip', 'a', 'show', 'dev', self.iface])
if b'state UP' in out and b'inet6 2600' in out and b'inet 192.168' in out:
break
@@ -147,33 +246,33 @@ DHCP=%s
else:
# should have link-local address on IPv6 only
out = subprocess.check_output(['ip', '-6', 'a', 'show', 'dev', self.iface])
- self.assertRegex(out, b'inet6 fe80::.* scope link')
+ self.assertRegex(out, br'inet6 fe80::.* scope link')
self.assertNotIn(b'scope global', out)
# should have IPv4 address
out = subprocess.check_output(['ip', '-4', 'a', 'show', 'dev', self.iface])
self.assertIn(b'state UP', out)
- self.assertRegex(out, b'inet 192.168.5.\d+/.* scope global dynamic')
+ self.assertRegex(out, br'inet 192.168.5.\d+/.* scope global dynamic')
# check networkctl state
out = subprocess.check_output(['networkctl'])
- self.assertRegex(out, ('%s\s+ether\s+routable\s+unmanaged' % self.if_router).encode())
- self.assertRegex(out, ('%s\s+ether\s+routable\s+configured' % self.iface).encode())
+ self.assertRegex(out, (r'%s\s+ether\s+routable\s+unmanaged' % self.if_router).encode())
+ self.assertRegex(out, (r'%s\s+ether\s+routable\s+configured' % self.iface).encode())
out = subprocess.check_output(['networkctl', 'status', self.iface])
- self.assertRegex(out, b'Type:\s+ether')
- self.assertRegex(out, b'State:\s+routable.*configured')
- self.assertRegex(out, b'Address:\s+192.168.5.\d+')
+ self.assertRegex(out, br'Type:\s+ether')
+ self.assertRegex(out, br'State:\s+routable.*configured')
+ self.assertRegex(out, br'Address:\s+192.168.5.\d+')
if ipv6:
- self.assertRegex(out, b'2600::')
+ self.assertRegex(out, br'2600::')
else:
- self.assertNotIn(b'2600::', out)
- self.assertRegex(out, b'fe80::')
- self.assertRegex(out, b'Gateway:\s+192.168.5.1')
- self.assertRegex(out, b'DNS:\s+192.168.5.1')
+ self.assertNotIn(br'2600::', out)
+ self.assertRegex(out, br'fe80::')
+ self.assertRegex(out, br'Gateway:\s+192.168.5.1')
+ self.assertRegex(out, br'DNS:\s+192.168.5.1')
except (AssertionError, subprocess.CalledProcessError):
# show networkd status, journal, and DHCP server log on failure
- with open(self.config) as f:
+ with open(os.path.join(NETWORK_UNITDIR, self.config)) as f:
print('\n---- %s ----\n%s' % (self.config, f.read()))
print('---- interface status ----')
sys.stdout.flush()
@@ -194,7 +293,7 @@ DHCP=%s
else:
self.fail('nameserver 192.168.5.1 not found in ' + RESOLV_CONF)
- if not coldplug:
+ if coldplug is False:
# check post-down.d hook
self.shutdown_iface()
@@ -228,12 +327,12 @@ DHCP=%s
self.do_test(coldplug=False, ipv6=True)
def test_route_only_dns(self):
- self.writeConfig('/run/systemd/network/myvpn.netdev', '''\
+ self.write_network('myvpn.netdev', '''\
[NetDev]
Name=dummy0
Kind=dummy
MACAddress=12:34:56:78:9a:bc''')
- self.writeConfig('/run/systemd/network/myvpn.network', '''\
+ self.write_network('myvpn.network', '''\
[Match]
Name=dummy0
[Network]
@@ -254,20 +353,16 @@ Domains= ~company''')
self.assertNotIn('nameserver 192.168.42.1\n', contents)
def test_route_only_dns_all_domains(self):
- with open('/run/systemd/network/myvpn.netdev', 'w') as f:
- f.write('''[NetDev]
+ self.write_network('myvpn.netdev', '''[NetDev]
Name=dummy0
Kind=dummy
MACAddress=12:34:56:78:9a:bc''')
- with open('/run/systemd/network/myvpn.network', 'w') as f:
- f.write('''[Match]
+ self.write_network('myvpn.network', '''[Match]
Name=dummy0
[Network]
Address=192.168.42.100
DNS=192.168.42.1
Domains= ~company ~.''')
- self.addCleanup(os.remove, '/run/systemd/network/myvpn.netdev')
- self.addCleanup(os.remove, '/run/systemd/network/myvpn.network')
self.do_test(coldplug=True, ipv6=False,
extra_opts='IPv6AcceptRouterAdvertisements=False')
@@ -284,20 +379,22 @@ Domains= ~company ~.''')
self.assertIn('nameserver 192.168.42.1\n', contents)
-@unittest.skipUnless(have_dnsmasq, 'dnsmasq not installed')
+@unittest.skipUnless(HAVE_DNSMASQ, 'dnsmasq not installed')
class DnsmasqClientTest(ClientTestBase, unittest.TestCase):
'''Test networkd client against dnsmasq'''
def setUp(self):
super().setUp()
self.dnsmasq = None
+ self.iface_mac = 'de:ad:be:ef:47:11'
def create_iface(self, ipv6=False, dnsmasq_opts=None):
'''Create test interface with DHCP server behind it'''
# add veth pair
- subprocess.check_call(['ip', 'link', 'add', 'name', self.iface, 'type',
- 'veth', 'peer', 'name', self.if_router])
+ subprocess.check_call(['ip', 'link', 'add', 'name', self.iface,
+ 'address', self.iface_mac,
+ 'type', 'veth', 'peer', 'name', self.if_router])
# give our router an IP
subprocess.check_call(['ip', 'a', 'flush', 'dev', self.if_router])
@@ -345,7 +442,7 @@ class DnsmasqClientTest(ClientTestBase, unittest.TestCase):
# create interface for generic connections; this will map all DNS names
# to 192.168.42.1
self.create_iface(dnsmasq_opts=['--address=/#/192.168.42.1'])
- self.writeConfig('/run/systemd/network/general.network', '''\
+ self.write_network('general.network', '''\
[Match]
Name=%s
[Network]
@@ -354,9 +451,7 @@ IPv6AcceptRA=False''' % self.iface)
# create second device/dnsmasq for a .company/.lab VPN interface
# static IPs for simplicity
- subprocess.check_call(['ip', 'link', 'add', 'name', 'testvpnclient', 'type',
- 'veth', 'peer', 'name', 'testvpnrouter'])
- self.addCleanup(subprocess.call, ['ip', 'link', 'del', 'dev', 'testvpnrouter'])
+ self.add_veth_pair('testvpnclient', 'testvpnrouter')
subprocess.check_call(['ip', 'a', 'flush', 'dev', 'testvpnrouter'])
subprocess.check_call(['ip', 'a', 'add', '10.241.3.1/24', 'dev', 'testvpnrouter'])
subprocess.check_call(['ip', 'link', 'set', 'testvpnrouter', 'up'])
@@ -371,7 +466,7 @@ IPv6AcceptRA=False''' % self.iface)
self.addCleanup(vpn_dnsmasq.wait)
self.addCleanup(vpn_dnsmasq.kill)
- self.writeConfig('/run/systemd/network/vpn.network', '''\
+ self.write_network('vpn.network', '''\
[Match]
Name=testvpnclient
[Network]
@@ -381,7 +476,7 @@ DNS=10.241.3.1
Domains= ~company ~lab''')
subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
- subprocess.check_call([self.networkd_wait_online, '--interface', self.iface,
+ subprocess.check_call([NETWORKD_WAIT_ONLINE, '--interface', self.iface,
'--interface=testvpnclient', '--timeout=20'])
# ensure we start fresh with every test
@@ -406,13 +501,129 @@ Domains= ~company ~lab''')
# VPN domains should only be sent to VPN DNS
self.assertRegex(vpn_log, 'query.*math.lab')
self.assertRegex(vpn_log, 'query.*cantina.company')
- self.assertNotIn('lab', general_log)
- self.assertNotIn('company', general_log)
+ self.assertNotIn('.lab', general_log)
+ self.assertNotIn('.company', general_log)
# general domains should not be sent to the VPN DNS
self.assertRegex(general_log, 'query.*megasearch.net')
self.assertNotIn('megasearch.net', vpn_log)
+ def test_resolved_etc_hosts(self):
+ '''resolved queries to /etc/hosts'''
+
+ # FIXME: -t MX query fails with enabled DNSSEC (even when using
+ # the known negative trust anchor .internal instead of .example)
+ conf = '/run/systemd/resolved.conf.d/test-disable-dnssec.conf'
+ os.makedirs(os.path.dirname(conf), exist_ok=True)
+ with open(conf, 'w') as f:
+ f.write('[Resolve]\nDNSSEC=no')
+ self.addCleanup(os.remove, conf)
+
+ # create /etc/hosts bind mount which resolves my.example for IPv4
+ hosts = os.path.join(self.workdir, 'hosts')
+ with open(hosts, 'w') as f:
+ f.write('172.16.99.99 my.example\n')
+ subprocess.check_call(['mount', '--bind', hosts, '/etc/hosts'])
+ self.addCleanup(subprocess.call, ['umount', '/etc/hosts'])
+ subprocess.check_call(['systemctl', 'stop', 'systemd-resolved.service'])
+
+ # note: different IPv4 address here, so that it's easy to tell apart
+ # what resolved the query
+ self.create_iface(dnsmasq_opts=['--host-record=my.example,172.16.99.1,2600::99:99',
+ '--host-record=other.example,172.16.0.42,2600::42',
+ '--mx-host=example,mail.example'],
+ ipv6=True)
+ self.do_test(coldplug=None, ipv6=True)
+
+ try:
+ # family specific queries
+ out = subprocess.check_output(['systemd-resolve', '-4', 'my.example'])
+ self.assertIn(b'my.example: 172.16.99.99', out)
+ # we don't expect an IPv6 answer; if /etc/hosts has any IP address,
+ # it's considered a sufficient source
+ self.assertNotEqual(subprocess.call(['systemd-resolve', '-6', 'my.example']), 0)
+ # "any family" query; IPv4 should come from /etc/hosts
+ out = subprocess.check_output(['systemd-resolve', 'my.example'])
+ self.assertIn(b'my.example: 172.16.99.99', out)
+ # IP → name lookup; again, takes the /etc/hosts one
+ out = subprocess.check_output(['systemd-resolve', '172.16.99.99'])
+ self.assertIn(b'172.16.99.99: my.example', out)
+
+ # non-address RRs should fall back to DNS
+ out = subprocess.check_output(['systemd-resolve', '--type=MX', 'example'])
+ self.assertIn(b'example IN MX 1 mail.example', out)
+
+ # other domains query DNS
+ out = subprocess.check_output(['systemd-resolve', 'other.example'])
+ self.assertIn(b'172.16.0.42', out)
+ out = subprocess.check_output(['systemd-resolve', '172.16.0.42'])
+ self.assertIn(b'172.16.0.42: other.example', out)
+ except (AssertionError, subprocess.CalledProcessError):
+ self.show_journal('systemd-resolved.service')
+ self.print_server_log()
+ raise
+
+ def test_transient_hostname(self):
+ '''networkd sets transient hostname from DHCP'''
+
+ orig_hostname = socket.gethostname()
+ self.addCleanup(socket.sethostname, orig_hostname)
+ # temporarily move /etc/hostname away; restart hostnamed to pick it up
+ if os.path.exists('/etc/hostname'):
+ subprocess.check_call(['mount', '--bind', '/dev/null', '/etc/hostname'])
+ self.addCleanup(subprocess.call, ['umount', '/etc/hostname'])
+ subprocess.check_call(['systemctl', 'stop', 'systemd-hostnamed.service'])
+
+ self.create_iface(dnsmasq_opts=['--dhcp-host=%s,192.168.5.210,testgreen' % self.iface_mac])
+ self.do_test(coldplug=None, extra_opts='IPv6AcceptRA=False', dhcp_mode='ipv4')
+
+ try:
+ # should have received the fixed IP above
+ out = subprocess.check_output(['ip', '-4', 'a', 'show', 'dev', self.iface])
+ self.assertRegex(out, b'inet 192.168.5.210/24 .* scope global dynamic')
+ # should have set transient hostname in hostnamed; this is
+ # sometimes a bit lagging (issue #4753), so retry a few times
+ for retry in range(1, 6):
+ out = subprocess.check_output(['hostnamectl'])
+ if b'testgreen' in out:
+ break
+ time.sleep(5)
+ sys.stdout.write('[retry %i] ' % retry)
+ sys.stdout.flush()
+ else:
+ self.fail('Transient hostname not found in hostnamectl:\n%s' % out.decode())
+ # and also applied to the system
+ self.assertEqual(socket.gethostname(), 'testgreen')
+ except AssertionError:
+ self.show_journal('systemd-networkd.service')
+ self.show_journal('systemd-hostnamed.service')
+ self.print_server_log()
+ raise
+
+ def test_transient_hostname_with_static(self):
+ '''transient hostname is not applied if static hostname exists'''
+
+ orig_hostname = socket.gethostname()
+ self.addCleanup(socket.sethostname, orig_hostname)
+ if not os.path.exists('/etc/hostname'):
+ self.writeConfig('/etc/hostname', orig_hostname)
+ subprocess.check_call(['systemctl', 'stop', 'systemd-hostnamed.service'])
+
+ self.create_iface(dnsmasq_opts=['--dhcp-host=%s,192.168.5.210,testgreen' % self.iface_mac])
+ self.do_test(coldplug=None, extra_opts='IPv6AcceptRA=False', dhcp_mode='ipv4')
+
+ try:
+ # should have received the fixed IP above
+ out = subprocess.check_output(['ip', '-4', 'a', 'show', 'dev', self.iface])
+ self.assertRegex(out, b'inet 192.168.5.210/24 .* scope global dynamic')
+ # static hostname wins over transient one, thus *not* applied
+ self.assertEqual(socket.gethostname(), orig_hostname)
+ except AssertionError:
+ self.show_journal('systemd-networkd.service')
+ self.show_journal('systemd-hostnamed.service')
+ self.print_server_log()
+ raise
+
class NetworkdClientTest(ClientTestBase, unittest.TestCase):
'''Test networkd client against networkd server'''
@@ -421,7 +632,7 @@ class NetworkdClientTest(ClientTestBase, unittest.TestCase):
super().setUp()
self.dnsmasq = None
- def create_iface(self, ipv6=False):
+ def create_iface(self, ipv6=False, dhcpserver_opts=None):
'''Create test interface with DHCP server behind it'''
# run "router-side" networkd in own mount namespace to shield it from
@@ -459,11 +670,13 @@ DHCPServer=yes
PoolOffset=10
PoolSize=50
DNS=192.168.5.1
+%(dhopts)s
EOF
# run networkd as in systemd-networkd.service
exec $(systemctl cat systemd-networkd.service | sed -n '/^ExecStart=/ { s/^.*=//; p}')
-''' % {'ifr': self.if_router, 'ifc': self.iface, 'addr6': ipv6 and 'Address=2600::1/64' or ''})
+''' % {'ifr': self.if_router, 'ifc': self.iface, 'addr6': ipv6 and 'Address=2600::1/64' or '',
+ 'dhopts': dhcpserver_opts or ''})
os.fchmod(fd, 0o755)
@@ -474,7 +687,7 @@ exec $(systemctl cat systemd-networkd.service | sed -n '/^ExecStart=/ { s/^.*=//
'--service-type=notify', script])
# wait until devices got created
- for timeout in range(50):
+ for _ in range(50):
out = subprocess.check_output(['ip', 'a', 'show', 'dev', self.if_router])
if b'state UP' in out and b'scope global' in out:
break
@@ -508,12 +721,12 @@ exec $(systemctl cat systemd-networkd.service | sed -n '/^ExecStart=/ { s/^.*=//
# we don't use this interface for this test
self.if_router = None
- self.writeConfig('/run/systemd/network/test.netdev', '''\
+ self.write_network('test.netdev', '''\
[NetDev]
Name=dummy0
Kind=dummy
MACAddress=12:34:56:78:9a:bc''')
- self.writeConfig('/run/systemd/network/test.network', '''\
+ self.write_network('test.network', '''\
[Match]
Name=dummy0
[Network]
@@ -540,12 +753,12 @@ Domains= one two three four five six seven eight nine ten''')
name_prefix = 'a' * 60
- self.writeConfig('/run/systemd/network/test.netdev', '''\
+ self.write_network('test.netdev', '''\
[NetDev]
Name=dummy0
Kind=dummy
MACAddress=12:34:56:78:9a:bc''')
- self.writeConfig('/run/systemd/network/test.network', '''\
+ self.write_network('test.network', '''\
[Match]
Name=dummy0
[Network]
@@ -568,18 +781,18 @@ Domains={p}0 {p}1 {p}2 {p}3 {p}4'''.format(p=name_prefix))
# we don't use this interface for this test
self.if_router = None
- self.writeConfig('/run/systemd/network/test.netdev', '''\
+ self.write_network('test.netdev', '''\
[NetDev]
Name=dummy0
Kind=dummy
MACAddress=12:34:56:78:9a:bc''')
- self.writeConfig('/run/systemd/network/test.network', '''\
+ self.write_network('test.network', '''\
[Match]
Name=dummy0
[Network]
Address=192.168.42.100
DNS=192.168.42.1''')
- self.writeConfig('/run/systemd/network/test.network.d/dns.conf', '''\
+ self.write_network_dropin('test.network', 'dns', '''\
[Network]
DNS=127.0.0.1''')
@@ -594,6 +807,141 @@ DNS=127.0.0.1''')
self.assertIn('nameserver 192.168.42.1\n', contents)
self.assertIn('nameserver 127.0.0.1\n', contents)
+ def test_dhcp_timezone(self):
+ '''networkd sets time zone from DHCP'''
+
+ def get_tz():
+ out = subprocess.check_output(['busctl', 'get-property', 'org.freedesktop.timedate1',
+ '/org/freedesktop/timedate1', 'org.freedesktop.timedate1', 'Timezone'])
+ assert out.startswith(b's "')
+ out = out.strip()
+ assert out.endswith(b'"')
+ return out[3:-1].decode()
+
+ orig_timezone = get_tz()
+ self.addCleanup(subprocess.call, ['timedatectl', 'set-timezone', orig_timezone])
+
+ self.create_iface(dhcpserver_opts='EmitTimezone=yes\nTimezone=Pacific/Honolulu')
+ self.do_test(coldplug=None, extra_opts='IPv6AcceptRA=false\n[DHCP]\nUseTimezone=true', dhcp_mode='ipv4')
+
+ # should have applied the received timezone
+ try:
+ self.assertEqual(get_tz(), 'Pacific/Honolulu')
+ except AssertionError:
+ self.show_journal('systemd-networkd.service')
+ self.show_journal('systemd-hostnamed.service')
+ raise
+
+
+class MatchClientTest(unittest.TestCase, NetworkdTestingUtilities):
+ """Test [Match] sections in .network files.
+
+ Be aware that matching the test host's interfaces will wipe their
+ configuration, so as a precaution, all network files should have a
+ restrictive [Match] section to only ever interfere with the
+ temporary veth interfaces created here.
+ """
+
+ def tearDown(self):
+ """Stop networkd."""
+ subprocess.call(['systemctl', 'stop', 'systemd-networkd'])
+
+ def test_basic_matching(self):
+ """Verify the Name= line works throughout this class."""
+ self.add_veth_pair('test_if1', 'fake_if2')
+ self.write_network('test.network', "[Match]\nName=test_*\n[Network]")
+ subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
+ self.assert_link_states(test_if1='managed', fake_if2='unmanaged')
+
+ def test_inverted_matching(self):
+ """Verify that a '!'-prefixed value inverts the match."""
+ # Use a MAC address as the interfaces' common matching attribute
+ # to avoid depending on udev, to support testing in containers.
+ mac = '00:01:02:03:98:99'
+ self.add_veth_pair('test_veth', 'test_peer',
+ ['addr', mac], ['addr', mac])
+ self.write_network('no-veth.network', """\
+[Match]
+MACAddress=%s
+Name=!nonexistent *peer*
+[Network]""" % mac)
+ subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
+ self.assert_link_states(test_veth='managed', test_peer='unmanaged')
+
+
+class UnmanagedClientTest(unittest.TestCase, NetworkdTestingUtilities):
+ """Test if networkd manages the correct interfaces."""
+
+ def setUp(self):
+ """Write .network files to match the named veth devices."""
+ # Define the veth+peer pairs to be created.
+ # Their pairing doesn't actually matter, only their names do.
+ self.veths = {
+ 'm1def': 'm0unm',
+ 'm1man': 'm1unm',
+ }
+
+ # Define the contents of .network files to be read in order.
+ self.configs = (
+ "[Match]\nName=m1def\n",
+ "[Match]\nName=m1unm\n[Link]\nUnmanaged=yes\n",
+ "[Match]\nName=m1*\n[Link]\nUnmanaged=no\n",
+ )
+
+ # Write out the .network files to be cleaned up automatically.
+ for i, config in enumerate(self.configs):
+ self.write_network("%02d-test.network" % i, config)
+
+ def tearDown(self):
+ """Stop networkd."""
+ subprocess.call(['systemctl', 'stop', 'systemd-networkd'])
+
+ def create_iface(self):
+ """Create temporary veth pairs for interface matching."""
+ for veth, peer in self.veths.items():
+ self.add_veth_pair(veth, peer)
+
+ def test_unmanaged_setting(self):
+ """Verify link states with Unmanaged= settings, hot-plug."""
+ subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
+ self.create_iface()
+ self.assert_link_states(m1def='managed',
+ m1man='managed',
+ m1unm='unmanaged',
+ m0unm='unmanaged')
+
+ def test_unmanaged_setting_coldplug(self):
+ """Verify link states with Unmanaged= settings, cold-plug."""
+ self.create_iface()
+ subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
+ self.assert_link_states(m1def='managed',
+ m1man='managed',
+ m1unm='unmanaged',
+ m0unm='unmanaged')
+
+ def test_catchall_config(self):
+ """Verify link states with a catch-all config, hot-plug."""
+ # Don't actually catch ALL interfaces. It messes up the host.
+ self.write_network('all.network', "[Match]\nName=m[01]???\n")
+ subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
+ self.create_iface()
+ self.assert_link_states(m1def='managed',
+ m1man='managed',
+ m1unm='unmanaged',
+ m0unm='managed')
+
+ def test_catchall_config_coldplug(self):
+ """Verify link states with a catch-all config, cold-plug."""
+ # Don't actually catch ALL interfaces. It messes up the host.
+ self.write_network('all.network', "[Match]\nName=m[01]???\n")
+ self.create_iface()
+ subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
+ self.assert_link_states(m1def='managed',
+ m1man='managed',
+ m1unm='unmanaged',
+ m0unm='managed')
+
+
if __name__ == '__main__':
unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout,
verbosity=2))
diff --git a/test/rule-syntax-check.py b/test/rule-syntax-check.py
index e43a3daeb3..dab01f1d8a 100644..100755
--- a/test/rule-syntax-check.py
+++ b/test/rule-syntax-check.py
@@ -1,3 +1,4 @@
+#!/usr/bin/python3
# Simple udev rules syntax checker
#
# (C) 2010 Canonical Ltd.
@@ -33,10 +34,10 @@ else:
sys.exit(2)
rules_files = glob(os.path.join(rules_dir, '*.rules'))
-no_args_tests = re.compile('(ACTION|DEVPATH|KERNELS?|NAME|SYMLINK|SUBSYSTEMS?|DRIVERS?|TAG|RESULT|TEST)\s*(?:=|!)=\s*"([^"]*)"$')
-args_tests = re.compile('(ATTRS?|ENV|TEST){([a-zA-Z0-9/_.*%-]+)}\s*(?:=|!)=\s*"([^"]*)"$')
-no_args_assign = re.compile('(NAME|SYMLINK|OWNER|GROUP|MODE|TAG|PROGRAM|RUN|LABEL|GOTO|OPTIONS|IMPORT)\s*(?:\+=|:=|=)\s*"([^"]*)"$')
-args_assign = re.compile('(ATTR|ENV|IMPORT|RUN){([a-zA-Z0-9/_.*%-]+)}\s*(=|\+=)\s*"([^"]*)"$')
+no_args_tests = re.compile(r'(ACTION|DEVPATH|KERNELS?|NAME|SYMLINK|SUBSYSTEMS?|DRIVERS?|TAG|RESULT|TEST)\s*(?:=|!)=\s*"([^"]*)"$')
+args_tests = re.compile(r'(ATTRS?|ENV|TEST){([a-zA-Z0-9/_.*%-]+)}\s*(?:=|!)=\s*"([^"]*)"$')
+no_args_assign = re.compile(r'(NAME|SYMLINK|OWNER|GROUP|MODE|TAG|PROGRAM|RUN|LABEL|GOTO|OPTIONS|IMPORT)\s*(?:\+=|:=|=)\s*"([^"]*)"$')
+args_assign = re.compile(r'(ATTR|ENV|IMPORT|RUN){([a-zA-Z0-9/_.*%-]+)}\s*(=|\+=)\s*"([^"]*)"$')
result = 0
buffer = ''
diff --git a/test/sys-script.py b/test/sys-script.py
new file mode 100755
index 0000000000..a9c0046667
--- /dev/null
+++ b/test/sys-script.py
@@ -0,0 +1,16861 @@
+#!/usr/bin/python3
+#
+# sys-script.py
+#
+# (C) 2017 Canonical Ltd.
+# Author: Dan Streetman <dan.streetman@canonical.com>
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+#
+
+import os, sys
+
+def d(path, mode):
+ os.mkdir(path, mode)
+
+def l(path, src):
+ os.symlink(src, path)
+
+def f(path, mode, contents):
+ with open(path, "wb") as f:
+ f.write(contents)
+ os.chmod(path, mode)
+
+
+if len(sys.argv) < 2:
+ exit("Usage: {} <target dir>".format(sys.argv[0]))
+
+if not os.path.isdir(sys.argv[1]):
+ exit("Target dir {} not found".format(sys.argv[1]))
+
+os.chdir(sys.argv[1])
+
+d('sys', 0o755)
+d('sys/kernel', 0o775)
+f('sys/kernel/kexec_crash_loaded', 0o664, b'0\n')
+f('sys/kernel/kexec_loaded', 0o664, b'0\n')
+f('sys/kernel/uevent_helper', 0o664, b'\n')
+f('sys/kernel/vmcoreinfo', 0o664, b'f15380 1000\n')
+f('sys/kernel/notes', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00Z\r!\x804\xc2\x8atA<"f5(\xe7m\xe8-i-')
+f('sys/kernel/uevent_seqnum', 0o664, b'1407\n')
+d('sys/kernel/slab', 0o775)
+d('sys/kernel/slab/kmalloc-96', 0o775)
+f('sys/kernel/slab/kmalloc-96/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-96/ctor', 0o664, b'')
+f('sys/kernel/slab/kmalloc-96/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-96/slab_size', 0o664, b'168\n')
+f('sys/kernel/slab/kmalloc-96/total_objects', 0o664, b'768\n')
+f('sys/kernel/slab/kmalloc-96/slabs', 0o664, b'32\n')
+f('sys/kernel/slab/kmalloc-96/poison', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-96/alloc_calls', 0o664, b''' 5 sched_create_group+0x1f/0x220 age=8351870/8359354/8366881 pid=1333-2177 cpus=0-1
+ 10 __register_sysctl_paths+0x56/0x340 age=8370387/8378535/8379888 pid=1-901 cpus=0-1
+ 15 __create_workqueue_key+0x31/0x290 age=8370409/8377818/8380009 pid=1-900 cpus=0-1
+ 59 load_module+0x19c0/0x1b30 age=8303111/8368469/8376350 pid=105-2754 cpus=0-1
+ 5 __vmalloc_area_node+0xfb/0x140 age=8355400/8371519/8376226 pid=147-1813 cpus=0
+ 22 __register_chrdev_region+0x2d/0x1a0 age=8309177/8375269/8380004 pid=1-2711 cpus=0-1
+ 1 do_sys_poll+0xdb/0x450 age=9671 pid=2262 cpus=1
+ 98 d_alloc+0x19d/0x1f0 age=22395/7516545/8376320 pid=317-13453 cpus=0-1
+ 8 sys_eventfd2+0x51/0xb0 age=8339333/8339377/8339421 pid=2400 cpus=0
+ 1 mb_cache_create+0x62/0x1f0 age=8379846 pid=1 cpus=1
+ 9 sysfs_setattr+0x19a/0x1f0 age=61999/6511912/8377277 pid=63-13308 cpus=0-1
+ 1 sysfs_open_file+0x1c5/0x230 age=0 pid=13466 cpus=0
+ 17 copy_semundo+0x71/0xc0 age=3847042/8077586/8366263 pid=1370-2590 cpus=0-1
+ 2 __crypto_alloc_tfm+0x43/0x1b0 age=8373678/8373678/8373678 pid=126 cpus=1
+ 2 pcim_iomap_table+0x45/0x60 age=8379289/8379547/8379805 pid=1 cpus=0-1
+ 26 pci_create_attr+0x3d/0x140 age=8378994/8378994/8378995 pid=1 cpus=0
+ 8 pci_enable_msi+0xb1/0x2b0 age=8356336/8373963/8379844 pid=1-1541 cpus=0-1
+ 1 fb_add_videomode+0x89/0xf0 age=8379841 pid=1 cpus=1
+ 1 soft_cursor+0x92/0x220 age=8379841 pid=1 cpus=1
+ 20 acpi_os_create_semaphore+0x36/0xaa age=8379969/8380118/8380142 pid=0-1 cpus=0
+ 6 acpi_ds_build_internal_package_obj+0xaf/0x1df age=8379981/8379985/8379993 pid=1 cpus=0
+ 2 acpi_ds_build_internal_buffer_obj+0xe1/0x121 age=8379986/8379986/8379987 pid=1 cpus=0
+ 1 acpi_ev_create_gpe_block+0x5f/0x3bf age=8379999 pid=1 cpus=0
+ 62 pnp_new_resource+0x25/0x60 age=8379891/8379894/8379895 pid=1 cpus=0
+ 1 tty_register_driver+0x1b3/0x2a0 age=8379806 pid=1 cpus=1
+ 5 kbd_connect+0x4e/0xe0 age=8374352/8375743/8379035 pid=17-341 cpus=0-1
+ 17 __class_create+0x3d/0xa0 age=8374616/8377737/8380008 pid=1-215 cpus=0-1
+ 2 scsi_probe_and_add_lun+0x65e/0xd80 age=8379084/8379252/8379421 pid=1 cpus=0-1
+ 3 inet_rtm_newaddr+0xdb/0x220 age=8325560/8353789/8367912 pid=1197-1541 cpus=0-1
+ 2 cache_add_dev+0x7c/0x546 age=8379855/8379855/8379856 pid=1 cpus=0
+ 22 kernel_param_sysfs_setup+0x2f/0xc9 age=8380005/8380005/8380005 pid=1 cpus=0
+ 15 acpi_system_init+0x12e/0x260 age=8379898/8379898/8379899 pid=1 cpus=0
+ 1 pci_mmcfg_insert_resources+0x5d/0x123 age=8378994 pid=1 cpus=0
+ 1 0xffffffffa0065104 age=8356008 pid=1766 cpus=0
+ 1 bitmap_create+0x373/0xad0 [md_mod] age=8370145 pid=916 cpus=0
+ 256 r1bio_pool_alloc+0x2f/0x60 [raid1] age=8370154/8370154/8370154 pid=916 cpus=0
+ 8 ip6addrlbl_add+0x75/0x330 [ipv6] age=8360215/8360215/8360215 pid=1549 cpus=0
+ 1 ip6_route_net_init+0x22/0xd0 [ipv6] age=8360216 pid=1549 cpus=0
+ 6 snd_mixer_oss_build_input+0x431/0x5c0 [snd_mixer_oss] age=8355594/8355594/8355595 pid=1813 cpus=0
+''')
+f('sys/kernel/slab/kmalloc-96/objs_per_slab', 0o664, b'24\n')
+f('sys/kernel/slab/kmalloc-96/shrink', 0o664, b'')
+f('sys/kernel/slab/kmalloc-96/trace', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-96/object_size', 0o664, b'96\n')
+f('sys/kernel/slab/kmalloc-96/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-96/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-96/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-96/objects_partial', 0o664, b'95\n')
+f('sys/kernel/slab/kmalloc-96/objects', 0o664, b'743\n')
+f('sys/kernel/slab/kmalloc-96/order', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-96/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-96/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-96/align', 0o664, b'8\n')
+f('sys/kernel/slab/kmalloc-96/partial', 0o664, b'5\n')
+f('sys/kernel/slab/kmalloc-96/validate', 0o664, b'')
+f('sys/kernel/slab/kmalloc-96/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-96/free_calls', 0o664, b''' 507 <not-available> age=4303047439 pid=0 cpus=0
+ 1 free_notes_attrs+0x4b/0x50 age=8375086 pid=383 cpus=0
+ 1 audit_send_list+0x88/0xa0 age=8361087 pid=1538 cpus=1
+ 6 __vunmap+0xe9/0x120 age=8309178/8363011/8375091 pid=126-2711 cpus=0-1
+ 1 do_sys_poll+0x32b/0x450 age=9672 pid=2262 cpus=1
+ 30 d_callback+0x22/0x40 age=22587/7808930/8375651 pid=0-13433 cpus=0-1
+ 20 sysfs_release+0x63/0xa0 age=22407/6699376/8376561 pid=165-13453 cpus=0-1
+ 1 release_sysfs_dirent+0x22/0xd0 age=8367199 pid=1309 cpus=1
+ 116 free_rb_tree_fname+0x5c/0xb0 age=53501/7931736/8376455 pid=163-13373 cpus=0-1
+ 7 kobject_uevent_env+0x11a/0x470 age=67088/6542620/8379296 pid=1-419 cpus=0-1
+ 1 msi_free_irqs+0xad/0x110 age=8356355 pid=1541 cpus=0
+ 1 acpi_os_execute_deferred+0x34/0x39 age=8379958 pid=13 cpus=1
+ 1 acpi_walk_resources+0xa4/0xbd age=8379895 pid=1 cpus=0
+ 1 acpi_pci_irq_add_prt+0x30b/0x324 age=8379922 pid=1 cpus=0
+ 6 scsi_execute_req+0x9f/0xf0 age=8335607/8359788/8379422 pid=1-1456 cpus=0-1
+ 9 netlink_destroy_callback+0x21/0x30 age=8325561/8347615/8367913 pid=1197-2527 cpus=0-1
+ 12 huft_free+0x1e/0x2f age=8379857/8379857/8379857 pid=1 cpus=0
+ 2 r1bio_pool_free+0x9/0x10 [raid1] age=8364428/8364431/8364434 pid=0 cpus=0
+''')
+f('sys/kernel/slab/kmalloc-96/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/blkdev_requests', 0o775)
+f('sys/kernel/slab/blkdev_requests/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/blkdev_requests/ctor', 0o664, b'')
+f('sys/kernel/slab/blkdev_requests/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/blkdev_requests/slab_size', 0o664, b'376\n')
+f('sys/kernel/slab/blkdev_requests/total_objects', 0o664, b'84\n')
+f('sys/kernel/slab/blkdev_requests/slabs', 0o664, b'4\n')
+f('sys/kernel/slab/blkdev_requests/poison', 0o664, b'1\n')
+f('sys/kernel/slab/blkdev_requests/alloc_calls', 0o664, b' 12 mempool_alloc_slab+0x11/0x20 age=61529/5606309/8378864 pid=1-13295 cpus=0-1\n')
+f('sys/kernel/slab/blkdev_requests/objs_per_slab', 0o664, b'21\n')
+f('sys/kernel/slab/blkdev_requests/shrink', 0o664, b'')
+f('sys/kernel/slab/blkdev_requests/trace', 0o664, b'0\n')
+f('sys/kernel/slab/blkdev_requests/object_size', 0o664, b'304\n')
+f('sys/kernel/slab/blkdev_requests/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/blkdev_requests/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/blkdev_requests/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/blkdev_requests/objects_partial', 0o664, b'8\n')
+f('sys/kernel/slab/blkdev_requests/objects', 0o664, b'50\n')
+f('sys/kernel/slab/blkdev_requests/order', 0o664, b'1\n')
+f('sys/kernel/slab/blkdev_requests/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/blkdev_requests/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/blkdev_requests/align', 0o664, b'0\n')
+f('sys/kernel/slab/blkdev_requests/partial', 0o664, b'2\n')
+f('sys/kernel/slab/blkdev_requests/validate', 0o664, b'')
+f('sys/kernel/slab/blkdev_requests/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/blkdev_requests/free_calls', 0o664, b''' 7 <not-available> age=4303046881 pid=0 cpus=0
+ 5 mempool_free_slab+0x12/0x20 age=63050/1742015/8378750 pid=0-1456 cpus=0
+''')
+f('sys/kernel/slab/blkdev_requests/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/tw_sock_TCP', 0o775)
+f('sys/kernel/slab/tw_sock_TCP/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/tw_sock_TCP/ctor', 0o664, b'')
+f('sys/kernel/slab/tw_sock_TCP/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/tw_sock_TCP/slab_size', 0o664, b'256\n')
+f('sys/kernel/slab/tw_sock_TCP/total_objects', 0o664, b'16\n')
+f('sys/kernel/slab/tw_sock_TCP/slabs', 0o664, b'1\n')
+f('sys/kernel/slab/tw_sock_TCP/poison', 0o664, b'1\n')
+f('sys/kernel/slab/tw_sock_TCP/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/tw_sock_TCP/objs_per_slab', 0o664, b'16\n')
+f('sys/kernel/slab/tw_sock_TCP/shrink', 0o664, b'')
+f('sys/kernel/slab/tw_sock_TCP/trace', 0o664, b'0\n')
+f('sys/kernel/slab/tw_sock_TCP/object_size', 0o664, b'136\n')
+f('sys/kernel/slab/tw_sock_TCP/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/tw_sock_TCP/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/tw_sock_TCP/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/tw_sock_TCP/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/tw_sock_TCP/objects', 0o664, b'16\n')
+f('sys/kernel/slab/tw_sock_TCP/order', 0o664, b'0\n')
+f('sys/kernel/slab/tw_sock_TCP/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/tw_sock_TCP/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/tw_sock_TCP/align', 0o664, b'0\n')
+f('sys/kernel/slab/tw_sock_TCP/partial', 0o664, b'0\n')
+f('sys/kernel/slab/tw_sock_TCP/validate', 0o664, b'')
+f('sys/kernel/slab/tw_sock_TCP/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/tw_sock_TCP/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/tw_sock_TCP/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/Acpi-Parse', 0o775)
+f('sys/kernel/slab/Acpi-Parse/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Parse/ctor', 0o664, b'')
+f('sys/kernel/slab/Acpi-Parse/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Parse/slab_size', 0o664, b'120\n')
+f('sys/kernel/slab/Acpi-Parse/total_objects', 0o664, b'68\n')
+f('sys/kernel/slab/Acpi-Parse/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/Acpi-Parse/poison', 0o664, b'1\n')
+f('sys/kernel/slab/Acpi-Parse/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/Acpi-Parse/objs_per_slab', 0o664, b'34\n')
+f('sys/kernel/slab/Acpi-Parse/shrink', 0o664, b'')
+f('sys/kernel/slab/Acpi-Parse/trace', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Parse/object_size', 0o664, b'48\n')
+f('sys/kernel/slab/Acpi-Parse/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Parse/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Parse/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Parse/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Parse/objects', 0o664, b'68\n')
+f('sys/kernel/slab/Acpi-Parse/order', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Parse/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/Acpi-Parse/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/Acpi-Parse/align', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Parse/partial', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Parse/validate', 0o664, b'')
+f('sys/kernel/slab/Acpi-Parse/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/Acpi-Parse/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/Acpi-Parse/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/sgpool-8', 0o775)
+f('sys/kernel/slab/sgpool-8/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-8/ctor', 0o664, b'')
+f('sys/kernel/slab/sgpool-8/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-8/slab_size', 0o664, b'384\n')
+f('sys/kernel/slab/sgpool-8/total_objects', 0o664, b'42\n')
+f('sys/kernel/slab/sgpool-8/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/sgpool-8/poison', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-8/alloc_calls', 0o664, b' 2 mempool_alloc_slab+0x11/0x20 age=8379297/8379297/8379297 pid=1 cpus=0\n')
+f('sys/kernel/slab/sgpool-8/objs_per_slab', 0o664, b'21\n')
+f('sys/kernel/slab/sgpool-8/shrink', 0o664, b'')
+f('sys/kernel/slab/sgpool-8/trace', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-8/object_size', 0o664, b'256\n')
+f('sys/kernel/slab/sgpool-8/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-8/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-8/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-8/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-8/objects', 0o664, b'42\n')
+f('sys/kernel/slab/sgpool-8/order', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-8/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-8/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-8/align', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-8/partial', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-8/validate', 0o664, b'')
+f('sys/kernel/slab/sgpool-8/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-8/free_calls', 0o664, b' 2 <not-available> age=4303046847 pid=0 cpus=0\n')
+f('sys/kernel/slab/sgpool-8/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/dnotify_cache', 0o775)
+f('sys/kernel/slab/dnotify_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/dnotify_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/dnotify_cache/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/dnotify_cache/slab_size', 0o664, b'112\n')
+f('sys/kernel/slab/dnotify_cache/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/dnotify_cache/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/dnotify_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/dnotify_cache/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/dnotify_cache/objs_per_slab', 0o664, b'36\n')
+f('sys/kernel/slab/dnotify_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/dnotify_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/dnotify_cache/object_size', 0o664, b'40\n')
+f('sys/kernel/slab/dnotify_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/dnotify_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/dnotify_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/dnotify_cache/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/dnotify_cache/objects', 0o664, b'0\n')
+f('sys/kernel/slab/dnotify_cache/order', 0o664, b'0\n')
+f('sys/kernel/slab/dnotify_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/dnotify_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/dnotify_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/dnotify_cache/partial', 0o664, b'0\n')
+f('sys/kernel/slab/dnotify_cache/validate', 0o664, b'')
+f('sys/kernel/slab/dnotify_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/dnotify_cache/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/dnotify_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/kmalloc-16', 0o775)
+f('sys/kernel/slab/kmalloc-16/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-16/ctor', 0o664, b'')
+f('sys/kernel/slab/kmalloc-16/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-16/slab_size', 0o664, b'88\n')
+f('sys/kernel/slab/kmalloc-16/total_objects', 0o664, b'2254\n')
+f('sys/kernel/slab/kmalloc-16/slabs', 0o664, b'49\n')
+f('sys/kernel/slab/kmalloc-16/poison', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-16/alloc_calls', 0o664, b''' 2 arch_acpi_processor_init_pdc+0x71/0x180 age=8375737/8375768/8375799 pid=330 cpus=0
+ 2 arch_acpi_processor_init_pdc+0xab/0x180 age=8375737/8375768/8375799 pid=330 cpus=0
+ 5 sched_create_group+0x40/0x220 age=8351840/8359324/8366851 pid=1333-2177 cpus=0-1
+ 5 sched_create_group+0x62/0x220 age=8351840/8359324/8366851 pid=1333-2177 cpus=0-1
+ 2 setup_modinfo_version+0x19/0x30 age=8374630/8375434/8376238 pid=122-126 cpus=0-1
+ 365 load_module+0x1ac4/0x1b30 age=8303081/8369498/8376320 pid=105-2754 cpus=0-1
+ 13 mempool_create_node+0x4b/0xf0 age=8379859/8379929/8379974 pid=1 cpus=0
+ 1 krealloc+0x1e/0x60 age=8375802 pid=330 cpus=0
+ 4 __vmalloc_area_node+0xfb/0x140 age=8374701/8375120/8375833 pid=126-392 cpus=0
+ 7 alloc_vfsmnt+0x97/0x180 age=61473/7184623/8379853 pid=1-13348 cpus=0-1
+ 2 proc_symlink+0x4d/0xb0 age=8380112/8380112/8380112 pid=0 cpus=0
+ 1275 sysfs_new_dirent+0x10c/0x120 age=22645/7761348/8379979 pid=1-13295 cpus=0-1
+ 2 ext3_fill_super+0x691/0x1a20 age=8369671/8374021/8378371 pid=1-962 cpus=0
+ 406 kvasprintf+0x55/0x90 age=22645/7760583/8380112 pid=0-13295 cpus=0-1
+ 1 bit_cursor+0x223/0x6a0 age=8356170 pid=7 cpus=0
+ 12 acpi_ds_build_internal_package_obj+0xaf/0x1df age=8379944/8379946/8379954 pid=1 cpus=0
+ 14 acpi_ds_build_internal_buffer_obj+0xe1/0x121 age=8379945/8379955/8379961 pid=1 cpus=0
+ 2 acpi_ut_copy_simple_object+0x8f/0x11c age=8375657/8375665/8375674 pid=396 cpus=0
+ 5 acpi_irq_stats_init+0x1bd/0x268 age=8379969/8379969/8379969 pid=1 cpus=0
+ 14 pnp_add_id+0x1e/0xe0 age=8379861/8379863/8379866 pid=1 cpus=0
+ 9 reserve_range+0x39/0x130 age=8379850/8379850/8379850 pid=1 cpus=0
+ 1 trackpoint_detect+0x94/0x190 age=8378732 pid=17 cpus=0
+ 2 proto_register+0xf2/0x260 age=8360199/8370021/8379844 pid=1-1549 cpus=0
+ 2 neigh_sysctl_register+0x1cd/0x330 age=8360183/8366975/8373768 pid=126-1549 cpus=0-1
+ 1 nl_pid_hash_rehash+0x180/0x1a0 age=8361057 pid=1533 cpus=0
+ 1 genl_register_family+0x1b6/0x1e0 age=8379853 pid=1 cpus=0
+ 1 __devinet_sysctl_register+0xb8/0x120 age=8373768 pid=126 cpus=1
+ 1 pci_acpi_scan_root+0x3f/0x230 age=8379897 pid=1 cpus=0
+ 1 acpi_parse_mcfg+0x61/0x140 age=8379976 pid=1 cpus=0
+ 1 pci_mmcfg_arch_init+0x26/0x129 age=8379976 pid=1 cpus=0
+ 1 icmp_sk_init+0x32/0x13f age=8379826 pid=1 cpus=0
+ 5 hub_probe+0x26b/0x820 [usbcore] age=8374065/8374558/8374911 pid=143-147 cpus=0-1
+ 12 usb_cache_string+0x65/0xa0 [usbcore] age=22646/4900582/8374931 pid=143-419 cpus=0-1
+ 1 usb_create_ep_files+0x283/0x350 [usbcore] age=8374798 pid=143 cpus=0
+ 1 0xffffffffa006595f age=8360191 pid=1549 cpus=0
+ 13 snd_info_create_entry+0x30/0xa0 [snd] age=8355564/8372743/8374175 pid=107-1813 cpus=0-1
+ 1 snd_oss_info_register+0x40/0xc0 [snd] age=8374813 pid=107 cpus=1
+ 1 async_chainiv_givencrypt+0xf9/0x110 [crypto_blkcipher] age=8374570 pid=215 cpus=0
+ 1 eseqiv_alloc+0x6d/0x80 [crypto_blkcipher] age=8374570 pid=215 cpus=0
+ 1 run+0xa9/0x500 [raid1] age=8370124 pid=916 cpus=0
+ 1 __addrconf_sysctl_register+0xcd/0x140 [ipv6] age=8360183 pid=1549 cpus=0
+''')
+f('sys/kernel/slab/kmalloc-16/objs_per_slab', 0o664, b'46\n')
+f('sys/kernel/slab/kmalloc-16/shrink', 0o664, b'')
+f('sys/kernel/slab/kmalloc-16/trace', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-16/object_size', 0o664, b'16\n')
+f('sys/kernel/slab/kmalloc-16/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-16/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-16/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-16/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-16/objects', 0o664, b'2254\n')
+f('sys/kernel/slab/kmalloc-16/order', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-16/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-16/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-16/align', 0o664, b'8\n')
+f('sys/kernel/slab/kmalloc-16/partial', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-16/validate', 0o664, b'')
+f('sys/kernel/slab/kmalloc-16/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-16/free_calls', 0o664, b''' 1912 <not-available> age=4303047409 pid=0 cpus=0
+ 2 free_sched_group+0x62/0x80 age=8375109/8375395/8375681 pid=0-72 cpus=0-1
+ 2 free_sched_group+0x6b/0x80 age=8375109/8375395/8375681 pid=0-72 cpus=0-1
+ 3 free_sect_attrs+0x2e/0x50 age=8375055/8375055/8375055 pid=383 cpus=0
+ 3 __vunmap+0xe9/0x120 age=8373650/8374619/8375152 pid=181-754 cpus=0
+ 7 vfs_rename+0x301/0x450 age=125333/5028818/8367033 pid=829-13249 cpus=0
+ 10 bio_free_map_data+0x14/0x30 age=23581/2550049/8379364 pid=0-1738 cpus=0-1
+ 10 bio_free_map_data+0x1d/0x30 age=53581/4218001/8379379 pid=0-558 cpus=0-1
+ 60 remove_kevent+0x44/0x60 age=61364/3011504/8354072 pid=1547-2544 cpus=0-1
+ 49 release_sysfs_dirent+0x8c/0xd0 age=7824392/8263442/8379778 pid=1-2141 cpus=0-1
+ 9 kobject_release+0xe1/0x140 age=7833231/8247578/8373891 pid=419-1541 cpus=0-1
+ 70 kobject_uevent_env+0x11a/0x470 age=409229/8261185/8379979 pid=1-12942 cpus=0-1
+ 2 bit_cursor+0x23b/0x6a0 age=8356171/8367984/8379797 pid=1-7 cpus=0-1
+ 1 acpi_ds_create_operand+0x12c/0x209 age=8379867 pid=1 cpus=0
+ 2 acpi_ns_get_node+0x92/0xa1 age=8374467/8374504/8374542 pid=215 cpus=0-1
+ 8 acpi_ut_delete_internal_obj+0x15f/0x16f age=8366439/8374588/8375781 pid=330-1358 cpus=0
+ 16 acpi_ut_delete_internal_object_list+0x28/0x2f age=8374469/8378935/8379920 pid=1-396 cpus=0
+ 2 reserve_range+0x11d/0x130 age=8379851/8379851/8379851 pid=1 cpus=0
+ 3 release_firmware+0x57/0x70 age=8356214/8363521/8367182 pid=1285-1541 cpus=0-1
+ 8 module_add_driver+0x66/0xd0 age=8373538/8375876/8379266 pid=1-181 cpus=0-1
+ 1 power_supply_uevent+0x1a0/0x210 age=8375647 pid=7 cpus=0
+ 2 get_modalias+0xd4/0x120 age=8355835/8367906/8379977 pid=1-1772 cpus=0
+ 1 nl_pid_hash_rehash+0x18e/0x1a0 age=8356437 pid=1708 cpus=0
+ 2 fib_hash_free+0x35/0x40 age=8367899/8367899/8367899 pid=1185 cpus=0
+ 2 wireless_send_event+0x172/0x330 age=8329605/8342854/8356103 pid=1545 cpus=0-1
+ 10 usb_get_configuration+0x42d/0x1480 [usbcore] age=22733/6708190/8374932 pid=143-419 cpus=0-1
+''')
+f('sys/kernel/slab/kmalloc-16/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/filp', 0o775)
+f('sys/kernel/slab/filp/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/filp/ctor', 0o664, b'')
+f('sys/kernel/slab/filp/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/filp/slab_size', 0o664, b'384\n')
+f('sys/kernel/slab/filp/total_objects', 0o664, b'4158\n')
+f('sys/kernel/slab/filp/slabs', 0o664, b'198\n')
+f('sys/kernel/slab/filp/poison', 0o664, b'1\n')
+f('sys/kernel/slab/filp/alloc_calls', 0o664, b' 4081 get_empty_filp+0x44/0x1a0 age=0/7917861/8378089 pid=1-20296 cpus=0-1\n')
+f('sys/kernel/slab/filp/objs_per_slab', 0o664, b'21\n')
+f('sys/kernel/slab/filp/shrink', 0o664, b'')
+f('sys/kernel/slab/filp/trace', 0o664, b'0\n')
+f('sys/kernel/slab/filp/object_size', 0o664, b'288\n')
+f('sys/kernel/slab/filp/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/filp/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/filp/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/filp/objects_partial', 0o664, b'685\n')
+f('sys/kernel/slab/filp/objects', 0o664, b'4064\n')
+f('sys/kernel/slab/filp/order', 0o664, b'1\n')
+f('sys/kernel/slab/filp/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/filp/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/filp/align', 0o664, b'0\n')
+f('sys/kernel/slab/filp/partial', 0o664, b'33\n')
+f('sys/kernel/slab/filp/validate', 0o664, b'')
+f('sys/kernel/slab/filp/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/filp/free_calls', 0o664, b''' 866 <not-available> age=4303047162 pid=0 cpus=0
+ 3217 file_free_rcu+0x16/0x20 age=10/7799670/8377025 pid=0-20296 cpus=0-1
+''')
+f('sys/kernel/slab/filp/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/kmalloc-2048', 0o775)
+f('sys/kernel/slab/kmalloc-2048/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-2048/ctor', 0o664, b'')
+f('sys/kernel/slab/kmalloc-2048/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-2048/slab_size', 0o664, b'2120\n')
+f('sys/kernel/slab/kmalloc-2048/total_objects', 0o664, b'600\n')
+f('sys/kernel/slab/kmalloc-2048/slabs', 0o664, b'40\n')
+f('sys/kernel/slab/kmalloc-2048/poison', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-2048/alloc_calls', 0o664, b''' 53 load_module+0x18d5/0x1b30 age=8303006/8368517/8376245 pid=105-2754 cpus=0-1
+ 1 mempool_create_node+0x4b/0xf0 age=8370049 pid=916 cpus=0
+ 20 sget+0xc4/0x460 age=61397/7958673/8380037 pid=0-13348 cpus=0-1
+ 15 alloc_fdtable+0x81/0x160 age=4219/6197046/8357231 pid=1532-12336 cpus=0-1
+ 2 journal_init_common+0x1a/0x130 age=8369592/8373942/8378292 pid=1-962 cpus=0
+ 15 alloc_disk_node+0x1b/0x120 age=61949/7263912/8379312 pid=1-13295 cpus=0-1
+ 1 pci_create_bus+0x3a/0x240 age=8379822 pid=1 cpus=0
+ 21 alloc_pci_dev+0x1a/0x40 age=8379818/8379820/8379822 pid=1 cpus=0
+ 1 framebuffer_alloc+0x3a/0x80 age=8379737 pid=1 cpus=1
+ 74 acpi_add_single_object+0x4e/0xd3c age=8379823/8379836/8379852 pid=1 cpus=0
+ 1 acpi_irq_stats_init+0xcb/0x268 age=8379894 pid=1 cpus=0
+ 11 pnp_alloc_dev+0x35/0x120 age=8379786/8379789/8379791 pid=1 cpus=0
+ 11 init_dev+0x12e/0x6f0 age=7217110/8250882/8378132 pid=33-2593 cpus=0-1
+ 3 init_dev+0x2aa/0x6f0 age=7217110/7969221/8364310 pid=1258-2593 cpus=0-1
+ 1 tty_register_driver+0x1b3/0x2a0 age=8379706 pid=1 cpus=1
+ 2 tty_write+0x160/0x280 age=913316/4463710/8014104 pid=1206-3110 cpus=0
+ 2 kobj_map_init+0x22/0xa0 age=8379899/8379968/8380037 pid=0-1 cpus=0
+ 3 mousedev_create+0x36/0x2d0 age=53460/5603607/8378947 pid=1-419 cpus=0
+ 1 atkbd_connect+0x33/0x290 age=8378940 pid=17 cpus=1
+ 2 thermal_zone_device_register+0x6f/0x310 age=8374790/8374807/8374825 pid=329 cpus=0-1
+ 15 sk_prot_alloc+0x83/0xb0 age=8328308/8367505/8379903 pid=1-2586 cpus=0-1
+ 1 reqsk_queue_alloc+0x112/0x120 age=8356786 pid=1690 cpus=0
+ 255 __netdev_alloc_skb+0x1f/0x40 age=8356300/8356301/8356303 pid=1541 cpus=0
+ 10 neigh_sysctl_register+0x8d/0x330 age=8360107/8368337/8379760 pid=1-1549 cpus=0-1
+ 6 __devinet_sysctl_register+0x74/0x120 age=8373573/8377097/8379760 pid=1-126 cpus=0-1
+ 7 pci_add_new_bus+0x25/0x160 age=8379818/8379818/8379820 pid=1 cpus=0
+ 1 i8042_create_aux_port+0x36/0x10f age=8378959 pid=1 cpus=0
+ 1 i8042_probe+0x190/0x68d age=8378959 pid=1 cpus=0
+ 1 netdev_init+0x32/0xc2 age=8379782 pid=1 cpus=0
+ 1 netdev_init+0x66/0xc2 age=8379782 pid=1 cpus=0
+ 1 fib_net_init+0x21/0x14c age=8379760 pid=1 cpus=0
+ 10 usb_alloc_dev+0x36/0x2c0 [usbcore] age=22875/5876181/8374868 pid=143-419 cpus=0-1
+ 2 acpi_thermal_add+0x36/0x4bb [thermal] age=8374792/8374809/8374827 pid=329 cpus=0-1
+ 5 evdev_open+0xaf/0x1e0 [evdev] age=8364377/8364927/8365226 pid=1443 cpus=0-1
+ 8 evdev_connect+0x54/0x1f0 [evdev] age=53452/7334685/8375002 pid=187-419 cpus=0-1
+ 1 rtc_device_register+0xa4/0x260 [rtc_core] age=8374707 pid=208 cpus=0
+ 1 iwl3945_bg_request_scan+0x5d3/0x660 [iwl3945] age=8356027 pid=733 cpus=0
+ 1 iwl3945_pci_probe+0xd26/0x1020 [iwl3945] age=8373700 pid=126 cpus=1
+ 1 patch_ad1981+0x1b/0x1d0 [snd_hda_intel] age=8374101 pid=107 cpus=1
+ 1 rfkill_allocate+0x24/0xc0 [rfkill] age=8374401 pid=215 cpus=0
+ 1 fuse_fill_super+0x26d/0x6d0 [fuse] age=8335736 pid=2476 cpus=0
+''')
+f('sys/kernel/slab/kmalloc-2048/objs_per_slab', 0o664, b'15\n')
+f('sys/kernel/slab/kmalloc-2048/shrink', 0o664, b'')
+f('sys/kernel/slab/kmalloc-2048/trace', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-2048/object_size', 0o664, b'2048\n')
+f('sys/kernel/slab/kmalloc-2048/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-2048/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-2048/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-2048/objects_partial', 0o664, b'59\n')
+f('sys/kernel/slab/kmalloc-2048/objects', 0o664, b'584\n')
+f('sys/kernel/slab/kmalloc-2048/order', 0o664, b'3\n')
+f('sys/kernel/slab/kmalloc-2048/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-2048/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-2048/align', 0o664, b'8\n')
+f('sys/kernel/slab/kmalloc-2048/partial', 0o664, b'5\n')
+f('sys/kernel/slab/kmalloc-2048/validate', 0o664, b'')
+f('sys/kernel/slab/kmalloc-2048/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-2048/free_calls', 0o664, b''' 424 <not-available> age=4303047334 pid=0 cpus=0
+ 1 __vunmap+0xe9/0x120 age=8374513 pid=107 cpus=1
+ 79 free_fdtable_rcu+0x71/0xb0 age=7254/7749386/8377555 pid=0-13365 cpus=0-1
+ 4 show_stat+0x50e/0x530 age=23516/2125165/8360113 pid=1258-1868 cpus=0
+ 4 acpi_add_single_object+0xc9a/0xd3c age=8379824/8379831/8379839 pid=1 cpus=0
+ 20 release_one_tty+0x145/0x190 age=8352386/8360775/8370275 pid=55-2136 cpus=0-1
+ 1 atkbd_connect+0x1ae/0x290 age=8378923 pid=17 cpus=0
+ 8 sk_free+0xcd/0x100 age=656267/7395001/8360982 pid=1533-12333 cpus=0-1
+ 18 skb_release_data+0x85/0xd0 age=61516/7352252/8379750 pid=1-13343 cpus=0-1
+ 5 __scm_destroy+0x41/0x50 age=7217111/8111550/8352414 pid=2135-2593 cpus=0-1
+ 1 huft_build+0x163/0x63e age=8379752 pid=1 cpus=0
+ 1 inflate_fixed+0x17c/0x193 age=8379752 pid=1 cpus=0
+ 1 usb_release_dev+0x59/0x70 [usbcore] age=53835 pid=419 cpus=0
+ 1 acpi_processor_get_throttling_info+0x2e4/0x58c [processor] age=8375644 pid=330 cpus=0
+ 1 acpi_thermal_add+0x457/0x4bb [thermal] age=8374828 pid=329 cpus=1
+ 1 snd_ctl_ioctl+0x2cf/0x960 [snd] age=8373099 pid=786 cpus=0
+''')
+f('sys/kernel/slab/kmalloc-2048/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/cfq_queue', 0o775)
+f('sys/kernel/slab/cfq_queue/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/cfq_queue/ctor', 0o664, b'')
+f('sys/kernel/slab/cfq_queue/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/cfq_queue/slab_size', 0o664, b'208\n')
+f('sys/kernel/slab/cfq_queue/total_objects', 0o664, b'95\n')
+f('sys/kernel/slab/cfq_queue/slabs', 0o664, b'5\n')
+f('sys/kernel/slab/cfq_queue/poison', 0o664, b'1\n')
+f('sys/kernel/slab/cfq_queue/alloc_calls', 0o664, b' 67 cfq_get_queue+0xc6/0x220 age=168/7825503/8379604 pid=1-13466 cpus=0-1\n')
+f('sys/kernel/slab/cfq_queue/objs_per_slab', 0o664, b'19\n')
+f('sys/kernel/slab/cfq_queue/shrink', 0o664, b'')
+f('sys/kernel/slab/cfq_queue/trace', 0o664, b'0\n')
+f('sys/kernel/slab/cfq_queue/object_size', 0o664, b'136\n')
+f('sys/kernel/slab/cfq_queue/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/cfq_queue/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/cfq_queue/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/cfq_queue/objects_partial', 0o664, b'35\n')
+f('sys/kernel/slab/cfq_queue/objects', 0o664, b'92\n')
+f('sys/kernel/slab/cfq_queue/order', 0o664, b'0\n')
+f('sys/kernel/slab/cfq_queue/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/cfq_queue/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/cfq_queue/align', 0o664, b'8\n')
+f('sys/kernel/slab/cfq_queue/partial', 0o664, b'2\n')
+f('sys/kernel/slab/cfq_queue/validate', 0o664, b'')
+f('sys/kernel/slab/cfq_queue/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/cfq_queue/free_calls', 0o664, b''' 11 <not-available> age=4303047621 pid=0 cpus=0
+ 56 cfq_put_queue+0x6f/0xe0 age=45755/7905388/8375272 pid=163-26529 cpus=0-1
+''')
+f('sys/kernel/slab/cfq_queue/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/ext3_xattr', 0o775)
+f('sys/kernel/slab/ext3_xattr/reclaim_account', 0o664, b'1\n')
+f('sys/kernel/slab/ext3_xattr/ctor', 0o664, b'')
+f('sys/kernel/slab/ext3_xattr/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/ext3_xattr/slab_size', 0o664, b'160\n')
+f('sys/kernel/slab/ext3_xattr/total_objects', 0o664, b'25\n')
+f('sys/kernel/slab/ext3_xattr/slabs', 0o664, b'1\n')
+f('sys/kernel/slab/ext3_xattr/poison', 0o664, b'1\n')
+f('sys/kernel/slab/ext3_xattr/alloc_calls', 0o664, b' 4 mb_cache_entry_alloc+0x15/0x50 age=5766034/7671829/8319899 pid=2676-9046 cpus=0\n')
+f('sys/kernel/slab/ext3_xattr/objs_per_slab', 0o664, b'25\n')
+f('sys/kernel/slab/ext3_xattr/shrink', 0o664, b'')
+f('sys/kernel/slab/ext3_xattr/trace', 0o664, b'0\n')
+f('sys/kernel/slab/ext3_xattr/object_size', 0o664, b'88\n')
+f('sys/kernel/slab/ext3_xattr/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/ext3_xattr/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/ext3_xattr/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/ext3_xattr/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/ext3_xattr/objects', 0o664, b'25\n')
+f('sys/kernel/slab/ext3_xattr/order', 0o664, b'0\n')
+f('sys/kernel/slab/ext3_xattr/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/ext3_xattr/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/ext3_xattr/align', 0o664, b'0\n')
+f('sys/kernel/slab/ext3_xattr/partial', 0o664, b'0\n')
+f('sys/kernel/slab/ext3_xattr/validate', 0o664, b'')
+f('sys/kernel/slab/ext3_xattr/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/ext3_xattr/free_calls', 0o664, b' 4 <not-available> age=4303047503 pid=0 cpus=0\n')
+f('sys/kernel/slab/ext3_xattr/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/bio', 0o775)
+f('sys/kernel/slab/bio/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/bio/ctor', 0o664, b'')
+f('sys/kernel/slab/bio/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/bio/slab_size', 0o664, b'192\n')
+f('sys/kernel/slab/bio/total_objects', 0o664, b'42\n')
+f('sys/kernel/slab/bio/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/bio/poison', 0o664, b'1\n')
+f('sys/kernel/slab/bio/alloc_calls', 0o664, b' 2 mempool_alloc_slab+0x11/0x20 age=8379518/8379518/8379518 pid=1 cpus=0\n')
+f('sys/kernel/slab/bio/objs_per_slab', 0o664, b'21\n')
+f('sys/kernel/slab/bio/shrink', 0o664, b'')
+f('sys/kernel/slab/bio/trace', 0o664, b'0\n')
+f('sys/kernel/slab/bio/object_size', 0o664, b'104\n')
+f('sys/kernel/slab/bio/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/bio/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/bio/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/bio/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/bio/objects', 0o664, b'42\n')
+f('sys/kernel/slab/bio/order', 0o664, b'0\n')
+f('sys/kernel/slab/bio/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/bio/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/bio/align', 0o664, b'8\n')
+f('sys/kernel/slab/bio/partial', 0o664, b'0\n')
+f('sys/kernel/slab/bio/validate', 0o664, b'')
+f('sys/kernel/slab/bio/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/bio/free_calls', 0o664, b' 2 <not-available> age=4303046952 pid=0 cpus=0\n')
+f('sys/kernel/slab/bio/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/TCP', 0o775)
+f('sys/kernel/slab/TCP/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/TCP/ctor', 0o664, b'')
+f('sys/kernel/slab/TCP/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/TCP/slab_size', 0o664, b'2304\n')
+f('sys/kernel/slab/TCP/total_objects', 0o664, b'28\n')
+f('sys/kernel/slab/TCP/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/TCP/poison', 0o664, b'1\n')
+f('sys/kernel/slab/TCP/alloc_calls', 0o664, b' 3 sk_prot_alloc+0x1e/0xb0 age=926836/5879023/8356238 pid=1206-1920 cpus=0\n')
+f('sys/kernel/slab/TCP/objs_per_slab', 0o664, b'14\n')
+f('sys/kernel/slab/TCP/shrink', 0o664, b'')
+f('sys/kernel/slab/TCP/trace', 0o664, b'0\n')
+f('sys/kernel/slab/TCP/object_size', 0o664, b'2200\n')
+f('sys/kernel/slab/TCP/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/TCP/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/TCP/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/TCP/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/TCP/objects', 0o664, b'28\n')
+f('sys/kernel/slab/TCP/order', 0o664, b'3\n')
+f('sys/kernel/slab/TCP/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/TCP/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/TCP/align', 0o664, b'0\n')
+f('sys/kernel/slab/TCP/partial', 0o664, b'0\n')
+f('sys/kernel/slab/TCP/validate', 0o664, b'')
+f('sys/kernel/slab/TCP/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/TCP/free_calls', 0o664, b' 3 sk_free+0x80/0x100 age=932105/5881414/8356684 pid=0-1762 cpus=0\n')
+f('sys/kernel/slab/TCP/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/nsproxy', 0o775)
+f('sys/kernel/slab/nsproxy/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/nsproxy/ctor', 0o664, b'')
+f('sys/kernel/slab/nsproxy/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/nsproxy/slab_size', 0o664, b'128\n')
+f('sys/kernel/slab/nsproxy/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/nsproxy/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/nsproxy/poison', 0o664, b'1\n')
+f('sys/kernel/slab/nsproxy/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/nsproxy/objs_per_slab', 0o664, b'32\n')
+f('sys/kernel/slab/nsproxy/shrink', 0o664, b'')
+f('sys/kernel/slab/nsproxy/trace', 0o664, b'0\n')
+f('sys/kernel/slab/nsproxy/object_size', 0o664, b'56\n')
+f('sys/kernel/slab/nsproxy/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/nsproxy/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/nsproxy/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/nsproxy/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/nsproxy/objects', 0o664, b'0\n')
+f('sys/kernel/slab/nsproxy/order', 0o664, b'0\n')
+f('sys/kernel/slab/nsproxy/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/nsproxy/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/nsproxy/align', 0o664, b'8\n')
+f('sys/kernel/slab/nsproxy/partial', 0o664, b'0\n')
+f('sys/kernel/slab/nsproxy/validate', 0o664, b'')
+f('sys/kernel/slab/nsproxy/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/nsproxy/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/nsproxy/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/inotify_watch_cache', 0o775)
+f('sys/kernel/slab/inotify_watch_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/inotify_watch_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/inotify_watch_cache/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/inotify_watch_cache/slab_size', 0o664, b'144\n')
+f('sys/kernel/slab/inotify_watch_cache/total_objects', 0o664, b'168\n')
+f('sys/kernel/slab/inotify_watch_cache/slabs', 0o664, b'6\n')
+f('sys/kernel/slab/inotify_watch_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/inotify_watch_cache/alloc_calls', 0o664, b' 126 sys_inotify_add_watch+0x15e/0x1d0 age=60497/8227702/8376765 pid=72-13355 cpus=0-1\n')
+f('sys/kernel/slab/inotify_watch_cache/objs_per_slab', 0o664, b'28\n')
+f('sys/kernel/slab/inotify_watch_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/inotify_watch_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/inotify_watch_cache/object_size', 0o664, b'72\n')
+f('sys/kernel/slab/inotify_watch_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/inotify_watch_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/inotify_watch_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/inotify_watch_cache/objects_partial', 0o664, b'24\n')
+f('sys/kernel/slab/inotify_watch_cache/objects', 0o664, b'164\n')
+f('sys/kernel/slab/inotify_watch_cache/order', 0o664, b'0\n')
+f('sys/kernel/slab/inotify_watch_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/inotify_watch_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/inotify_watch_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/inotify_watch_cache/partial', 0o664, b'1\n')
+f('sys/kernel/slab/inotify_watch_cache/validate', 0o664, b'')
+f('sys/kernel/slab/inotify_watch_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/inotify_watch_cache/free_calls', 0o664, b''' 122 <not-available> age=4303047477 pid=0 cpus=0
+ 4 free_inotify_user_watch+0x60/0x70 age=104648/4219698/8334832 pid=2423-13211 cpus=0
+''')
+f('sys/kernel/slab/inotify_watch_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/fs_cache', 0o775)
+f('sys/kernel/slab/fs_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/fs_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/fs_cache/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/fs_cache/slab_size', 0o664, b'192\n')
+f('sys/kernel/slab/fs_cache/total_objects', 0o664, b'126\n')
+f('sys/kernel/slab/fs_cache/slabs', 0o664, b'6\n')
+f('sys/kernel/slab/fs_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/fs_cache/alloc_calls', 0o664, b' 79 __copy_fs_struct+0x28/0xc0 age=4126/7761540/8379883 pid=1-12336 cpus=0-1\n')
+f('sys/kernel/slab/fs_cache/objs_per_slab', 0o664, b'21\n')
+f('sys/kernel/slab/fs_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/fs_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/fs_cache/object_size', 0o664, b'104\n')
+f('sys/kernel/slab/fs_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/fs_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/fs_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/fs_cache/objects_partial', 0o664, b'75\n')
+f('sys/kernel/slab/fs_cache/objects', 0o664, b'117\n')
+f('sys/kernel/slab/fs_cache/order', 0o664, b'0\n')
+f('sys/kernel/slab/fs_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/fs_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/fs_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/fs_cache/partial', 0o664, b'4\n')
+f('sys/kernel/slab/fs_cache/validate', 0o664, b'')
+f('sys/kernel/slab/fs_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/fs_cache/free_calls', 0o664, b''' 7 <not-available> age=4303047241 pid=0 cpus=0
+ 72 put_fs_struct+0x37/0x40 age=7168/7706405/8375333 pid=145-20292 cpus=0-1
+''')
+f('sys/kernel/slab/fs_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/kmalloc-512', 0o775)
+f('sys/kernel/slab/kmalloc-512/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-512/ctor', 0o664, b'')
+f('sys/kernel/slab/kmalloc-512/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-512/slab_size', 0o664, b'584\n')
+f('sys/kernel/slab/kmalloc-512/total_objects', 0o664, b'504\n')
+f('sys/kernel/slab/kmalloc-512/slabs', 0o664, b'36\n')
+f('sys/kernel/slab/kmalloc-512/poison', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-512/alloc_calls', 0o664, b''' 14 __register_sysctl_paths+0x56/0x340 age=8360125/8372514/8379788 pid=1-1549 cpus=0
+ 14 param_sysfs_setup+0x87/0x140 age=8355309/8375663/8379919 pid=1-1813 cpus=0-1
+ 59 module_add_modinfo_attrs+0x25/0xf0 age=8303025/8368384/8376264 pid=105-2754 cpus=0-1
+ 2 __vmalloc_area_node+0xfb/0x140 age=8374650/8375296/8375942 pid=126-144 cpus=0
+ 1 dma_kmalloc_cache+0xca/0x150 age=8375776 pid=163 cpus=0
+ 107 kmem_cache_create+0x4e/0x2e0 age=8360130/8377702/8380056 pid=0-1549 cpus=0-1
+ 2 __percpu_alloc_mask+0xbc/0x140 age=8379768/8379768/8379768 pid=1 cpus=1
+ 17 sys_inotify_init1+0xaa/0x220 age=8333709/8350157/8376641 pid=72-2544 cpus=0-1
+ 4 sys_epoll_create1+0x41/0x100 age=2416994/6871289/8356805 pid=1690-20296 cpus=0-1
+ 2 __crypto_alloc_tfm+0x43/0x1b0 age=8373592/8373592/8373592 pid=126 cpus=1
+ 1 crypto_alloc_instance+0x2b/0xe0 age=8373592 pid=745 cpus=0
+ 3 elevator_alloc+0x67/0xc0 age=62000/5606780/8379335 pid=1-13295 cpus=0-1
+ 3 cfq_init_queue+0x1b/0x120 age=62000/5606780/8379335 pid=1-13295 cpus=0-1
+ 1 fb_alloc_cmap+0x66/0x150 age=8379756 pid=1 cpus=1
+ 1 fb_alloc_cmap+0x81/0x150 age=8379756 pid=1 cpus=1
+ 1 fb_alloc_cmap+0x9c/0x150 age=8379756 pid=1 cpus=1
+ 1 fbcon_startup+0xd6/0x2f0 age=8379755 pid=1 cpus=1
+ 1 acpi_ds_build_internal_buffer_obj+0xe1/0x121 age=8379896 pid=1 cpus=0
+ 1 make_acpi_ec+0x1a/0xcb age=8379913 pid=1 cpus=0
+ 1 acpi_irq_stats_init+0x83/0x268 age=8379913 pid=1 cpus=0
+ 1 acpi_irq_stats_init+0xa7/0x268 age=8379913 pid=1 cpus=0
+ 5 alloc_tty_driver+0x1c/0x40 age=8309091/8365595/8379725 pid=1-2711 cpus=1
+ 2 vt_ioctl+0x1874/0x1c30 age=8356613/8356613/8356613 pid=1703 cpus=0
+ 8 set_inverse_transl+0xa0/0xb0 age=8355024/8367389/8379755 pid=1-1898 cpus=1
+ 2 con_clear_unimap+0x2a/0xd0 age=8355024/8367389/8379755 pid=1-1898 cpus=1
+ 7 vc_allocate+0x99/0x1b0 age=8356563/8358748/8368241 pid=1135-1729 cpus=0-1
+ 1 hpet_alloc+0x6b/0x3c0 age=8379798 pid=1 cpus=0
+ 4 uart_open+0x36c/0x4b0 age=8368845/8368914/8369120 pid=1059-1073 cpus=0-1
+ 43 bus_add_driver+0x4f/0x280 age=8303025/8373842/8379841 pid=1-2754 cpus=0-1
+ 9 bus_register+0x35/0x290 age=8373434/8378695/8379923 pid=1-770 cpus=0-1
+ 30 __class_register+0x28/0x1e0 age=8374523/8378099/8379922 pid=1-352 cpus=0-1
+ 1 mousedev_open+0xc8/0x1d0 age=8354269 pid=1738 cpus=0
+ 1 cpufreq_add_dev+0x8f/0x5c0 age=8366381 pid=1358 cpus=0
+ 4 sock_alloc_send_skb+0x1cd/0x200 age=8330763/8342704/8350746 pid=1738 cpus=0-1
+ 1 alloc_netdev_mq+0x6c/0x180 age=8373712 pid=126 cpus=1
+ 4 inetdev_init+0x28/0x190 age=8373592/8375784/8379779 pid=1-126 cpus=0-1
+ 2 fib_hash_table+0x1c/0x80 age=8379779/8379779/8379779 pid=1 cpus=0
+ 1 ioapic_init_sysfs+0x74/0xcf age=8379769 pid=1 cpus=1
+ 3 snd_malloc_sgbuf_pages+0xbe/0x1f0 [snd_page_alloc] age=8374119/8374119/8374119 pid=107 cpus=1
+ 1 usb_get_configuration+0x18f/0x1480 [usbcore] age=22677 pid=419 cpus=0
+ 1 usb_get_configuration+0x5f2/0x1480 [usbcore] age=8372692 pid=419 cpus=0
+ 2 acpi_processor_get_throttling_info+0x21f/0x58c [processor] age=8375662/8375686/8375710 pid=330 cpus=0
+ 48 snd_info_create_entry+0x1b/0xa0 [snd] age=8355304/8371157/8374867 pid=107-1813 cpus=0-1
+ 4 snd_timer_new+0x40/0x190 [snd_timer] age=8374097/8374262/8374757 pid=107 cpus=1
+ 2 ieee80211_key_alloc+0x37/0xe0 [mac80211] age=3544694/3544694/3544694 pid=1545 cpus=0
+ 3 snd_pcm_new_stream+0x161/0x520 [snd_pcm] age=8374119/8374119/8374119 pid=107 cpus=1
+ 1 snd_hda_bus_new+0x31/0xf4 [snd_hda_intel] age=8374122 pid=107 cpus=1
+ 1 crypto_blkcipher_type+0x54/0xffffffffffffff8e [crypto_blkcipher] age=8374450 pid=215 cpus=0
+ 1 md_import_device+0x32/0x290 [md_mod] age=8370110 pid=916 cpus=0
+ 1 bitmap_create+0x5e/0xad0 [md_mod] age=8370066 pid=916 cpus=0
+ 1 run+0x42/0x500 [raid1] age=8370068 pid=916 cpus=0
+ 1 ip6_route_net_init+0x4d/0xd0 [ipv6] age=8360130 pid=1549 cpus=0
+''')
+f('sys/kernel/slab/kmalloc-512/objs_per_slab', 0o664, b'14\n')
+f('sys/kernel/slab/kmalloc-512/shrink', 0o664, b'')
+f('sys/kernel/slab/kmalloc-512/trace', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-512/object_size', 0o664, b'512\n')
+f('sys/kernel/slab/kmalloc-512/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-512/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-512/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-512/objects_partial', 0o664, b'79\n')
+f('sys/kernel/slab/kmalloc-512/objects', 0o664, b'443\n')
+f('sys/kernel/slab/kmalloc-512/order', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-512/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-512/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-512/align', 0o664, b'8\n')
+f('sys/kernel/slab/kmalloc-512/partial', 0o664, b'10\n')
+f('sys/kernel/slab/kmalloc-512/validate', 0o664, b'')
+f('sys/kernel/slab/kmalloc-512/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-512/free_calls', 0o664, b''' 163 <not-available> age=4303047353 pid=0 cpus=0
+ 4 __vunmap+0xe9/0x120 age=8374515/8375319/8376179 pid=122-215 cpus=0
+ 1 kmem_cache_shrink+0x5d/0x1b0 age=8379872 pid=1 cpus=0
+ 33 load_elf_binary+0xa7e/0x1e20 age=8303117/8365402/8377217 pid=62-2754 cpus=0-1
+ 19 load_elf_binary+0xc37/0x1e20 age=8355044/8370854/8376371 pid=197-1912 cpus=0-1
+ 1 crypto_larval_destroy+0x2b/0x40 age=8373593 pid=126 cpus=1
+ 210 skb_release_data+0x85/0xd0 age=22792/8177097/8379923 pid=1-20296 cpus=0-1
+ 1 acpi_processor_get_power_info+0x2eb/0x569 [processor] age=8375661 pid=330 cpus=1
+ 1 skcipher_geniv_alloc+0xea/0x3f0 [crypto_blkcipher] age=8374478 pid=215 cpus=0
+ 1 snd_mixer_oss_build_input+0x402/0x5c0 [snd_mixer_oss] age=8355509 pid=1813 cpus=0
+''')
+f('sys/kernel/slab/kmalloc-512/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/biovec-256', 0o775)
+f('sys/kernel/slab/biovec-256/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-256/ctor', 0o664, b'')
+f('sys/kernel/slab/biovec-256/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-256/slab_size', 0o664, b'4224\n')
+f('sys/kernel/slab/biovec-256/total_objects', 0o664, b'7\n')
+f('sys/kernel/slab/biovec-256/slabs', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-256/poison', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-256/alloc_calls', 0o664, b' 2 mempool_alloc_slab+0x11/0x20 age=8379465/8379465/8379465 pid=1 cpus=0\n')
+f('sys/kernel/slab/biovec-256/objs_per_slab', 0o664, b'7\n')
+f('sys/kernel/slab/biovec-256/shrink', 0o664, b'')
+f('sys/kernel/slab/biovec-256/trace', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-256/object_size', 0o664, b'4096\n')
+f('sys/kernel/slab/biovec-256/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-256/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-256/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-256/objects_partial', 0o664, b'2\n')
+f('sys/kernel/slab/biovec-256/objects', 0o664, b'2\n')
+f('sys/kernel/slab/biovec-256/order', 0o664, b'3\n')
+f('sys/kernel/slab/biovec-256/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-256/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-256/align', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-256/partial', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-256/validate', 0o664, b'')
+f('sys/kernel/slab/biovec-256/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-256/free_calls', 0o664, b' 2 <not-available> age=4303046899 pid=0 cpus=0\n')
+f('sys/kernel/slab/biovec-256/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/kmalloc-128', 0o775)
+f('sys/kernel/slab/kmalloc-128/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-128/ctor', 0o664, b'')
+f('sys/kernel/slab/kmalloc-128/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-128/slab_size', 0o664, b'200\n')
+f('sys/kernel/slab/kmalloc-128/total_objects', 0o664, b'360\n')
+f('sys/kernel/slab/kmalloc-128/slabs', 0o664, b'18\n')
+f('sys/kernel/slab/kmalloc-128/poison', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-128/alloc_calls', 0o664, b''' 17 param_sysfs_setup+0x87/0x140 age=8366402/8376536/8379939 pid=1-1358 cpus=0-1
+ 1 mempool_create_node+0x4b/0xf0 age=8379025 pid=1 cpus=0
+ 4 __vmalloc_area_node+0xfb/0x140 age=8303049/8349608/8370350 pid=900-2754 cpus=0
+ 2 shmem_fill_super+0x38/0x200 age=8377584/8378686/8379788 pid=1-46 cpus=0-1
+ 56 __percpu_alloc_mask+0xbc/0x140 age=61988/7483637/8379799 pid=1-13295 cpus=0-1
+ 11 cdev_alloc+0x1a/0x50 age=61988/7621848/8379938 pid=1-13295 cpus=0-1
+ 110 d_alloc+0x19d/0x1f0 age=22451/5346628/8376065 pid=401-13439 cpus=0-1
+ 2 bm_register_write+0x63/0x630 age=8354053/8354053/8354053 pid=2054 cpus=1
+ 2 alloc_disk_node+0x6c/0x120 age=62016/4220683/8379351 pid=1-13295 cpus=1
+ 20 ida_pre_get+0x86/0x90 age=8298034/8372144/8380076 pid=0-2761 cpus=0-1
+ 5 acpi_ds_build_internal_package_obj+0xaf/0x1df age=8379905/8379914/8379918 pid=1 cpus=0
+ 2 acpi_ds_build_internal_buffer_obj+0xe1/0x121 age=8379921/8379921/8379921 pid=1 cpus=0
+ 1 acpi_ev_create_gpe_block+0xb2/0x3bf age=8379933 pid=1 cpus=0
+ 4 acpi_add_single_object+0x5d8/0xd3c age=8379862/8379869/8379873 pid=1 cpus=0
+ 41 con_insert_unipair+0xd6/0x110 age=8355044/8369520/8379775 pid=1-1898 cpus=1
+ 2 thermal_zone_bind_cooling_device+0xde/0x2a0 age=8374828/8374828/8374828 pid=329 cpus=0
+ 4 led_trigger_register_simple+0x2b/0x80 age=8375615/8375659/8375793 pid=392-396 cpus=0
+ 1 sock_kmalloc+0x5c/0x70 age=8328344 pid=2586 cpus=0
+ 3 alloc_netdev_mq+0x6c/0x180 age=8373612/8376531/8379814 pid=1-126 cpus=0-1
+ 2 neigh_table_init_no_netlink+0xd2/0x250 age=8360154/8369976/8379799 pid=1-1549 cpus=0
+ 8 neigh_parms_alloc+0x5d/0x110 age=8360146/8367976/8379799 pid=1-1549 cpus=0-1
+ 4 fz_hash_alloc+0x4a/0x60 age=8325493/8357250/8367862 pid=1185-1541 cpus=0-1
+ 1 get_local_pda+0x39/0x9b age=8380015 pid=1 cpus=0
+ 1 mnt_init+0xf9/0x202 age=8380076 pid=0 cpus=0
+ 1 net_ns_init+0x49/0x16d age=8379942 pid=1 cpus=0
+ 3 sg_add+0x8c/0x400 [sg] age=61988/5604850/8376284 pid=169-13295 cpus=0
+ 3 usb_get_configuration+0x5f2/0x1480 [usbcore] age=22696/22696/22696 pid=419 cpus=0
+ 15 usb_get_configuration+0x1388/0x1480 [usbcore] age=22696/3922325/8372712 pid=419 cpus=0
+ 1 0xffffffffa0065117 age=8374777 pid=107 cpus=1
+ 1 ieee80211_led_init+0x1b/0x230 [mac80211] age=8373612 pid=126 cpus=1
+ 1 ieee80211_led_init+0x83/0x230 [mac80211] age=8373612 pid=126 cpus=1
+ 1 ieee80211_led_init+0xeb/0x230 [mac80211] age=8373611 pid=126 cpus=1
+ 1 ieee80211_led_init+0x153/0x230 [mac80211] age=8373611 pid=126 cpus=1
+ 1 snd_hda_codec_new+0x1ec/0x559 [snd_hda_intel] age=8374142 pid=107 cpus=1
+ 1 md_register_thread+0x35/0xd0 [md_mod] age=8370088 pid=916 cpus=0
+ 1 fib6_net_init+0x7e/0x130 [ipv6] age=8360149 pid=1549 cpus=0
+''')
+f('sys/kernel/slab/kmalloc-128/objs_per_slab', 0o664, b'20\n')
+f('sys/kernel/slab/kmalloc-128/shrink', 0o664, b'')
+f('sys/kernel/slab/kmalloc-128/trace', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-128/object_size', 0o664, b'128\n')
+f('sys/kernel/slab/kmalloc-128/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-128/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-128/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-128/objects_partial', 0o664, b'83\n')
+f('sys/kernel/slab/kmalloc-128/objects', 0o664, b'343\n')
+f('sys/kernel/slab/kmalloc-128/order', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-128/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-128/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-128/align', 0o664, b'8\n')
+f('sys/kernel/slab/kmalloc-128/partial', 0o664, b'5\n')
+f('sys/kernel/slab/kmalloc-128/validate', 0o664, b'')
+f('sys/kernel/slab/kmalloc-128/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-128/free_calls', 0o664, b''' 197 <not-available> age=4303047372 pid=0 cpus=0
+ 3 call_usermodehelper_freeinfo+0x27/0x30 age=8360145/8367948/8373612 pid=745-1532 cpus=0
+ 2 __vunmap+0xe9/0x120 age=8375480/8375882/8376284 pid=105-169 cpus=0
+ 5 percpu_free+0x2d/0x60 age=7838031/7838092/7838171 pid=419-3347 cpus=0
+ 1 cdev_dynamic_release+0x19/0x20 age=7838171 pid=419 cpus=0
+ 49 d_callback+0x22/0x40 age=53327/5302082/8375461 pid=0-13314 cpus=0-1
+ 51 load_elf_binary+0xaf/0x1e20 age=25315/7326461/8377585 pid=46-21952 cpus=0-1
+ 1 free_rb_tree_fname+0x5c/0xb0 age=8366816 pid=1274 cpus=0
+ 1 disk_release+0x2e/0x50 age=7838031 pid=3347 cpus=0
+ 2 free_bitmap+0x29/0x80 age=8368053/8369024/8369995 pid=55 cpus=0-1
+ 1 acpi_evaluate_reference+0x100/0x117 age=8374829 pid=329 cpus=0
+ 6 acpi_get_object_info+0x1b6/0x1d4 age=8379736/8379841/8379873 pid=1 cpus=0-1
+ 4 do_acpi_find_child+0x48/0x51 age=8379209/8379658/8379850 pid=1 cpus=0-1
+ 1 unpack_to_rootfs+0x105/0xa39 age=8379790 pid=1 cpus=0
+ 1 sg_remove+0x1ca/0x240 [sg] age=7838171 pid=419 cpus=0
+ 6 usb_release_interface_cache+0x2c/0x60 [usbcore] age=7833192/7833192/7833192 pid=419 cpus=1
+ 2 usb_release_interface_cache+0x47/0x60 [usbcore] age=7833192/7833192/7833192 pid=419 cpus=1
+ 1 acpi_processor_get_throttling_info+0x15e/0x58c [processor] age=8375683 pid=330 cpus=0
+''')
+f('sys/kernel/slab/kmalloc-128/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/ip_dst_cache', 0o775)
+f('sys/kernel/slab/ip_dst_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/ip_dst_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/ip_dst_cache/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/ip_dst_cache/slab_size', 0o664, b'384\n')
+f('sys/kernel/slab/ip_dst_cache/total_objects', 0o664, b'42\n')
+f('sys/kernel/slab/ip_dst_cache/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/ip_dst_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/ip_dst_cache/alloc_calls', 0o664, b' 1 dst_alloc+0x2b/0x90 age=920684 pid=1206 cpus=0\n')
+f('sys/kernel/slab/ip_dst_cache/objs_per_slab', 0o664, b'21\n')
+f('sys/kernel/slab/ip_dst_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/ip_dst_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/ip_dst_cache/object_size', 0o664, b'312\n')
+f('sys/kernel/slab/ip_dst_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/ip_dst_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/ip_dst_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/ip_dst_cache/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/ip_dst_cache/objects', 0o664, b'42\n')
+f('sys/kernel/slab/ip_dst_cache/order', 0o664, b'1\n')
+f('sys/kernel/slab/ip_dst_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/ip_dst_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/ip_dst_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/ip_dst_cache/partial', 0o664, b'0\n')
+f('sys/kernel/slab/ip_dst_cache/validate', 0o664, b'')
+f('sys/kernel/slab/ip_dst_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/ip_dst_cache/free_calls', 0o664, b' 1 <not-available> age=4303046733 pid=0 cpus=0\n')
+f('sys/kernel/slab/ip_dst_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/journal_head', 0o775)
+f('sys/kernel/slab/journal_head/reclaim_account', 0o664, b'1\n')
+f('sys/kernel/slab/journal_head/ctor', 0o664, b'')
+f('sys/kernel/slab/journal_head/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/journal_head/slab_size', 0o664, b'168\n')
+f('sys/kernel/slab/journal_head/total_objects', 0o664, b'7680\n')
+f('sys/kernel/slab/journal_head/slabs', 0o664, b'320\n')
+f('sys/kernel/slab/journal_head/poison', 0o664, b'1\n')
+f('sys/kernel/slab/journal_head/alloc_calls', 0o664, b' 7662 journal_add_journal_head+0x9f/0x1b0 age=0/2379/651354 pid=1336-13466 cpus=0-1\n')
+f('sys/kernel/slab/journal_head/objs_per_slab', 0o664, b'24\n')
+f('sys/kernel/slab/journal_head/shrink', 0o664, b'')
+f('sys/kernel/slab/journal_head/trace', 0o664, b'0\n')
+f('sys/kernel/slab/journal_head/object_size', 0o664, b'96\n')
+f('sys/kernel/slab/journal_head/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/journal_head/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/journal_head/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/journal_head/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/journal_head/objects', 0o664, b'7680\n')
+f('sys/kernel/slab/journal_head/order', 0o664, b'0\n')
+f('sys/kernel/slab/journal_head/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/journal_head/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/journal_head/align', 0o664, b'0\n')
+f('sys/kernel/slab/journal_head/partial', 0o664, b'0\n')
+f('sys/kernel/slab/journal_head/validate', 0o664, b'')
+f('sys/kernel/slab/journal_head/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/journal_head/free_calls', 0o664, b''' 7589 <not-available> age=4303047557 pid=0 cpus=0
+ 74 __journal_remove_journal_head+0xcb/0x160 age=1585/52253/654521 pid=32-13248 cpus=0-1
+''')
+f('sys/kernel/slab/journal_head/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/scsi_data_buffer', 0o775)
+f('sys/kernel/slab/scsi_data_buffer/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_data_buffer/ctor', 0o664, b'')
+f('sys/kernel/slab/scsi_data_buffer/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_data_buffer/slab_size', 0o664, b'96\n')
+f('sys/kernel/slab/scsi_data_buffer/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_data_buffer/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_data_buffer/poison', 0o664, b'1\n')
+f('sys/kernel/slab/scsi_data_buffer/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/scsi_data_buffer/objs_per_slab', 0o664, b'42\n')
+f('sys/kernel/slab/scsi_data_buffer/shrink', 0o664, b'')
+f('sys/kernel/slab/scsi_data_buffer/trace', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_data_buffer/object_size', 0o664, b'24\n')
+f('sys/kernel/slab/scsi_data_buffer/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_data_buffer/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_data_buffer/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_data_buffer/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_data_buffer/objects', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_data_buffer/order', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_data_buffer/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/scsi_data_buffer/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/scsi_data_buffer/align', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_data_buffer/partial', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_data_buffer/validate', 0o664, b'')
+f('sys/kernel/slab/scsi_data_buffer/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/scsi_data_buffer/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/scsi_data_buffer/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/fuse_request', 0o775)
+f('sys/kernel/slab/fuse_request/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/fuse_request/ctor', 0o664, b'')
+f('sys/kernel/slab/fuse_request/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/fuse_request/slab_size', 0o664, b'728\n')
+f('sys/kernel/slab/fuse_request/total_objects', 0o664, b'44\n')
+f('sys/kernel/slab/fuse_request/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/fuse_request/poison', 0o664, b'1\n')
+f('sys/kernel/slab/fuse_request/alloc_calls', 0o664, b' 1 fuse_request_alloc+0x1a/0x40 [fuse] age=8336120 pid=2476 cpus=0\n')
+f('sys/kernel/slab/fuse_request/objs_per_slab', 0o664, b'22\n')
+f('sys/kernel/slab/fuse_request/shrink', 0o664, b'')
+f('sys/kernel/slab/fuse_request/trace', 0o664, b'0\n')
+f('sys/kernel/slab/fuse_request/object_size', 0o664, b'656\n')
+f('sys/kernel/slab/fuse_request/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/fuse_request/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/fuse_request/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/fuse_request/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/fuse_request/objects', 0o664, b'44\n')
+f('sys/kernel/slab/fuse_request/order', 0o664, b'2\n')
+f('sys/kernel/slab/fuse_request/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/fuse_request/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/fuse_request/align', 0o664, b'0\n')
+f('sys/kernel/slab/fuse_request/partial', 0o664, b'0\n')
+f('sys/kernel/slab/fuse_request/validate', 0o664, b'')
+f('sys/kernel/slab/fuse_request/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/fuse_request/free_calls', 0o664, b' 1 <not-available> age=4303047718 pid=0 cpus=0\n')
+f('sys/kernel/slab/fuse_request/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/pid', 0o775)
+f('sys/kernel/slab/pid/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/pid/ctor', 0o664, b'')
+f('sys/kernel/slab/pid/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/pid/slab_size', 0o664, b'192\n')
+f('sys/kernel/slab/pid/total_objects', 0o664, b'252\n')
+f('sys/kernel/slab/pid/slabs', 0o664, b'12\n')
+f('sys/kernel/slab/pid/poison', 0o664, b'1\n')
+f('sys/kernel/slab/pid/alloc_calls', 0o664, b' 207 alloc_pid+0x26/0x430 age=4190/8015525/8379960 pid=0-13212 cpus=0-1\n')
+f('sys/kernel/slab/pid/objs_per_slab', 0o664, b'21\n')
+f('sys/kernel/slab/pid/shrink', 0o664, b'')
+f('sys/kernel/slab/pid/trace', 0o664, b'0\n')
+f('sys/kernel/slab/pid/object_size', 0o664, b'80\n')
+f('sys/kernel/slab/pid/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/pid/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/pid/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/pid/objects_partial', 0o664, b'131\n')
+f('sys/kernel/slab/pid/objects', 0o664, b'236\n')
+f('sys/kernel/slab/pid/order', 0o664, b'0\n')
+f('sys/kernel/slab/pid/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/pid/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/pid/align', 0o664, b'8\n')
+f('sys/kernel/slab/pid/partial', 0o664, b'7\n')
+f('sys/kernel/slab/pid/validate', 0o664, b'')
+f('sys/kernel/slab/pid/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/pid/free_calls', 0o664, b''' 69 <not-available> age=4303047306 pid=0 cpus=0
+ 138 put_pid+0x36/0x40 age=7228/7841898/8377070 pid=0-13258 cpus=0-1
+''')
+f('sys/kernel/slab/pid/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/ext2_inode_cache', 0o775)
+f('sys/kernel/slab/ext2_inode_cache/reclaim_account', 0o664, b'1\n')
+f('sys/kernel/slab/ext2_inode_cache/ctor', 0o664, b'init_once+0x0/0x60\n')
+f('sys/kernel/slab/ext2_inode_cache/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/ext2_inode_cache/slab_size', 0o664, b'1456\n')
+f('sys/kernel/slab/ext2_inode_cache/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/ext2_inode_cache/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/ext2_inode_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/ext2_inode_cache/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/ext2_inode_cache/objs_per_slab', 0o664, b'22\n')
+f('sys/kernel/slab/ext2_inode_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/ext2_inode_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/ext2_inode_cache/object_size', 0o664, b'1384\n')
+f('sys/kernel/slab/ext2_inode_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/ext2_inode_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/ext2_inode_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/ext2_inode_cache/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/ext2_inode_cache/objects', 0o664, b'0\n')
+f('sys/kernel/slab/ext2_inode_cache/order', 0o664, b'3\n')
+f('sys/kernel/slab/ext2_inode_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/ext2_inode_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/ext2_inode_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/ext2_inode_cache/partial', 0o664, b'0\n')
+f('sys/kernel/slab/ext2_inode_cache/validate', 0o664, b'')
+f('sys/kernel/slab/ext2_inode_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/ext2_inode_cache/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/ext2_inode_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/kmalloc-1024', 0o775)
+f('sys/kernel/slab/kmalloc-1024/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-1024/ctor', 0o664, b'')
+f('sys/kernel/slab/kmalloc-1024/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-1024/slab_size', 0o664, b'1096\n')
+f('sys/kernel/slab/kmalloc-1024/total_objects', 0o664, b'580\n')
+f('sys/kernel/slab/kmalloc-1024/slabs', 0o664, b'20\n')
+f('sys/kernel/slab/kmalloc-1024/poison', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-1024/alloc_calls', 0o664, b''' 23 __register_sysctl_paths+0x56/0x340 age=8360116/8368981/8379769 pid=1-1549 cpus=0-1
+ 5 param_sysfs_setup+0x87/0x140 age=8355550/8371926/8379909 pid=1-1805 cpus=0-1
+ 5 load_module+0x18d5/0x1b30 age=8328407/8365286/8375764 pid=208-2578 cpus=0
+ 2 __vmalloc_area_node+0xfb/0x140 age=8360170/8367347/8374524 pid=107-1549 cpus=0
+ 4 __percpu_alloc_mask+0xbc/0x140 age=8379760/8379760/8379760 pid=1 cpus=0
+ 113 alloc_pipe_info+0x25/0x60 age=125624/8270722/8377065 pid=1-13212 cpus=0-1
+ 2 alloc_fdtable+0x81/0x160 age=2417000/5386894/8356789 pid=1690 cpus=0-1
+ 1 mb_cache_create+0xb6/0x1f0 age=8379750 pid=1 cpus=1
+ 1 mb_cache_create+0x11e/0x1f0 age=8379750 pid=1 cpus=1
+ 8 add_partition+0x45/0x250 age=61959/7339549/8379206 pid=1-13295 cpus=0
+ 2 __crypto_alloc_tfm+0x43/0x1b0 age=3544684/3544684/3544684 pid=1545 cpus=0
+ 1 pci_create_bus+0x82/0x240 age=8379831 pid=1 cpus=0
+ 14 pcie_port_device_register+0x254/0x4a0 age=8379746/8379746/8379748 pid=1 cpus=1
+ 1 acpi_ev_create_gpe_block+0x10b/0x3bf age=8379903 pid=1 cpus=0
+ 1 acpi_tb_resize_root_table_list+0x66/0xdb age=8375731 pid=330 cpus=0
+ 2 tty_buffer_request_room+0x136/0x190 age=8214639/8272696/8330753 pid=0-2262 cpus=0
+ 1 tty_register_driver+0x1b3/0x2a0 age=8309081 pid=2711 cpus=1
+ 10 tty_write+0x160/0x280 age=7214010/8238951/8377659 pid=34-2590 cpus=0-1
+ 2 set_inverse_trans_unicode+0xce/0xf0 age=8355014/8367379/8379745 pid=1-1898 cpus=1
+ 1 uart_register_driver+0x31/0x1c0 age=8379710 pid=1 cpus=1
+ 166 device_create_vargs+0x8c/0x100 age=22658/8173620/8379911 pid=1-13295 cpus=0-1
+ 8 platform_device_alloc+0x37/0x90 age=8367172/8376785/8379911 pid=1-1285 cpus=0-1
+ 3 scsi_alloc_target+0x63/0x2e0 age=61990/5606770/8379325 pid=1-13295 cpus=0-1
+ 2 sd_probe+0x86/0x430 age=61986/4220653/8379321 pid=1-13295 cpus=1
+ 1 ahci_port_start+0x34/0xe0 age=8379708 pid=1 cpus=1
+ 1 psmouse_connect+0x5b/0x2c0 age=8378898 pid=17 cpus=1
+ 2 thermal_cooling_device_register+0x7f/0x290 age=8375643/8375667/8375692 pid=330 cpus=0-1
+ 1 hid_add_field+0xcc/0x3a0 age=53473 pid=419 cpus=0
+ 4 sock_alloc_send_skb+0x1cd/0x200 age=8344775/8349266/8350926 pid=1738 cpus=0-1
+ 3 __rtnl_register+0x79/0x90 age=8360119/8373266/8379912 pid=1-1549 cpus=0
+ 6 qdisc_alloc+0x34/0xd0 age=8356043/8356079/8356257 pid=1541 cpus=0
+ 1 dmi_id_init+0x2a4/0x30c age=8379910 pid=1 cpus=0
+ 5 hub_probe+0xdd/0x820 [usbcore] age=8373999/8374492/8374845 pid=143-147 cpus=0-1
+ 5 usb_create_hcd+0x39/0x150 [usbcore] age=8374071/8374526/8374892 pid=143-147 cpus=0
+ 26 usb_set_configuration+0x441/0x5f0 [usbcore] age=22663/3237429/8374857 pid=143-419 cpus=0-1
+ 10 usb_get_configuration+0x92/0x1480 [usbcore] age=22667/5876069/8374865 pid=143-419 cpus=0-1
+ 34 usb_create_ep_files+0x51/0x350 [usbcore] age=22579/5431762/8374732 pid=143-419 cpus=0-1
+ 1 acpi_battery_add+0x29/0x1d3 [battery] age=8375630 pid=396 cpus=0
+ 1 snd_card_new+0x38/0x370 [snd] age=8374136 pid=107 cpus=0
+ 1 sta_info_alloc+0x3c/0x1d0 [mac80211] age=8329523 pid=742 cpus=0
+ 2 snd_pcm_new+0x47/0x130 [snd_pcm] age=8374109/8374109/8374109 pid=107 cpus=1
+ 1 rs_alloc_sta+0x25/0x120 [iwl3945] age=8329523 pid=742 cpus=0
+ 1 get_alloc_hash+0x9b/0x140 [snd_hda_intel] age=8373108 pid=786 cpus=0
+ 1 azx_probe+0xb3/0xc20 [snd_hda_intel] age=8374129 pid=107 cpus=0
+ 1 azx_probe+0x4a9/0xc20 [snd_hda_intel] age=8374122 pid=107 cpus=0
+ 1 snd_hda_codec_new+0x3e/0x559 [snd_hda_intel] age=8374112 pid=107 cpus=1
+ 1 md_probe+0xa1/0x360 [md_mod] age=8370183 pid=916 cpus=0
+ 8 loop_alloc+0x28/0x140 [loop] age=8369639/8369639/8369639 pid=951 cpus=0
+ 4 ipv6_add_dev+0x69/0x330 [ipv6] age=8360116/8360117/8360119 pid=1549 cpus=0
+ 1 ipv6_route_sysctl_init+0x22/0xb0 [ipv6] age=8360115 pid=1549 cpus=0
+ 2 snd_seq_create_port+0x35/0x180 [snd_seq] age=8355549/8355549/8355549 pid=1805 cpus=0
+''')
+f('sys/kernel/slab/kmalloc-1024/objs_per_slab', 0o664, b'29\n')
+f('sys/kernel/slab/kmalloc-1024/shrink', 0o664, b'')
+f('sys/kernel/slab/kmalloc-1024/trace', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-1024/object_size', 0o664, b'1024\n')
+f('sys/kernel/slab/kmalloc-1024/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-1024/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-1024/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-1024/objects_partial', 0o664, b'196\n')
+f('sys/kernel/slab/kmalloc-1024/objects', 0o664, b'544\n')
+f('sys/kernel/slab/kmalloc-1024/order', 0o664, b'3\n')
+f('sys/kernel/slab/kmalloc-1024/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-1024/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-1024/align', 0o664, b'8\n')
+f('sys/kernel/slab/kmalloc-1024/partial', 0o664, b'8\n')
+f('sys/kernel/slab/kmalloc-1024/validate', 0o664, b'')
+f('sys/kernel/slab/kmalloc-1024/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-1024/free_calls', 0o664, b''' 216 <not-available> age=4303047343 pid=0 cpus=0
+ 1 __vunmap+0xe9/0x120 age=8360137 pid=1549 cpus=0
+ 64 __free_pipe_info+0x5c/0x70 age=55301/8227248/8377668 pid=34-13363 cpus=0-1
+ 19 acpi_ds_delete_walk_state+0xc9/0xcd age=8355814/8376228/8380000 pid=0-1772 cpus=0-1
+ 1 acpi_tb_resize_root_table_list+0xbf/0xdb age=8375732 pid=330 cpus=0
+ 2 release_one_tty+0xc7/0x190 age=8352476/8361380/8370284 pid=55-1253 cpus=0-1
+ 1 vt_ioctl+0x273/0x1c30 age=8356598 pid=1703 cpus=0
+ 14 device_create_release+0x9/0x10 age=8352395/8354628/8356598 pid=1703-2139 cpus=0-1
+ 1 fw_dev_release+0x20/0x30 age=8356148 pid=1541 cpus=0
+ 184 skb_release_data+0x85/0xd0 age=22639/7036434/8379911 pid=0-13303 cpus=0-1
+''')
+f('sys/kernel/slab/kmalloc-1024/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/files_cache', 0o775)
+f('sys/kernel/slab/files_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/files_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/files_cache/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/files_cache/slab_size', 0o664, b'896\n')
+f('sys/kernel/slab/files_cache/total_objects', 0o664, b'108\n')
+f('sys/kernel/slab/files_cache/slabs', 0o664, b'6\n')
+f('sys/kernel/slab/files_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/files_cache/alloc_calls', 0o664, b' 80 dup_fd+0x2e/0x420 age=4136/7769280/8379905 pid=0-12336 cpus=0-1\n')
+f('sys/kernel/slab/files_cache/objs_per_slab', 0o664, b'18\n')
+f('sys/kernel/slab/files_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/files_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/files_cache/object_size', 0o664, b'768\n')
+f('sys/kernel/slab/files_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/files_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/files_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/files_cache/objects_partial', 0o664, b'29\n')
+f('sys/kernel/slab/files_cache/objects', 0o664, b'101\n')
+f('sys/kernel/slab/files_cache/order', 0o664, b'2\n')
+f('sys/kernel/slab/files_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/files_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/files_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/files_cache/partial', 0o664, b'2\n')
+f('sys/kernel/slab/files_cache/validate', 0o664, b'')
+f('sys/kernel/slab/files_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/files_cache/free_calls', 0o664, b''' 9 <not-available> age=4303047250 pid=0 cpus=0
+ 31 put_files_struct+0xb4/0xe0 age=7177/7367129/8366999 pid=1202-20292 cpus=0-1
+ 40 free_fdtable_rcu+0xa0/0xb0 age=61634/7953135/8376143 pid=0-12335 cpus=0-1
+''')
+f('sys/kernel/slab/files_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/UDP-Lite', 0o775)
+f('sys/kernel/slab/UDP-Lite/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/UDP-Lite/ctor', 0o664, b'')
+f('sys/kernel/slab/UDP-Lite/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/UDP-Lite/slab_size', 0o664, b'1344\n')
+f('sys/kernel/slab/UDP-Lite/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/UDP-Lite/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/UDP-Lite/poison', 0o664, b'1\n')
+f('sys/kernel/slab/UDP-Lite/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/UDP-Lite/objs_per_slab', 0o664, b'12\n')
+f('sys/kernel/slab/UDP-Lite/shrink', 0o664, b'')
+f('sys/kernel/slab/UDP-Lite/trace', 0o664, b'0\n')
+f('sys/kernel/slab/UDP-Lite/object_size', 0o664, b'1232\n')
+f('sys/kernel/slab/UDP-Lite/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/UDP-Lite/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/UDP-Lite/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/UDP-Lite/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/UDP-Lite/objects', 0o664, b'0\n')
+f('sys/kernel/slab/UDP-Lite/order', 0o664, b'2\n')
+f('sys/kernel/slab/UDP-Lite/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/UDP-Lite/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/UDP-Lite/align', 0o664, b'0\n')
+f('sys/kernel/slab/UDP-Lite/partial', 0o664, b'0\n')
+f('sys/kernel/slab/UDP-Lite/validate', 0o664, b'')
+f('sys/kernel/slab/UDP-Lite/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/UDP-Lite/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/UDP-Lite/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/mnt_cache', 0o775)
+f('sys/kernel/slab/mnt_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/mnt_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/mnt_cache/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/mnt_cache/slab_size', 0o664, b'320\n')
+f('sys/kernel/slab/mnt_cache/total_objects', 0o664, b'36\n')
+f('sys/kernel/slab/mnt_cache/slabs', 0o664, b'3\n')
+f('sys/kernel/slab/mnt_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/mnt_cache/alloc_calls', 0o664, b' 25 alloc_vfsmnt+0x1f/0x180 age=61162/8041266/8379801 pid=0-13348 cpus=0-1\n')
+f('sys/kernel/slab/mnt_cache/objs_per_slab', 0o664, b'12\n')
+f('sys/kernel/slab/mnt_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/mnt_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/mnt_cache/object_size', 0o664, b'224\n')
+f('sys/kernel/slab/mnt_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/mnt_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/mnt_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/mnt_cache/objects_partial', 0o664, b'4\n')
+f('sys/kernel/slab/mnt_cache/objects', 0o664, b'28\n')
+f('sys/kernel/slab/mnt_cache/order', 0o664, b'0\n')
+f('sys/kernel/slab/mnt_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/mnt_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/mnt_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/mnt_cache/partial', 0o664, b'1\n')
+f('sys/kernel/slab/mnt_cache/validate', 0o664, b'')
+f('sys/kernel/slab/mnt_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/mnt_cache/free_calls', 0o664, b''' 24 <not-available> age=4303047098 pid=0 cpus=0
+ 1 free_vfsmnt+0x2c/0x40 age=7837771 pid=3347 cpus=0
+''')
+f('sys/kernel/slab/mnt_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/skbuff_head_cache', 0o775)
+f('sys/kernel/slab/skbuff_head_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/skbuff_head_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/skbuff_head_cache/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/skbuff_head_cache/slab_size', 0o664, b'320\n')
+f('sys/kernel/slab/skbuff_head_cache/total_objects', 0o664, b'588\n')
+f('sys/kernel/slab/skbuff_head_cache/slabs', 0o664, b'49\n')
+f('sys/kernel/slab/skbuff_head_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/skbuff_head_cache/alloc_calls', 0o664, b' 550 __alloc_skb+0x44/0x150 age=1665/3999351/8355948 pid=733-1738 cpus=0-1\n')
+f('sys/kernel/slab/skbuff_head_cache/objs_per_slab', 0o664, b'12\n')
+f('sys/kernel/slab/skbuff_head_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/skbuff_head_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/skbuff_head_cache/object_size', 0o664, b'208\n')
+f('sys/kernel/slab/skbuff_head_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/skbuff_head_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/skbuff_head_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/skbuff_head_cache/objects_partial', 0o664, b'18\n')
+f('sys/kernel/slab/skbuff_head_cache/objects', 0o664, b'570\n')
+f('sys/kernel/slab/skbuff_head_cache/order', 0o664, b'0\n')
+f('sys/kernel/slab/skbuff_head_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/skbuff_head_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/skbuff_head_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/skbuff_head_cache/partial', 0o664, b'3\n')
+f('sys/kernel/slab/skbuff_head_cache/validate', 0o664, b'')
+f('sys/kernel/slab/skbuff_head_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/skbuff_head_cache/free_calls', 0o664, b''' 333 <not-available> age=4303046979 pid=0 cpus=0
+ 217 __kfree_skb+0x3a/0xa0 age=1666/662694/8356220 pid=0-13466 cpus=0-1
+''')
+f('sys/kernel/slab/skbuff_head_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/fuse_inode', 0o775)
+f('sys/kernel/slab/fuse_inode/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/fuse_inode/ctor', 0o664, b'fuse_inode_init_once+0x0/0x10 [fuse]\n')
+f('sys/kernel/slab/fuse_inode/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/fuse_inode/slab_size', 0o664, b'1344\n')
+f('sys/kernel/slab/fuse_inode/total_objects', 0o664, b'12\n')
+f('sys/kernel/slab/fuse_inode/slabs', 0o664, b'1\n')
+f('sys/kernel/slab/fuse_inode/poison', 0o664, b'1\n')
+f('sys/kernel/slab/fuse_inode/alloc_calls', 0o664, b' 1 fuse_alloc_inode+0x1a/0xe0 [fuse] age=8336111 pid=2476 cpus=0\n')
+f('sys/kernel/slab/fuse_inode/objs_per_slab', 0o664, b'12\n')
+f('sys/kernel/slab/fuse_inode/shrink', 0o664, b'')
+f('sys/kernel/slab/fuse_inode/trace', 0o664, b'0\n')
+f('sys/kernel/slab/fuse_inode/object_size', 0o664, b'1248\n')
+f('sys/kernel/slab/fuse_inode/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/fuse_inode/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/fuse_inode/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/fuse_inode/objects_partial', 0o664, b'1\n')
+f('sys/kernel/slab/fuse_inode/objects', 0o664, b'1\n')
+f('sys/kernel/slab/fuse_inode/order', 0o664, b'2\n')
+f('sys/kernel/slab/fuse_inode/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/fuse_inode/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/fuse_inode/align', 0o664, b'0\n')
+f('sys/kernel/slab/fuse_inode/partial', 0o664, b'1\n')
+f('sys/kernel/slab/fuse_inode/validate', 0o664, b'')
+f('sys/kernel/slab/fuse_inode/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/fuse_inode/free_calls', 0o664, b' 1 <not-available> age=4303047710 pid=0 cpus=0\n')
+f('sys/kernel/slab/fuse_inode/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/skbuff_fclone_cache', 0o775)
+f('sys/kernel/slab/skbuff_fclone_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/skbuff_fclone_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/skbuff_fclone_cache/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/skbuff_fclone_cache/slab_size', 0o664, b'512\n')
+f('sys/kernel/slab/skbuff_fclone_cache/total_objects', 0o664, b'32\n')
+f('sys/kernel/slab/skbuff_fclone_cache/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/skbuff_fclone_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/skbuff_fclone_cache/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/skbuff_fclone_cache/objs_per_slab', 0o664, b'16\n')
+f('sys/kernel/slab/skbuff_fclone_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/skbuff_fclone_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/skbuff_fclone_cache/object_size', 0o664, b'420\n')
+f('sys/kernel/slab/skbuff_fclone_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/skbuff_fclone_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/skbuff_fclone_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/skbuff_fclone_cache/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/skbuff_fclone_cache/objects', 0o664, b'32\n')
+f('sys/kernel/slab/skbuff_fclone_cache/order', 0o664, b'1\n')
+f('sys/kernel/slab/skbuff_fclone_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/skbuff_fclone_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/skbuff_fclone_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/skbuff_fclone_cache/partial', 0o664, b'0\n')
+f('sys/kernel/slab/skbuff_fclone_cache/validate', 0o664, b'')
+f('sys/kernel/slab/skbuff_fclone_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/skbuff_fclone_cache/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/skbuff_fclone_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/buffer_head', 0o775)
+f('sys/kernel/slab/buffer_head/reclaim_account', 0o664, b'1\n')
+f('sys/kernel/slab/buffer_head/ctor', 0o664, b'init_buffer_head+0x0/0x20\n')
+f('sys/kernel/slab/buffer_head/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/buffer_head/slab_size', 0o664, b'176\n')
+f('sys/kernel/slab/buffer_head/total_objects', 0o664, b'31487\n')
+f('sys/kernel/slab/buffer_head/slabs', 0o664, b'1369\n')
+f('sys/kernel/slab/buffer_head/poison', 0o664, b'1\n')
+f('sys/kernel/slab/buffer_head/alloc_calls', 0o664, b' 31488 alloc_buffer_head+0x19/0x50 age=1/3079345/8378152 pid=1-32767 cpus=0-1\n')
+f('sys/kernel/slab/buffer_head/objs_per_slab', 0o664, b'23\n')
+f('sys/kernel/slab/buffer_head/shrink', 0o664, b'')
+f('sys/kernel/slab/buffer_head/trace', 0o664, b'0\n')
+f('sys/kernel/slab/buffer_head/object_size', 0o664, b'104\n')
+f('sys/kernel/slab/buffer_head/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/buffer_head/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/buffer_head/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/buffer_head/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/buffer_head/objects', 0o664, b'31487\n')
+f('sys/kernel/slab/buffer_head/order', 0o664, b'0\n')
+f('sys/kernel/slab/buffer_head/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/buffer_head/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/buffer_head/align', 0o664, b'0\n')
+f('sys/kernel/slab/buffer_head/partial', 0o664, b'0\n')
+f('sys/kernel/slab/buffer_head/validate', 0o664, b'')
+f('sys/kernel/slab/buffer_head/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/buffer_head/free_calls', 0o664, b''' 14436 <not-available> age=4303047199 pid=0 cpus=0
+ 17053 free_buffer_head+0x20/0x40 age=1227/1928220/8379062 pid=1-32759 cpus=0-1
+''')
+f('sys/kernel/slab/buffer_head/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/blkdev_queue', 0o775)
+f('sys/kernel/slab/blkdev_queue/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/blkdev_queue/ctor', 0o664, b'')
+f('sys/kernel/slab/blkdev_queue/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/blkdev_queue/slab_size', 0o664, b'2496\n')
+f('sys/kernel/slab/blkdev_queue/total_objects', 0o664, b'26\n')
+f('sys/kernel/slab/blkdev_queue/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/blkdev_queue/poison', 0o664, b'1\n')
+f('sys/kernel/slab/blkdev_queue/alloc_calls', 0o664, b' 12 blk_alloc_queue_node+0x1c/0xc0 age=61520/7678497/8378855 pid=1-13295 cpus=0-1\n')
+f('sys/kernel/slab/blkdev_queue/objs_per_slab', 0o664, b'13\n')
+f('sys/kernel/slab/blkdev_queue/shrink', 0o664, b'')
+f('sys/kernel/slab/blkdev_queue/trace', 0o664, b'0\n')
+f('sys/kernel/slab/blkdev_queue/object_size', 0o664, b'2424\n')
+f('sys/kernel/slab/blkdev_queue/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/blkdev_queue/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/blkdev_queue/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/blkdev_queue/objects_partial', 0o664, b'10\n')
+f('sys/kernel/slab/blkdev_queue/objects', 0o664, b'23\n')
+f('sys/kernel/slab/blkdev_queue/order', 0o664, b'3\n')
+f('sys/kernel/slab/blkdev_queue/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/blkdev_queue/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/blkdev_queue/align', 0o664, b'0\n')
+f('sys/kernel/slab/blkdev_queue/partial', 0o664, b'1\n')
+f('sys/kernel/slab/blkdev_queue/validate', 0o664, b'')
+f('sys/kernel/slab/blkdev_queue/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/blkdev_queue/free_calls', 0o664, b' 12 <not-available> age=4303046873 pid=0 cpus=0\n')
+f('sys/kernel/slab/blkdev_queue/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/RAW', 0o775)
+f('sys/kernel/slab/RAW/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/RAW/ctor', 0o664, b'')
+f('sys/kernel/slab/RAW/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/RAW/slab_size', 0o664, b'1280\n')
+f('sys/kernel/slab/RAW/total_objects', 0o664, b'12\n')
+f('sys/kernel/slab/RAW/slabs', 0o664, b'1\n')
+f('sys/kernel/slab/RAW/poison', 0o664, b'1\n')
+f('sys/kernel/slab/RAW/alloc_calls', 0o664, b' 3 sk_prot_alloc+0x1e/0xb0 age=8379168/8379171/8379177 pid=1 cpus=0\n')
+f('sys/kernel/slab/RAW/objs_per_slab', 0o664, b'12\n')
+f('sys/kernel/slab/RAW/shrink', 0o664, b'')
+f('sys/kernel/slab/RAW/trace', 0o664, b'0\n')
+f('sys/kernel/slab/RAW/object_size', 0o664, b'1208\n')
+f('sys/kernel/slab/RAW/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/RAW/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/RAW/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/RAW/objects_partial', 0o664, b'3\n')
+f('sys/kernel/slab/RAW/objects', 0o664, b'3\n')
+f('sys/kernel/slab/RAW/order', 0o664, b'2\n')
+f('sys/kernel/slab/RAW/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/RAW/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/RAW/align', 0o664, b'0\n')
+f('sys/kernel/slab/RAW/partial', 0o664, b'1\n')
+f('sys/kernel/slab/RAW/validate', 0o664, b'')
+f('sys/kernel/slab/RAW/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/RAW/free_calls', 0o664, b' 3 <not-available> age=4303046751 pid=0 cpus=0\n')
+f('sys/kernel/slab/RAW/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/blkdev_ioc', 0o775)
+f('sys/kernel/slab/blkdev_ioc/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/blkdev_ioc/ctor', 0o664, b'')
+f('sys/kernel/slab/blkdev_ioc/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/blkdev_ioc/slab_size', 0o664, b'200\n')
+f('sys/kernel/slab/blkdev_ioc/total_objects', 0o664, b'100\n')
+f('sys/kernel/slab/blkdev_ioc/slabs', 0o664, b'5\n')
+f('sys/kernel/slab/blkdev_ioc/poison', 0o664, b'1\n')
+f('sys/kernel/slab/blkdev_ioc/alloc_calls', 0o664, b' 64 alloc_io_context+0x19/0xa0 age=3410/8058449/8378873 pid=1-13466 cpus=0-1\n')
+f('sys/kernel/slab/blkdev_ioc/objs_per_slab', 0o664, b'20\n')
+f('sys/kernel/slab/blkdev_ioc/shrink', 0o664, b'')
+f('sys/kernel/slab/blkdev_ioc/trace', 0o664, b'0\n')
+f('sys/kernel/slab/blkdev_ioc/object_size', 0o664, b'128\n')
+f('sys/kernel/slab/blkdev_ioc/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/blkdev_ioc/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/blkdev_ioc/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/blkdev_ioc/objects_partial', 0o664, b'38\n')
+f('sys/kernel/slab/blkdev_ioc/objects', 0o664, b'98\n')
+f('sys/kernel/slab/blkdev_ioc/order', 0o664, b'0\n')
+f('sys/kernel/slab/blkdev_ioc/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/blkdev_ioc/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/blkdev_ioc/align', 0o664, b'0\n')
+f('sys/kernel/slab/blkdev_ioc/partial', 0o664, b'2\n')
+f('sys/kernel/slab/blkdev_ioc/validate', 0o664, b'')
+f('sys/kernel/slab/blkdev_ioc/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/blkdev_ioc/free_calls', 0o664, b''' 9 <not-available> age=4303046891 pid=0 cpus=0
+ 55 put_io_context+0xb2/0xd0 age=45025/8043308/8374605 pid=145-13349 cpus=0-1
+''')
+f('sys/kernel/slab/blkdev_ioc/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/sigqueue', 0o775)
+f('sys/kernel/slab/sigqueue/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/sigqueue/ctor', 0o664, b'')
+f('sys/kernel/slab/sigqueue/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/sigqueue/slab_size', 0o664, b'232\n')
+f('sys/kernel/slab/sigqueue/total_objects', 0o664, b'34\n')
+f('sys/kernel/slab/sigqueue/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/sigqueue/poison', 0o664, b'1\n')
+f('sys/kernel/slab/sigqueue/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/sigqueue/objs_per_slab', 0o664, b'17\n')
+f('sys/kernel/slab/sigqueue/shrink', 0o664, b'')
+f('sys/kernel/slab/sigqueue/trace', 0o664, b'0\n')
+f('sys/kernel/slab/sigqueue/object_size', 0o664, b'160\n')
+f('sys/kernel/slab/sigqueue/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/sigqueue/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/sigqueue/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/sigqueue/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/sigqueue/objects', 0o664, b'34\n')
+f('sys/kernel/slab/sigqueue/order', 0o664, b'0\n')
+f('sys/kernel/slab/sigqueue/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/sigqueue/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/sigqueue/align', 0o664, b'8\n')
+f('sys/kernel/slab/sigqueue/partial', 0o664, b'0\n')
+f('sys/kernel/slab/sigqueue/validate', 0o664, b'')
+f('sys/kernel/slab/sigqueue/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/sigqueue/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/sigqueue/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/TCPv6', 0o775)
+f('sys/kernel/slab/TCPv6/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/TCPv6/ctor', 0o664, b'')
+f('sys/kernel/slab/TCPv6/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/TCPv6/slab_size', 0o664, b'2432\n')
+f('sys/kernel/slab/TCPv6/total_objects', 0o664, b'26\n')
+f('sys/kernel/slab/TCPv6/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/TCPv6/poison', 0o664, b'1\n')
+f('sys/kernel/slab/TCPv6/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/TCPv6/objs_per_slab', 0o664, b'13\n')
+f('sys/kernel/slab/TCPv6/shrink', 0o664, b'')
+f('sys/kernel/slab/TCPv6/trace', 0o664, b'0\n')
+f('sys/kernel/slab/TCPv6/object_size', 0o664, b'2336\n')
+f('sys/kernel/slab/TCPv6/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/TCPv6/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/TCPv6/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/TCPv6/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/TCPv6/objects', 0o664, b'26\n')
+f('sys/kernel/slab/TCPv6/order', 0o664, b'3\n')
+f('sys/kernel/slab/TCPv6/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/TCPv6/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/TCPv6/align', 0o664, b'0\n')
+f('sys/kernel/slab/TCPv6/partial', 0o664, b'0\n')
+f('sys/kernel/slab/TCPv6/validate', 0o664, b'')
+f('sys/kernel/slab/TCPv6/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/TCPv6/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/TCPv6/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/kioctx', 0o775)
+f('sys/kernel/slab/kioctx/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/kioctx/ctor', 0o664, b'')
+f('sys/kernel/slab/kioctx/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/kioctx/slab_size', 0o664, b'640\n')
+f('sys/kernel/slab/kioctx/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/kioctx/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/kioctx/poison', 0o664, b'1\n')
+f('sys/kernel/slab/kioctx/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/kioctx/objs_per_slab', 0o664, b'12\n')
+f('sys/kernel/slab/kioctx/shrink', 0o664, b'')
+f('sys/kernel/slab/kioctx/trace', 0o664, b'0\n')
+f('sys/kernel/slab/kioctx/object_size', 0o664, b'512\n')
+f('sys/kernel/slab/kioctx/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/kioctx/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/kioctx/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/kioctx/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/kioctx/objects', 0o664, b'0\n')
+f('sys/kernel/slab/kioctx/order', 0o664, b'1\n')
+f('sys/kernel/slab/kioctx/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/kioctx/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/kioctx/align', 0o664, b'8\n')
+f('sys/kernel/slab/kioctx/partial', 0o664, b'0\n')
+f('sys/kernel/slab/kioctx/validate', 0o664, b'')
+f('sys/kernel/slab/kioctx/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/kioctx/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/kioctx/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/kmalloc-32', 0o775)
+f('sys/kernel/slab/kmalloc-32/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-32/ctor', 0o664, b'')
+f('sys/kernel/slab/kmalloc-32/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-32/slab_size', 0o664, b'104\n')
+f('sys/kernel/slab/kmalloc-32/total_objects', 0o664, b'624\n')
+f('sys/kernel/slab/kmalloc-32/slabs', 0o664, b'16\n')
+f('sys/kernel/slab/kmalloc-32/poison', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-32/alloc_calls', 0o664, b''' 1 mtrr_file_add+0xb0/0xe0 age=8355511 pid=1738 cpus=0
+ 2 arch_acpi_processor_init_pdc+0x8e/0x180 age=8375727/8375758/8375789 pid=330 cpus=0
+ 1 pm_qos_add_requirement+0x34/0xe0 age=8376080 pid=122 cpus=1
+ 59 setup_modinfo_srcversion+0x19/0x30 age=8303075/8368435/8376316 pid=105-2754 cpus=0-1
+ 42 load_module+0x1455/0x1b30 age=8303075/8366312/8375832 pid=107-2754 cpus=0-1
+ 151 load_module+0x1ac4/0x1b30 age=8303071/8368871/8376310 pid=105-2754 cpus=0-1
+ 3 mempool_create_node+0x4b/0xf0 age=62046/5606826/8379381 pid=1-13295 cpus=0-1
+ 1 strndup_user+0x6d/0xc0 age=8374925 pid=107 cpus=0
+ 16 __vmalloc_area_node+0xfb/0x140 age=8328464/8366300/8376086 pid=107-2578 cpus=0-1
+ 1 do_kern_mount+0xca/0x110 age=8335800 pid=2476 cpus=0
+ 1 do_sys_poll+0xdb/0x450 age=1303 pid=1333 cpus=1
+ 1 alloc_vfsmnt+0x97/0x180 age=8335801 pid=2476 cpus=0
+ 1 single_open+0x3c/0xb0 age=8355816 pid=1738 cpus=0
+ 66 sysfs_new_dirent+0x10c/0x120 age=8360190/8377926/8379815 pid=1-1549 cpus=0-1
+ 30 do_shmat+0x169/0x410 age=8274161/8330033/8348616 pid=1738-2621 cpus=0-1
+ 21 register_blkdev+0x60/0x150 age=8369695/8377753/8379765 pid=1-951 cpus=0-1
+ 39 kvasprintf+0x55/0x90 age=8360190/8378048/8379814 pid=1-1549 cpus=0-1
+ 7 pci_save_state+0x1a4/0x250 age=8373637/8378406/8379803 pid=1-126 cpus=0-1
+ 2 pcim_enable_device+0x86/0xb0 age=8379255/8379510/8379765 pid=1 cpus=0-1
+ 15 acpi_ds_build_internal_package_obj+0xaf/0x1df age=8379932/8379938/8379947 pid=1 cpus=0
+ 21 acpi_ds_build_internal_buffer_obj+0xe1/0x121 age=3847501/7731852/8379949 pid=1-330 cpus=0
+ 1 acpi_install_gpe_handler+0xa7/0x13a age=8379959 pid=1 cpus=0
+ 1 acpi_ev_create_gpe_block+0x282/0x3bf age=8379959 pid=1 cpus=0
+ 1 acpi_pci_bind_root+0x8d/0x13e age=8379883 pid=1 cpus=0
+ 18 acpi_pci_bind+0x85/0x28d age=8379879/8379879/8379882 pid=1 cpus=0
+ 15 rand_initialize_disk+0x1d/0x30 age=62014/7263977/8379377 pid=1-13295 cpus=0-1
+ 1 ata_host_start+0xcb/0x1e0 age=8379764 pid=1 cpus=1
+ 1 hidinput_connect+0x2372/0x24e0 age=53529 pid=419 cpus=0
+ 1 sock_kmalloc+0x5c/0x70 age=8325518 pid=1849 cpus=1
+ 2 proto_register+0x7c/0x260 age=8360191/8370012/8379834 pid=1-1549 cpus=0
+ 2 neigh_hash_alloc+0x42/0x50 age=8325417/8327412/8329408 pid=0-1849 cpus=1
+ 1 nl_pid_hash_rehash+0x180/0x1a0 age=947530 pid=1189 cpus=0
+ 28 unix_bind+0xd8/0x3a0 age=8356458/8357177/8366824 pid=1336-1738 cpus=0-1
+ 3 ipc_init_proc_interface+0x2e/0x7c age=8379805/8379805/8379805 pid=1 cpus=1
+ 13 usb_cache_string+0x65/0xa0 [usbcore] age=22649/4521883/8374921 pid=143-419 cpus=0-1
+ 6 usb_get_configuration+0x18f/0x1480 [usbcore] age=67053/6989971/8374921 pid=143-419 cpus=0-1
+ 2 _snd_ctl_register_ioctl+0x2b/0x80 [snd] age=8374675/8374675/8374675 pid=107 cpus=0
+ 2 snd_oss_info_register+0x40/0xc0 [snd] age=8355350/8355452/8355555 pid=1813 cpus=0
+ 6 adjust_io+0xeb/0x120 [rsrc_nonstatic] age=8373110/8373182/8373542 pid=352-800 cpus=0
+ 5 adjust_memory+0xe5/0x1a0 [rsrc_nonstatic] age=8373110/8373278/8373535 pid=352-800 cpus=0
+ 1 ieee80211_sta_set_extra_ie+0x7d/0xe0 [mac80211] age=8329597 pid=1545 cpus=0
+ 2 ieee80211_rx_bss_info+0x4df/0xa20 [mac80211] age=8330170/8342783/8355397 pid=0 cpus=0
+ 2 ieee80211_rx_bss_info+0x568/0xa20 [mac80211] age=22736/4188782/8354829 pid=742-1951 cpus=0
+ 2 ieee80211_rx_bss_info+0x5f7/0xa20 [mac80211] age=22736/4189294/8355852 pid=742-1772 cpus=0
+ 1 rate_control_alloc+0x32/0x110 [mac80211] age=8373757 pid=126 cpus=1
+ 2 ieee80211_rate_control_register+0x72/0xf0 [mac80211] age=8374580/8374635/8374690 pid=126 cpus=0-1
+ 2 azx_probe+0x9a4/0xc20 [snd_hda_intel] age=8374165/8374165/8374165 pid=107 cpus=1
+ 1 async_chainiv_givencrypt+0x71/0x110 [crypto_blkcipher] age=8374560 pid=215 cpus=0
+ 1 run+0x66/0x500 [raid1] age=8370114 pid=916 cpus=0
+ 1 acpi_cpufreq_cpu_init+0x4d/0x45c [acpi_cpufreq] age=8366427 pid=1358 cpus=0
+''')
+f('sys/kernel/slab/kmalloc-32/objs_per_slab', 0o664, b'39\n')
+f('sys/kernel/slab/kmalloc-32/shrink', 0o664, b'')
+f('sys/kernel/slab/kmalloc-32/trace', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-32/object_size', 0o664, b'32\n')
+f('sys/kernel/slab/kmalloc-32/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-32/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-32/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-32/objects_partial', 0o664, b'149\n')
+f('sys/kernel/slab/kmalloc-32/objects', 0o664, b'617\n')
+f('sys/kernel/slab/kmalloc-32/order', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-32/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-32/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-32/align', 0o664, b'8\n')
+f('sys/kernel/slab/kmalloc-32/partial', 0o664, b'4\n')
+f('sys/kernel/slab/kmalloc-32/validate', 0o664, b'')
+f('sys/kernel/slab/kmalloc-32/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-32/free_calls', 0o664, b''' 409 <not-available> age=4303047399 pid=0 cpus=0
+ 4 __vunmap+0xe9/0x120 age=8366429/8372533/8374823 pid=215-1358 cpus=0-1
+ 1 vfs_rename+0x301/0x450 age=8274772 pid=2851 cpus=0
+ 8 do_sys_poll+0x32b/0x450 age=1304/6728883/8333312 pid=1333 cpus=0-1
+ 1 seq_release_private+0x2d/0x60 age=8352378 pid=2141 cpus=0
+ 5 single_release+0x2e/0x40 age=8343903/8358822/8366889 pid=1258-1806 cpus=0
+ 1 setxattr+0xa6/0x130 age=8355591 pid=1816 cpus=0
+ 6 bio_free_map_data+0x25/0x30 age=53571/4350975/8375998 pid=0-318 cpus=0
+ 6 remove_kevent+0x44/0x60 age=7219423/7961750/8346613 pid=2271-2423 cpus=0-1
+ 57 load_elf_binary+0xa72/0x1e20 age=22671/8213994/8376585 pid=102-13419 cpus=0-1
+ 1 generic_acl_set+0x15e/0x1a0 age=8355591 pid=1816 cpus=0
+ 67 kobject_uevent_env+0x11a/0x470 age=62016/8246870/8379965 pid=1-13295 cpus=0-1
+ 2 pci_get_subsys+0x74/0xa0 age=8375728/8375759/8375790 pid=330 cpus=0
+ 8 acpi_evaluate_integer+0xbf/0xd1 age=3847577/7810351/8379888 pid=1-2097 cpus=0
+ 3 acpi_ds_create_operand+0x12c/0x209 age=3847578/6867437/8379889 pid=1-2097 cpus=0
+ 3 acpi_ns_get_node+0x92/0xa1 age=8374447/8376288/8379960 pid=1-215 cpus=0-1
+ 5 acpi_ut_delete_internal_obj+0x15f/0x16f age=8366428/8373878/8375771 pid=330-1358 cpus=0
+ 3 acpi_pci_bind+0x277/0x28d age=8379881/8379881/8379883 pid=1 cpus=0
+ 1 get_modalias+0xd4/0x120 age=8355825 pid=1772 cpus=0
+ 2 ioctl_standard_iw_point+0x179/0x350 age=63360/84363/105367 pid=1541 cpus=0
+ 1 pci_bus_assign_resources+0xfe/0x4d0 age=8379836 pid=1 cpus=0
+ 1 sg_clean+0x3e/0x80 [usbcore] age=59566 pid=13294 cpus=0
+ 9 usb_get_device_descriptor+0x9b/0xa0 [usbcore] age=22724/6523118/8374922 pid=143-419 cpus=0-1
+ 1 ieee80211_rx_bss_info+0x552/0xa20 [mac80211] age=22737 pid=742 cpus=0
+ 2 ieee80211_rx_bss_info+0x5e1/0xa20 [mac80211] age=22737/4189295/8355853 pid=742-1772 cpus=0
+''')
+f('sys/kernel/slab/kmalloc-32/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/kmalloc-64', 0o775)
+f('sys/kernel/slab/kmalloc-64/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-64/ctor', 0o664, b'')
+f('sys/kernel/slab/kmalloc-64/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-64/slab_size', 0o664, b'136\n')
+f('sys/kernel/slab/kmalloc-64/total_objects', 0o664, b'15300\n')
+f('sys/kernel/slab/kmalloc-64/slabs', 0o664, b'510\n')
+f('sys/kernel/slab/kmalloc-64/poison', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-64/alloc_calls', 0o664, b''' 30 alternatives_smp_module_add+0x81/0x160 age=8303055/8368397/8380085 pid=0-2754 cpus=0-1
+ 39 __request_region+0x39/0x120 age=8373811/8378273/8379949 pid=1-352 cpus=0-1
+ 1 audit_log_start+0x353/0x3f0 age=8379797 pid=1 cpus=1
+ 16 request_irq+0x9a/0xf0 age=8356279/8374005/8379942 pid=1-1541 cpus=0-1
+ 3 devm_request_irq+0x4b/0xc0 age=8379232/8379403/8379747 pid=1 cpus=0-1
+ 1 strndup_user+0x6d/0xc0 age=8374545 pid=215 cpus=0
+ 95 __get_vm_area_node+0x9b/0x220 age=8303058/8371551/8380085 pid=0-2754 cpus=0-1
+ 17 __vmalloc_area_node+0xfb/0x140 age=8309125/8366469/8376299 pid=105-2711 cpus=0-1
+ 1 add_swap_extent+0x57/0xc0 age=8372039 pid=867 cpus=0
+ 33 dma_pool_alloc+0x6d/0x200 age=8309120/8340771/8374904 pid=143-2711 cpus=0-1
+ 40 alloc_kmem_cache_cpu+0x81/0x90 age=8360159/8368022/8379787 pid=1-1549 cpus=0-1
+ 164 __percpu_alloc_mask+0x52/0x140 age=61997/8067718/8380085 pid=0-13295 cpus=0-1
+ 184 __percpu_alloc_mask+0xbc/0x140 age=62029/8100825/8380085 pid=0-13295 cpus=0-1
+ 604 d_alloc+0x19d/0x1f0 age=22685/7859083/8376462 pid=72-24701 cpus=0-1
+ 17 alloc_fdtable+0x57/0x160 age=4267/6101781/8357279 pid=1532-12336 cpus=0-1
+ 17 alloc_fdtable+0xb4/0x160 age=4267/6101781/8357279 pid=1532-12336 cpus=0-1
+ 1 bioset_create+0x21/0xc0 age=8379947 pid=1 cpus=0
+ 1 bd_claim_by_disk+0x6f/0x270 age=8370131 pid=916 cpus=0
+ 14 posix_acl_alloc+0x1b/0x30 age=53326/7759393/8352180 pid=2175-13390 cpus=0-1
+ 5 proc_reg_open+0x3f/0x170 age=8355799/8361268/8366755 pid=1327-1738 cpus=0
+ 12754 ext3_init_block_alloc_info+0x22/0x80 age=1/498494/8368528 pid=1-23373 cpus=0-1
+ 4 ext3_readdir+0x617/0x650 age=8352064/8352079/8352114 pid=1370 cpus=0
+ 8 ext3_htree_store_dirent+0x37/0x130 age=8352064/8352072/8352099 pid=1370 cpus=0
+ 277 kobject_create+0x1a/0x40 age=22618/7771015/8380085 pid=0-13295 cpus=0-1
+ 1 pci_create_sysfs_dev_files+0x23e/0x3b0 age=8378937 pid=1 cpus=0
+ 11 acpi_os_validate_address+0x3d/0xa3 age=8379914/8379927/8379932 pid=1 cpus=0
+ 124 acpi_ds_build_internal_package_obj+0xaf/0x1df age=3847484/8233379/8379936 pid=1-330 cpus=0
+ 6 acpi_ds_build_internal_buffer_obj+0xe1/0x121 age=8379920/8379925/8379934 pid=1 cpus=0
+ 1 acpi_ev_system_memory_region_setup+0x68/0x8f age=8379914 pid=1 cpus=0
+ 3 acpi_add_single_object+0x596/0xd3c age=8379878/8379880/8379882 pid=1 cpus=0
+ 3 acpi_add_single_object+0x5d8/0xd3c age=8379886/8379888/8379890 pid=1 cpus=0
+ 27 acpi_add_single_object+0x9f7/0xd3c age=8379871/8379888/8379900 pid=1 cpus=0
+ 55 acpi_ec_add_query_handler+0x31/0x91 age=8379870/8379870/8379870 pid=1 cpus=0
+ 1 find_dock+0x2c9/0x426 age=8379950 pid=1 cpus=0
+ 6 find_dock_devices+0x5e/0x92 age=8379950/8379950/8379950 pid=1 cpus=0
+ 8 acpi_pci_link_add+0x32/0x1db age=8379843/8379844/8379846 pid=1 cpus=0
+ 39 acpi_pci_irq_add_prt+0x181/0x324 age=8379862/8379863/8379865 pid=1 cpus=0
+ 15 init_dev+0x3c8/0x6f0 age=7217158/8282400/8378180 pid=33-2593 cpus=0-1
+ 15 init_dev+0x437/0x6f0 age=7217158/8282400/8378180 pid=33-2593 cpus=0-1
+ 3 init_dev+0x5b2/0x6f0 age=7217158/7969269/8364358 pid=1258-2593 cpus=0-1
+ 3 init_dev+0x637/0x6f0 age=7217158/7969269/8364358 pid=1258-2593 cpus=0-1
+ 2 kobj_map_init+0x36/0xa0 age=8379947/8380016/8380085 pid=0-1 cpus=0
+ 38 kobj_map+0x79/0x1a0 age=61997/7936136/8379947 pid=1-13295 cpus=0-1
+ 3 dmam_alloc_coherent+0x3f/0xa0 age=8379232/8379403/8379747 pid=1 cpus=0-1
+ 1 scsi_probe_and_add_lun+0x65e/0xd80 age=62028 pid=13295 cpus=0
+ 170 scsi_dev_info_list_add+0x3d/0x120 age=8379831/8379831/8379831 pid=1 cpus=0
+ 1 ahci_init_one+0x137/0xcb0 age=8379748 pid=1 cpus=1
+ 1 cpufreq_stat_notifier_policy+0xa1/0x2e0 age=8366410 pid=1358 cpus=0
+ 1 cpufreq_stat_notifier_policy+0x17e/0x2e0 age=8366410 pid=1358 cpus=0
+ 1 hid_parse_report+0xa9/0x2c0 age=53512 pid=419 cpus=0
+ 10 __dev_addr_add+0x69/0xe0 age=8325501/8345496/8360156 pid=8-1849 cpus=0-1
+''')
+f('sys/kernel/slab/kmalloc-64/objs_per_slab', 0o664, b'30\n')
+f('sys/kernel/slab/kmalloc-64/shrink', 0o664, b'')
+f('sys/kernel/slab/kmalloc-64/trace', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-64/object_size', 0o664, b'64\n')
+f('sys/kernel/slab/kmalloc-64/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-64/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-64/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-64/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-64/objects', 0o664, b'15300\n')
+f('sys/kernel/slab/kmalloc-64/order', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-64/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-64/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-64/align', 0o664, b'8\n')
+f('sys/kernel/slab/kmalloc-64/partial', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-64/validate', 0o664, b'')
+f('sys/kernel/slab/kmalloc-64/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-64/free_calls', 0o664, b''' 13029 <not-available> age=4303047386 pid=0 cpus=0
+ 1 iounmap+0xc2/0x100 age=8379917 pid=1 cpus=0
+ 1 memtype_get_idx+0x75/0xc0 age=782 pid=13466 cpus=0
+ 2 __release_region+0xc6/0xd0 age=8379754/8379754/8379754 pid=1 cpus=1
+ 3 __request_region+0x86/0x120 age=8379828/8379828/8379828 pid=1 cpus=0
+ 1 generic_smp_call_function_single_interrupt+0xce/0xe0 age=8355499 pid=0 cpus=1
+ 53 __stop_machine+0x216/0x220 age=8303059/8367652/8376299 pid=105-2754 cpus=0-1
+ 2 free_irq+0xef/0x190 age=8356302/8367658/8379015 pid=1-1541 cpus=0
+ 28 __vunmap+0xcd/0x120 age=8309125/8366969/8376298 pid=105-2711 cpus=0-1
+ 8 __vunmap+0xe9/0x120 age=8328457/8364062/8376068 pid=107-2578 cpus=0-1
+ 1 percpu_free+0x2d/0x60 age=61987 pid=13295 cpus=0
+ 10 do_sys_poll+0x32b/0x450 age=61481/7500944/8334758 pid=1333-2262 cpus=0-1
+ 187 d_callback+0x22/0x40 age=22704/7997936/8376459 pid=0-2156 cpus=0-1
+ 198 free_fdtable_rcu+0x7a/0xb0 age=1292/3883175/8376371 pid=0-13456 cpus=0-1
+ 224 free_fdtable_rcu+0x82/0xb0 age=1292/3491449/8377150 pid=0-13456 cpus=0-1
+ 42 proc_reg_release+0x96/0x120 age=3564/7013222/8376067 pid=126-2586 cpus=0-1
+ 50 proc_reg_open+0x138/0x170 age=656297/2956669/8367924 pid=1184-12336 cpus=0-1
+ 1046 free_rb_tree_fname+0x5c/0xb0 age=5905/4315279/8376402 pid=102-24701 cpus=0-1
+ 79 ext3_htree_free_dir_info+0x19/0x20 age=5905/6235661/8376402 pid=102-24701 cpus=0-1
+ 26 ext3_clear_inode+0xa5/0xb0 age=12954/2421572/8354304 pid=1253-8445 cpus=0-1
+ 1 dynamic_kobj_release+0x2c/0x40 age=8356191 pid=1541 cpus=0
+ 66 kobject_uevent_env+0x11a/0x470 age=22624/7608199/8379955 pid=1-2711 cpus=0-1
+ 16 acpi_ds_call_control_method+0xfe/0x180 age=3020/4710292/8379848 pid=1-13466 cpus=0-1
+ 1 acpi_ev_execute_reg_method+0x129/0x13a age=8379946 pid=1 cpus=0
+ 1 acpi_ev_asynch_execute_gpe_method+0xcc/0x119 age=8379905 pid=12 cpus=1
+ 33 acpi_evaluate_object+0x1ea/0x1fc age=3015/5838124/8379955 pid=1-13466 cpus=0-1
+ 4 acpi_get_object_info+0x1c4/0x1d4 age=8379876/8379888/8379895 pid=1 cpus=0
+ 1 acpi_walk_resources+0xa4/0xbd age=8379755 pid=1 cpus=1
+ 41 acpi_ut_evaluate_object+0x18d/0x19b age=8379223/8379861/8379919 pid=1 cpus=0-1
+ 4 acpi_ut_delete_internal_obj+0x15f/0x16f age=8366416/8373412/8375744 pid=330-1358 cpus=0
+ 7 acpi_bus_get_ejd+0x73/0x80 age=8379955/8379955/8379955 pid=1 cpus=0
+ 11 pnp_show_options+0x459/0x600 age=1578/1602/1627 pid=13466 cpus=0
+ 11 pnp_show_current_resources+0x16f/0x180 age=1578/1603/1628 pid=13466 cpus=0
+ 19 release_one_tty+0x53/0x190 age=804540/7566113/8370327 pid=55-2106 cpus=0-1
+ 24 release_one_tty+0x60/0x190 age=804540/7729452/8370327 pid=55-2141 cpus=0-1
+ 6 release_one_tty+0x167/0x190 age=8352429/8353224/8354794 pid=1967-2141 cpus=0
+ 4 devres_remove_group+0x9e/0xe0 age=8379026/8379313/8379753 pid=1 cpus=0-1
+ 1 ata_acpi_on_devcfg+0x385/0x6a0 age=8379406 pid=25 cpus=0
+ 3 serio_free_event+0x1d/0x30 age=8378463/8378812/8378999 pid=17 cpus=0-1
+ 6 input_register_device+0x17c/0x230 age=53514/6988336/8378983 pid=17-803 cpus=0-1
+ 1 ip_cork_release+0x1f/0x50 age=8333854 pid=2536 cpus=1
+ 1 unix_sock_destructor+0x75/0xd0 age=7217178 pid=2344 cpus=0
+ 13 huft_free+0x1e/0x2f age=8379804/8379804/8379804 pid=1 cpus=0
+ 6 hub_port_init+0x522/0x740 [usbcore] age=22825/4210550/8374275 pid=419 cpus=0-1
+ 1 usb_release_interface_cache+0x2c/0x60 [usbcore] age=8373868 pid=419 cpus=0
+ 1 usb_release_interface_cache+0x47/0x60 [usbcore] age=8373868 pid=419 cpus=0
+ 1 __param_str_act+0x16c/0xfffffffffffffb13 [thermal] age=8375113 pid=383 cpus=0
+ 3 snd_card_file_remove+0x73/0x130 [snd] age=8333050/8337203/8339297 pid=2400-2425 cpus=0
+ 2 hid_probe+0x222/0xf30 [usbhid] age=53517/4212911/8372306 pid=419-803 cpus=0
+''')
+f('sys/kernel/slab/kmalloc-64/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/sgpool-128', 0o775)
+f('sys/kernel/slab/sgpool-128/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-128/ctor', 0o664, b'')
+f('sys/kernel/slab/sgpool-128/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-128/slab_size', 0o664, b'4224\n')
+f('sys/kernel/slab/sgpool-128/total_objects', 0o664, b'14\n')
+f('sys/kernel/slab/sgpool-128/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/sgpool-128/poison', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-128/alloc_calls', 0o664, b' 2 mempool_alloc_slab+0x11/0x20 age=8379262/8379262/8379262 pid=1 cpus=0\n')
+f('sys/kernel/slab/sgpool-128/objs_per_slab', 0o664, b'7\n')
+f('sys/kernel/slab/sgpool-128/shrink', 0o664, b'')
+f('sys/kernel/slab/sgpool-128/trace', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-128/object_size', 0o664, b'4096\n')
+f('sys/kernel/slab/sgpool-128/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-128/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-128/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-128/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-128/objects', 0o664, b'14\n')
+f('sys/kernel/slab/sgpool-128/order', 0o664, b'3\n')
+f('sys/kernel/slab/sgpool-128/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-128/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-128/align', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-128/partial', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-128/validate', 0o664, b'')
+f('sys/kernel/slab/sgpool-128/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-128/free_calls', 0o664, b' 2 <not-available> age=4303046812 pid=0 cpus=0\n')
+f('sys/kernel/slab/sgpool-128/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/kcopyd_job', 0o775)
+f('sys/kernel/slab/kcopyd_job/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/kcopyd_job/ctor', 0o664, b'')
+f('sys/kernel/slab/kcopyd_job/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/kcopyd_job/slab_size', 0o664, b'544\n')
+f('sys/kernel/slab/kcopyd_job/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/kcopyd_job/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/kcopyd_job/poison', 0o664, b'1\n')
+f('sys/kernel/slab/kcopyd_job/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/kcopyd_job/objs_per_slab', 0o664, b'15\n')
+f('sys/kernel/slab/kcopyd_job/shrink', 0o664, b'')
+f('sys/kernel/slab/kcopyd_job/trace', 0o664, b'0\n')
+f('sys/kernel/slab/kcopyd_job/object_size', 0o664, b'472\n')
+f('sys/kernel/slab/kcopyd_job/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/kcopyd_job/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/kcopyd_job/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/kcopyd_job/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/kcopyd_job/objects', 0o664, b'0\n')
+f('sys/kernel/slab/kcopyd_job/order', 0o664, b'1\n')
+f('sys/kernel/slab/kcopyd_job/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/kcopyd_job/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/kcopyd_job/align', 0o664, b'8\n')
+f('sys/kernel/slab/kcopyd_job/partial', 0o664, b'0\n')
+f('sys/kernel/slab/kcopyd_job/validate', 0o664, b'')
+f('sys/kernel/slab/kcopyd_job/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/kcopyd_job/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/kcopyd_job/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/dm_target_io', 0o775)
+f('sys/kernel/slab/dm_target_io/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/dm_target_io/ctor', 0o664, b'')
+f('sys/kernel/slab/dm_target_io/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/dm_target_io/slab_size', 0o664, b'96\n')
+f('sys/kernel/slab/dm_target_io/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/dm_target_io/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/dm_target_io/poison', 0o664, b'1\n')
+f('sys/kernel/slab/dm_target_io/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/dm_target_io/objs_per_slab', 0o664, b'42\n')
+f('sys/kernel/slab/dm_target_io/shrink', 0o664, b'')
+f('sys/kernel/slab/dm_target_io/trace', 0o664, b'0\n')
+f('sys/kernel/slab/dm_target_io/object_size', 0o664, b'24\n')
+f('sys/kernel/slab/dm_target_io/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/dm_target_io/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/dm_target_io/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/dm_target_io/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/dm_target_io/objects', 0o664, b'0\n')
+f('sys/kernel/slab/dm_target_io/order', 0o664, b'0\n')
+f('sys/kernel/slab/dm_target_io/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/dm_target_io/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/dm_target_io/align', 0o664, b'8\n')
+f('sys/kernel/slab/dm_target_io/partial', 0o664, b'0\n')
+f('sys/kernel/slab/dm_target_io/validate', 0o664, b'')
+f('sys/kernel/slab/dm_target_io/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/dm_target_io/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/dm_target_io/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/signal_cache', 0o775)
+f('sys/kernel/slab/signal_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/signal_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/signal_cache/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/signal_cache/slab_size', 0o664, b'1024\n')
+f('sys/kernel/slab/signal_cache/total_objects', 0o664, b'160\n')
+f('sys/kernel/slab/signal_cache/slabs', 0o664, b'10\n')
+f('sys/kernel/slab/signal_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/signal_cache/alloc_calls', 0o664, b' 124 copy_process+0x93c/0x1220 age=4145/7851187/8379914 pid=0-12336 cpus=0-1\n')
+f('sys/kernel/slab/signal_cache/objs_per_slab', 0o664, b'16\n')
+f('sys/kernel/slab/signal_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/signal_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/signal_cache/object_size', 0o664, b'896\n')
+f('sys/kernel/slab/signal_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/signal_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/signal_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/signal_cache/objects_partial', 0o664, b'70\n')
+f('sys/kernel/slab/signal_cache/objects', 0o664, b'150\n')
+f('sys/kernel/slab/signal_cache/order', 0o664, b'2\n')
+f('sys/kernel/slab/signal_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/signal_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/signal_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/signal_cache/partial', 0o664, b'5\n')
+f('sys/kernel/slab/signal_cache/validate', 0o664, b'')
+f('sys/kernel/slab/signal_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/signal_cache/free_calls', 0o664, b''' 42 <not-available> age=4303047259 pid=0 cpus=0
+ 82 __cleanup_signal+0x20/0x30 age=7186/7586663/8375843 pid=1-13288 cpus=0-1
+''')
+f('sys/kernel/slab/signal_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/radix_tree_node', 0o775)
+f('sys/kernel/slab/radix_tree_node/reclaim_account', 0o664, b'1\n')
+f('sys/kernel/slab/radix_tree_node/ctor', 0o664, b'radix_tree_node_ctor+0x0/0x10\n')
+f('sys/kernel/slab/radix_tree_node/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/radix_tree_node/slab_size', 0o664, b'624\n')
+f('sys/kernel/slab/radix_tree_node/total_objects', 0o664, b'6747\n')
+f('sys/kernel/slab/radix_tree_node/slabs', 0o664, b'519\n')
+f('sys/kernel/slab/radix_tree_node/poison', 0o664, b'1\n')
+f('sys/kernel/slab/radix_tree_node/alloc_calls', 0o664, b' 6737 radix_tree_preload+0x3b/0xb0 age=16/6612251/8379044 pid=1-32767 cpus=0-1\n')
+f('sys/kernel/slab/radix_tree_node/objs_per_slab', 0o664, b'13\n')
+f('sys/kernel/slab/radix_tree_node/shrink', 0o664, b'')
+f('sys/kernel/slab/radix_tree_node/trace', 0o664, b'0\n')
+f('sys/kernel/slab/radix_tree_node/object_size', 0o664, b'552\n')
+f('sys/kernel/slab/radix_tree_node/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/radix_tree_node/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/radix_tree_node/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/radix_tree_node/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/radix_tree_node/objects', 0o664, b'6747\n')
+f('sys/kernel/slab/radix_tree_node/order', 0o664, b'1\n')
+f('sys/kernel/slab/radix_tree_node/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/radix_tree_node/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/radix_tree_node/align', 0o664, b'0\n')
+f('sys/kernel/slab/radix_tree_node/partial', 0o664, b'0\n')
+f('sys/kernel/slab/radix_tree_node/validate', 0o664, b'')
+f('sys/kernel/slab/radix_tree_node/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/radix_tree_node/free_calls', 0o664, b''' 4146 <not-available> age=4303047064 pid=0 cpus=0
+ 2591 radix_tree_node_rcu_free+0x41/0x50 age=39290/6239072/8378908 pid=0-32584 cpus=0-1
+''')
+f('sys/kernel/slab/radix_tree_node/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/uid_cache', 0o775)
+f('sys/kernel/slab/uid_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/uid_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/uid_cache/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/uid_cache/slab_size', 0o664, b'320\n')
+f('sys/kernel/slab/uid_cache/total_objects', 0o664, b'24\n')
+f('sys/kernel/slab/uid_cache/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/uid_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/uid_cache/alloc_calls', 0o664, b' 5 alloc_uid+0xbd/0x1e0 age=8351086/8358570/8366097 pid=1333-2177 cpus=0-1\n')
+f('sys/kernel/slab/uid_cache/objs_per_slab', 0o664, b'12\n')
+f('sys/kernel/slab/uid_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/uid_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/uid_cache/object_size', 0o664, b'216\n')
+f('sys/kernel/slab/uid_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/uid_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/uid_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/uid_cache/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/uid_cache/objects', 0o664, b'24\n')
+f('sys/kernel/slab/uid_cache/order', 0o664, b'0\n')
+f('sys/kernel/slab/uid_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/uid_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/uid_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/uid_cache/partial', 0o664, b'0\n')
+f('sys/kernel/slab/uid_cache/validate', 0o664, b'')
+f('sys/kernel/slab/uid_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/uid_cache/free_calls', 0o664, b''' 2 <not-available> age=4303046654 pid=0 cpus=0
+ 3 remove_user_sysfs_dir+0xd0/0x100 age=8357175/8367109/8374935 pid=7 cpus=0
+''')
+f('sys/kernel/slab/uid_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/tw_sock_TCPv6', 0o775)
+f('sys/kernel/slab/tw_sock_TCPv6/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/tw_sock_TCPv6/ctor', 0o664, b'')
+f('sys/kernel/slab/tw_sock_TCPv6/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/tw_sock_TCPv6/slab_size', 0o664, b'256\n')
+f('sys/kernel/slab/tw_sock_TCPv6/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/tw_sock_TCPv6/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/tw_sock_TCPv6/poison', 0o664, b'1\n')
+f('sys/kernel/slab/tw_sock_TCPv6/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/tw_sock_TCPv6/objs_per_slab', 0o664, b'16\n')
+f('sys/kernel/slab/tw_sock_TCPv6/shrink', 0o664, b'')
+f('sys/kernel/slab/tw_sock_TCPv6/trace', 0o664, b'0\n')
+f('sys/kernel/slab/tw_sock_TCPv6/object_size', 0o664, b'168\n')
+f('sys/kernel/slab/tw_sock_TCPv6/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/tw_sock_TCPv6/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/tw_sock_TCPv6/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/tw_sock_TCPv6/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/tw_sock_TCPv6/objects', 0o664, b'0\n')
+f('sys/kernel/slab/tw_sock_TCPv6/order', 0o664, b'0\n')
+f('sys/kernel/slab/tw_sock_TCPv6/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/tw_sock_TCPv6/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/tw_sock_TCPv6/align', 0o664, b'0\n')
+f('sys/kernel/slab/tw_sock_TCPv6/partial', 0o664, b'0\n')
+f('sys/kernel/slab/tw_sock_TCPv6/validate', 0o664, b'')
+f('sys/kernel/slab/tw_sock_TCPv6/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/tw_sock_TCPv6/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/tw_sock_TCPv6/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/sighand_cache', 0o775)
+f('sys/kernel/slab/sighand_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/sighand_cache/ctor', 0o664, b'sighand_ctor+0x0/0x40\n')
+f('sys/kernel/slab/sighand_cache/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/sighand_cache/slab_size', 0o664, b'2304\n')
+f('sys/kernel/slab/sighand_cache/total_objects', 0o664, b'154\n')
+f('sys/kernel/slab/sighand_cache/slabs', 0o664, b'11\n')
+f('sys/kernel/slab/sighand_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/sighand_cache/alloc_calls', 0o664, b''' 123 copy_process+0x82a/0x1220 age=4154/7846897/8379923 pid=0-12336 cpus=0-1
+ 1 flush_old_exec+0x4e1/0x8a0 age=8378174 pid=1 cpus=0
+''')
+f('sys/kernel/slab/sighand_cache/objs_per_slab', 0o664, b'14\n')
+f('sys/kernel/slab/sighand_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/sighand_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/sighand_cache/object_size', 0o664, b'2184\n')
+f('sys/kernel/slab/sighand_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/sighand_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/sighand_cache/destroy_by_rcu', 0o664, b'1\n')
+f('sys/kernel/slab/sighand_cache/objects_partial', 0o664, b'61\n')
+f('sys/kernel/slab/sighand_cache/objects', 0o664, b'145\n')
+f('sys/kernel/slab/sighand_cache/order', 0o664, b'3\n')
+f('sys/kernel/slab/sighand_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/sighand_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/sighand_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/sighand_cache/partial', 0o664, b'5\n')
+f('sys/kernel/slab/sighand_cache/validate', 0o664, b'')
+f('sys/kernel/slab/sighand_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/sighand_cache/free_calls', 0o664, b''' 46 <not-available> age=4303047268 pid=0 cpus=0
+ 78 __cleanup_sighand+0x27/0x30 age=7195/7547046/8375852 pid=1-13288 cpus=0-1
+''')
+f('sys/kernel/slab/sighand_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/names_cache', 0o775)
+f('sys/kernel/slab/names_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/names_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/names_cache/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/names_cache/slab_size', 0o664, b'4224\n')
+f('sys/kernel/slab/names_cache/total_objects', 0o664, b'14\n')
+f('sys/kernel/slab/names_cache/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/names_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/names_cache/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/names_cache/objs_per_slab', 0o664, b'7\n')
+f('sys/kernel/slab/names_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/names_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/names_cache/object_size', 0o664, b'4096\n')
+f('sys/kernel/slab/names_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/names_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/names_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/names_cache/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/names_cache/objects', 0o664, b'14\n')
+f('sys/kernel/slab/names_cache/order', 0o664, b'3\n')
+f('sys/kernel/slab/names_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/names_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/names_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/names_cache/partial', 0o664, b'0\n')
+f('sys/kernel/slab/names_cache/validate', 0o664, b'')
+f('sys/kernel/slab/names_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/names_cache/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/names_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/dm_io', 0o775)
+f('sys/kernel/slab/dm_io/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/dm_io/ctor', 0o664, b'')
+f('sys/kernel/slab/dm_io/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/dm_io/slab_size', 0o664, b'104\n')
+f('sys/kernel/slab/dm_io/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/dm_io/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/dm_io/poison', 0o664, b'1\n')
+f('sys/kernel/slab/dm_io/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/dm_io/objs_per_slab', 0o664, b'39\n')
+f('sys/kernel/slab/dm_io/shrink', 0o664, b'')
+f('sys/kernel/slab/dm_io/trace', 0o664, b'0\n')
+f('sys/kernel/slab/dm_io/object_size', 0o664, b'32\n')
+f('sys/kernel/slab/dm_io/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/dm_io/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/dm_io/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/dm_io/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/dm_io/objects', 0o664, b'0\n')
+f('sys/kernel/slab/dm_io/order', 0o664, b'0\n')
+f('sys/kernel/slab/dm_io/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/dm_io/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/dm_io/align', 0o664, b'8\n')
+f('sys/kernel/slab/dm_io/partial', 0o664, b'0\n')
+f('sys/kernel/slab/dm_io/validate', 0o664, b'')
+f('sys/kernel/slab/dm_io/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/dm_io/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/dm_io/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/key_jar', 0o775)
+f('sys/kernel/slab/key_jar/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/key_jar/ctor', 0o664, b'')
+f('sys/kernel/slab/key_jar/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/key_jar/slab_size', 0o664, b'320\n')
+f('sys/kernel/slab/key_jar/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/key_jar/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/key_jar/poison', 0o664, b'1\n')
+f('sys/kernel/slab/key_jar/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/key_jar/objs_per_slab', 0o664, b'12\n')
+f('sys/kernel/slab/key_jar/shrink', 0o664, b'')
+f('sys/kernel/slab/key_jar/trace', 0o664, b'0\n')
+f('sys/kernel/slab/key_jar/object_size', 0o664, b'232\n')
+f('sys/kernel/slab/key_jar/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/key_jar/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/key_jar/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/key_jar/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/key_jar/objects', 0o664, b'0\n')
+f('sys/kernel/slab/key_jar/order', 0o664, b'0\n')
+f('sys/kernel/slab/key_jar/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/key_jar/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/key_jar/align', 0o664, b'0\n')
+f('sys/kernel/slab/key_jar/partial', 0o664, b'0\n')
+f('sys/kernel/slab/key_jar/validate', 0o664, b'')
+f('sys/kernel/slab/key_jar/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/key_jar/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/key_jar/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/tcp_bind_bucket', 0o775)
+f('sys/kernel/slab/tcp_bind_bucket/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/tcp_bind_bucket/ctor', 0o664, b'')
+f('sys/kernel/slab/tcp_bind_bucket/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/tcp_bind_bucket/slab_size', 0o664, b'128\n')
+f('sys/kernel/slab/tcp_bind_bucket/total_objects', 0o664, b'64\n')
+f('sys/kernel/slab/tcp_bind_bucket/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/tcp_bind_bucket/poison', 0o664, b'1\n')
+f('sys/kernel/slab/tcp_bind_bucket/alloc_calls', 0o664, b' 3 inet_bind_bucket_create+0x27/0x80 age=926731/5878918/8356133 pid=1206-1920 cpus=0\n')
+f('sys/kernel/slab/tcp_bind_bucket/objs_per_slab', 0o664, b'32\n')
+f('sys/kernel/slab/tcp_bind_bucket/shrink', 0o664, b'')
+f('sys/kernel/slab/tcp_bind_bucket/trace', 0o664, b'0\n')
+f('sys/kernel/slab/tcp_bind_bucket/object_size', 0o664, b'40\n')
+f('sys/kernel/slab/tcp_bind_bucket/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/tcp_bind_bucket/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/tcp_bind_bucket/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/tcp_bind_bucket/objects_partial', 0o664, b'2\n')
+f('sys/kernel/slab/tcp_bind_bucket/objects', 0o664, b'34\n')
+f('sys/kernel/slab/tcp_bind_bucket/order', 0o664, b'0\n')
+f('sys/kernel/slab/tcp_bind_bucket/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/tcp_bind_bucket/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/tcp_bind_bucket/align', 0o664, b'0\n')
+f('sys/kernel/slab/tcp_bind_bucket/partial', 0o664, b'1\n')
+f('sys/kernel/slab/tcp_bind_bucket/validate', 0o664, b'')
+f('sys/kernel/slab/tcp_bind_bucket/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/tcp_bind_bucket/free_calls', 0o664, b''' 1 <not-available> age=4303046680 pid=0 cpus=0
+ 2 inet_bind_bucket_destroy+0x29/0x30 age=1107644/4731733/8355822 pid=0-1707 cpus=0
+''')
+f('sys/kernel/slab/tcp_bind_bucket/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/mm_struct', 0o775)
+f('sys/kernel/slab/mm_struct/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/mm_struct/ctor', 0o664, b'')
+f('sys/kernel/slab/mm_struct/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/mm_struct/slab_size', 0o664, b'1216\n')
+f('sys/kernel/slab/mm_struct/total_objects', 0o664, b'91\n')
+f('sys/kernel/slab/mm_struct/slabs', 0o664, b'7\n')
+f('sys/kernel/slab/mm_struct/poison', 0o664, b'1\n')
+f('sys/kernel/slab/mm_struct/alloc_calls', 0o664, b''' 52 mm_alloc+0x15/0x50 age=4100/7453183/8378125 pid=1-20296 cpus=0-1
+ 27 dup_mm+0x61/0x390 age=8335613/8355052/8376513 pid=71-2467 cpus=0-1
+''')
+f('sys/kernel/slab/mm_struct/objs_per_slab', 0o664, b'13\n')
+f('sys/kernel/slab/mm_struct/shrink', 0o664, b'')
+f('sys/kernel/slab/mm_struct/trace', 0o664, b'0\n')
+f('sys/kernel/slab/mm_struct/object_size', 0o664, b'1144\n')
+f('sys/kernel/slab/mm_struct/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/mm_struct/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/mm_struct/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/mm_struct/objects_partial', 0o664, b'23\n')
+f('sys/kernel/slab/mm_struct/objects', 0o664, b'88\n')
+f('sys/kernel/slab/mm_struct/order', 0o664, b'2\n')
+f('sys/kernel/slab/mm_struct/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/mm_struct/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/mm_struct/align', 0o664, b'0\n')
+f('sys/kernel/slab/mm_struct/partial', 0o664, b'2\n')
+f('sys/kernel/slab/mm_struct/validate', 0o664, b'')
+f('sys/kernel/slab/mm_struct/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/mm_struct/free_calls', 0o664, b''' 6 <not-available> age=4303047216 pid=0 cpus=0
+ 73 __mmdrop+0x47/0x60 age=7143/7714522/8376982 pid=1-20295 cpus=0-1
+''')
+f('sys/kernel/slab/mm_struct/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/dentry', 0o775)
+f('sys/kernel/slab/dentry/reclaim_account', 0o664, b'1\n')
+f('sys/kernel/slab/dentry/ctor', 0o664, b'')
+f('sys/kernel/slab/dentry/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/dentry/slab_size', 0o664, b'328\n')
+f('sys/kernel/slab/dentry/total_objects', 0o664, b'49656\n')
+f('sys/kernel/slab/dentry/slabs', 0o664, b'4138\n')
+f('sys/kernel/slab/dentry/poison', 0o664, b'1\n')
+f('sys/kernel/slab/dentry/alloc_calls', 0o664, b' 49656 d_alloc+0x22/0x1f0 age=0/4250434/8379825 pid=0-32757 cpus=0-1\n')
+f('sys/kernel/slab/dentry/objs_per_slab', 0o664, b'12\n')
+f('sys/kernel/slab/dentry/shrink', 0o664, b'')
+f('sys/kernel/slab/dentry/trace', 0o664, b'0\n')
+f('sys/kernel/slab/dentry/object_size', 0o664, b'256\n')
+f('sys/kernel/slab/dentry/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/dentry/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/dentry/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/dentry/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/dentry/objects', 0o664, b'49656\n')
+f('sys/kernel/slab/dentry/order', 0o664, b'0\n')
+f('sys/kernel/slab/dentry/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/dentry/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/dentry/align', 0o664, b'8\n')
+f('sys/kernel/slab/dentry/partial', 0o664, b'0\n')
+f('sys/kernel/slab/dentry/validate', 0o664, b'')
+f('sys/kernel/slab/dentry/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/dentry/free_calls', 0o664, b''' 30093 <not-available> age=4303047137 pid=0 cpus=0
+ 2265 d_free+0x6c/0x80 age=519/5532797/8376904 pid=1-32728 cpus=0-1
+ 17299 d_callback+0x31/0x40 age=1040/2433896/8379551 pid=0-30210 cpus=0-1
+''')
+f('sys/kernel/slab/dentry/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/UDPv6', 0o775)
+f('sys/kernel/slab/UDPv6/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/UDPv6/ctor', 0o664, b'')
+f('sys/kernel/slab/UDPv6/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/UDPv6/slab_size', 0o664, b'1472\n')
+f('sys/kernel/slab/UDPv6/total_objects', 0o664, b'22\n')
+f('sys/kernel/slab/UDPv6/slabs', 0o664, b'1\n')
+f('sys/kernel/slab/UDPv6/poison', 0o664, b'1\n')
+f('sys/kernel/slab/UDPv6/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/UDPv6/objs_per_slab', 0o664, b'22\n')
+f('sys/kernel/slab/UDPv6/shrink', 0o664, b'')
+f('sys/kernel/slab/UDPv6/trace', 0o664, b'0\n')
+f('sys/kernel/slab/UDPv6/object_size', 0o664, b'1368\n')
+f('sys/kernel/slab/UDPv6/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/UDPv6/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/UDPv6/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/UDPv6/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/UDPv6/objects', 0o664, b'22\n')
+f('sys/kernel/slab/UDPv6/order', 0o664, b'3\n')
+f('sys/kernel/slab/UDPv6/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/UDPv6/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/UDPv6/align', 0o664, b'0\n')
+f('sys/kernel/slab/UDPv6/partial', 0o664, b'0\n')
+f('sys/kernel/slab/UDPv6/validate', 0o664, b'')
+f('sys/kernel/slab/UDPv6/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/UDPv6/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/UDPv6/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/mqueue_inode_cache', 0o775)
+f('sys/kernel/slab/mqueue_inode_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/mqueue_inode_cache/ctor', 0o664, b'init_once+0x0/0x10\n')
+f('sys/kernel/slab/mqueue_inode_cache/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/mqueue_inode_cache/slab_size', 0o664, b'1536\n')
+f('sys/kernel/slab/mqueue_inode_cache/total_objects', 0o664, b'21\n')
+f('sys/kernel/slab/mqueue_inode_cache/slabs', 0o664, b'1\n')
+f('sys/kernel/slab/mqueue_inode_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/mqueue_inode_cache/alloc_calls', 0o664, b' 1 mqueue_alloc_inode+0x15/0x30 age=8380010 pid=1 cpus=1\n')
+f('sys/kernel/slab/mqueue_inode_cache/objs_per_slab', 0o664, b'21\n')
+f('sys/kernel/slab/mqueue_inode_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/mqueue_inode_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/mqueue_inode_cache/object_size', 0o664, b'1456\n')
+f('sys/kernel/slab/mqueue_inode_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/mqueue_inode_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/mqueue_inode_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/mqueue_inode_cache/objects_partial', 0o664, b'1\n')
+f('sys/kernel/slab/mqueue_inode_cache/objects', 0o664, b'1\n')
+f('sys/kernel/slab/mqueue_inode_cache/order', 0o664, b'3\n')
+f('sys/kernel/slab/mqueue_inode_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/mqueue_inode_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/mqueue_inode_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/mqueue_inode_cache/partial', 0o664, b'1\n')
+f('sys/kernel/slab/mqueue_inode_cache/validate', 0o664, b'')
+f('sys/kernel/slab/mqueue_inode_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/mqueue_inode_cache/free_calls', 0o664, b' 1 <not-available> age=4303047603 pid=0 cpus=0\n')
+f('sys/kernel/slab/mqueue_inode_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/biovec-128', 0o775)
+f('sys/kernel/slab/biovec-128/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-128/ctor', 0o664, b'')
+f('sys/kernel/slab/biovec-128/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-128/slab_size', 0o664, b'2176\n')
+f('sys/kernel/slab/biovec-128/total_objects', 0o664, b'15\n')
+f('sys/kernel/slab/biovec-128/slabs', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-128/poison', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-128/alloc_calls', 0o664, b' 2 mempool_alloc_slab+0x11/0x20 age=8379474/8379474/8379474 pid=1 cpus=0\n')
+f('sys/kernel/slab/biovec-128/objs_per_slab', 0o664, b'15\n')
+f('sys/kernel/slab/biovec-128/shrink', 0o664, b'')
+f('sys/kernel/slab/biovec-128/trace', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-128/object_size', 0o664, b'2048\n')
+f('sys/kernel/slab/biovec-128/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-128/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-128/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-128/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-128/objects', 0o664, b'15\n')
+f('sys/kernel/slab/biovec-128/order', 0o664, b'3\n')
+f('sys/kernel/slab/biovec-128/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-128/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-128/align', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-128/partial', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-128/validate', 0o664, b'')
+f('sys/kernel/slab/biovec-128/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-128/free_calls', 0o664, b' 2 <not-available> age=4303046908 pid=0 cpus=0\n')
+f('sys/kernel/slab/biovec-128/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/kmalloc-192', 0o775)
+f('sys/kernel/slab/kmalloc-192/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-192/ctor', 0o664, b'')
+f('sys/kernel/slab/kmalloc-192/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-192/slab_size', 0o664, b'264\n')
+f('sys/kernel/slab/kmalloc-192/total_objects', 0o664, b'255\n')
+f('sys/kernel/slab/kmalloc-192/slabs', 0o664, b'17\n')
+f('sys/kernel/slab/kmalloc-192/poison', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-192/alloc_calls', 0o664, b''' 10 sched_create_group+0x91/0x220 age=8351861/8359345/8366872 pid=1333-2177 cpus=0-1
+ 10 sched_create_group+0xae/0x220 age=8351861/8359345/8366872 pid=1333-2177 cpus=0-1
+ 10 groups_alloc+0x41/0xe0 age=17070/6159814/8366872 pid=1333-20296 cpus=0-1
+ 9 param_sysfs_setup+0x87/0x140 age=8303102/8368759/8379996 pid=1-2754 cpus=0-1
+ 2 futex_lock_pi+0x776/0xb00 age=125614/1986240/3846867 pid=2411-13213 cpus=0-1
+ 18 mempool_create_node+0x2e/0xf0 age=62077/7917175/8379995 pid=1-13295 cpus=0-1
+ 4 __vmalloc_area_node+0xfb/0x140 age=8370390/8373664/8374956 pid=107-901 cpus=0
+ 30 __percpu_alloc_mask+0xbc/0x140 age=8370400/8377809/8380000 pid=1-900 cpus=0-1
+ 4 d_alloc+0x19d/0x1f0 age=61160/6282991/8356935 pid=1706-13349 cpus=0-1
+ 1 bm_register_write+0x63/0x630 age=8354110 pid=2054 cpus=1
+ 1 sysfs_open_file+0xd6/0x230 age=0 pid=13466 cpus=0
+ 15 ipc_rcu_alloc+0x4a/0x70 age=8274192/8330064/8348647 pid=2177-2621 cpus=0-1
+ 28 kset_create_and_add+0x35/0xa0 age=8355999/8378311/8380000 pid=1-1766 cpus=0-1
+ 1 acpi_ds_build_internal_package_obj+0xaf/0x1df age=8379979 pid=1 cpus=0
+ 3 acpi_ds_build_internal_buffer_obj+0xe1/0x121 age=8379976/8379976/8379977 pid=1 cpus=0
+ 1 acpi_power_add+0x4a/0x1d6 age=8379890 pid=1 cpus=0
+ 2 ata_host_alloc+0x4f/0xf0 age=8379280/8379538/8379796 pid=1 cpus=0-1
+ 8 cpuidle_add_state_sysfs+0xc3/0x140 age=125753/125759/125766 pid=13 cpus=0-1
+ 1 hid_parse_report+0x43/0x2c0 age=53560 pid=419 cpus=0
+ 2 hid_add_field+0x18a/0x3a0 age=53560/53560/53560 pid=419 cpus=0
+ 6 fib_create_info+0x61/0x970 age=8324536/8346547/8367903 pid=1197-1541 cpus=0-1
+ 1 unix_sysctl_register+0x2a/0x80 age=8379847 pid=1 cpus=0
+ 1 rtnetlink_init+0x38/0x113 age=8379999 pid=1 cpus=0
+ 1 inet_diag_init+0x15/0x6b age=8378998 pid=1 cpus=0
+ 41 usb_alloc_urb+0x19/0x50 [usbcore] age=22746/1043846/8374920 pid=143-419 cpus=0-1
+ 1 usb_get_configuration+0x5f2/0x1480 [usbcore] age=22753 pid=419 cpus=0
+ 2 usb_get_configuration+0x1388/0x1480 [usbcore] age=8372394/8372581/8372769 pid=419 cpus=0
+ 1 sr_probe+0x76/0x540 [sr_mod] age=8375854 pid=163 cpus=0
+ 18 snd_ctl_new+0x28/0x90 [snd] age=8374174/8374174/8374174 pid=107 cpus=1
+ 1 iwl3945_pci_probe+0xd3f/0x1020 [iwl3945] age=8373796 pid=126 cpus=1
+ 1 blkcipher_walk_next+0x29c/0x390 [crypto_blkcipher] age=8374562 pid=215 cpus=1
+ 3 dm_register_target+0x1f/0xf0 [dm_mod] age=8370400/8370400/8370401 pid=900 cpus=0
+ 1 ipv6_icmp_sysctl_init+0x22/0x40 [ipv6] age=8360202 pid=1549 cpus=0
+ 1 snd_seq_pool_new+0x1b/0x80 [snd_seq] age=8355636 pid=1805 cpus=0
+''')
+f('sys/kernel/slab/kmalloc-192/objs_per_slab', 0o664, b'15\n')
+f('sys/kernel/slab/kmalloc-192/shrink', 0o664, b'')
+f('sys/kernel/slab/kmalloc-192/trace', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-192/object_size', 0o664, b'192\n')
+f('sys/kernel/slab/kmalloc-192/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-192/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-192/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-192/objects_partial', 0o664, b'14\n')
+f('sys/kernel/slab/kmalloc-192/objects', 0o664, b'254\n')
+f('sys/kernel/slab/kmalloc-192/order', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-192/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-192/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-192/align', 0o664, b'8\n')
+f('sys/kernel/slab/kmalloc-192/partial', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-192/validate', 0o664, b'')
+f('sys/kernel/slab/kmalloc-192/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-192/free_calls', 0o664, b''' 149 <not-available> age=4303047430 pid=0 cpus=0
+ 5 free_sched_group+0x3b/0x80 age=363179/6767246/8375130 pid=0-1614 cpus=0-1
+ 1 free_sched_group+0x50/0x80 age=8369988 pid=0 cpus=0
+ 1 do_exit+0x713/0x960 age=8333169 pid=2558 cpus=1
+ 7 groups_free+0x56/0x60 age=17071/4081875/8369994 pid=0-1690 cpus=0-1
+ 1 __vunmap+0xe9/0x120 age=8356237 pid=1748 cpus=1
+ 1 do_readv_writev+0xe4/0x1e0 age=8331191 pid=2262 cpus=0
+ 4 getxattr+0x8c/0x140 age=0/6266155/8357946 pid=1610-13466 cpus=0-1
+ 20 sysfs_release+0x7c/0xa0 age=53608/7118781/8376453 pid=226-2519 cpus=0-1
+ 1 ipc_immediate_free+0x9/0x10 age=8330259 pid=2568 cpus=0
+ 1 acpi_pci_irq_add_prt+0x30b/0x324 age=8379911 pid=1 cpus=0
+ 6 cpuidle_remove_state_sysfs+0x4f/0x70 age=125768/1366349/3847513 pid=13 cpus=0
+ 4 free_fib_info+0x34/0x60 age=8367904/8367909/8367920 pid=1185-1197 cpus=0-1
+ 36 urb_destroy+0x23/0x30 [usbcore] age=22749/2596918/8374921 pid=143-13294 cpus=0-1
+ 1 sg_clean+0x3e/0x80 [usbcore] age=61399 pid=13294 cpus=0
+ 1 0xffffffffa006521f age=8355637 pid=1805 cpus=0
+''')
+f('sys/kernel/slab/kmalloc-192/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/task_struct', 0o775)
+f('sys/kernel/slab/task_struct/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/task_struct/ctor', 0o664, b'')
+f('sys/kernel/slab/task_struct/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/task_struct/slab_size', 0o664, b'4400\n')
+f('sys/kernel/slab/task_struct/total_objects', 0o664, b'224\n')
+f('sys/kernel/slab/task_struct/slabs', 0o664, b'32\n')
+f('sys/kernel/slab/task_struct/poison', 0o664, b'1\n')
+f('sys/kernel/slab/task_struct/alloc_calls', 0o664, b' 203 copy_process+0xa4/0x1220 age=4172/8008848/8379941 pid=0-13212 cpus=0-1\n')
+f('sys/kernel/slab/task_struct/objs_per_slab', 0o664, b'7\n')
+f('sys/kernel/slab/task_struct/shrink', 0o664, b'')
+f('sys/kernel/slab/task_struct/trace', 0o664, b'0\n')
+f('sys/kernel/slab/task_struct/object_size', 0o664, b'4320\n')
+f('sys/kernel/slab/task_struct/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/task_struct/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/task_struct/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/task_struct/objects_partial', 0o664, b'57\n')
+f('sys/kernel/slab/task_struct/objects', 0o664, b'211\n')
+f('sys/kernel/slab/task_struct/order', 0o664, b'3\n')
+f('sys/kernel/slab/task_struct/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/task_struct/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/task_struct/align', 0o664, b'16\n')
+f('sys/kernel/slab/task_struct/partial', 0o664, b'10\n')
+f('sys/kernel/slab/task_struct/validate', 0o664, b'')
+f('sys/kernel/slab/task_struct/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/task_struct/free_calls', 0o664, b''' 93 <not-available> age=4303047286 pid=0 cpus=0
+ 110 free_task+0x30/0x40 age=7208/7706854/8377050 pid=0-13258 cpus=0-1
+''')
+f('sys/kernel/slab/task_struct/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/sgpool-16', 0o775)
+f('sys/kernel/slab/sgpool-16/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-16/ctor', 0o664, b'')
+f('sys/kernel/slab/sgpool-16/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-16/slab_size', 0o664, b'640\n')
+f('sys/kernel/slab/sgpool-16/total_objects', 0o664, b'24\n')
+f('sys/kernel/slab/sgpool-16/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/sgpool-16/poison', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-16/alloc_calls', 0o664, b' 2 mempool_alloc_slab+0x11/0x20 age=8379289/8379289/8379289 pid=1 cpus=0\n')
+f('sys/kernel/slab/sgpool-16/objs_per_slab', 0o664, b'12\n')
+f('sys/kernel/slab/sgpool-16/shrink', 0o664, b'')
+f('sys/kernel/slab/sgpool-16/trace', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-16/object_size', 0o664, b'512\n')
+f('sys/kernel/slab/sgpool-16/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-16/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-16/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-16/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-16/objects', 0o664, b'24\n')
+f('sys/kernel/slab/sgpool-16/order', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-16/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-16/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-16/align', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-16/partial', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-16/validate', 0o664, b'')
+f('sys/kernel/slab/sgpool-16/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-16/free_calls', 0o664, b' 2 <not-available> age=4303046838 pid=0 cpus=0\n')
+f('sys/kernel/slab/sgpool-16/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/request_sock_TCPv6', 0o775)
+f('sys/kernel/slab/request_sock_TCPv6/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCPv6/ctor', 0o664, b'')
+f('sys/kernel/slab/request_sock_TCPv6/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/request_sock_TCPv6/slab_size', 0o664, b'256\n')
+f('sys/kernel/slab/request_sock_TCPv6/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCPv6/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCPv6/poison', 0o664, b'1\n')
+f('sys/kernel/slab/request_sock_TCPv6/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/request_sock_TCPv6/objs_per_slab', 0o664, b'16\n')
+f('sys/kernel/slab/request_sock_TCPv6/shrink', 0o664, b'')
+f('sys/kernel/slab/request_sock_TCPv6/trace', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCPv6/object_size', 0o664, b'136\n')
+f('sys/kernel/slab/request_sock_TCPv6/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCPv6/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCPv6/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCPv6/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCPv6/objects', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCPv6/order', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCPv6/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/request_sock_TCPv6/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/request_sock_TCPv6/align', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCPv6/partial', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCPv6/validate', 0o664, b'')
+f('sys/kernel/slab/request_sock_TCPv6/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/request_sock_TCPv6/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/request_sock_TCPv6/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/Acpi-Namespace', 0o775)
+f('sys/kernel/slab/Acpi-Namespace/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Namespace/ctor', 0o664, b'')
+f('sys/kernel/slab/Acpi-Namespace/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Namespace/slab_size', 0o664, b'104\n')
+f('sys/kernel/slab/Acpi-Namespace/total_objects', 0o664, b'1755\n')
+f('sys/kernel/slab/Acpi-Namespace/slabs', 0o664, b'45\n')
+f('sys/kernel/slab/Acpi-Namespace/poison', 0o664, b'1\n')
+f('sys/kernel/slab/Acpi-Namespace/alloc_calls', 0o664, b' 1709 acpi_ns_create_node+0x34/0x45 age=8375345/8379655/8379737 pid=0-330 cpus=0\n')
+f('sys/kernel/slab/Acpi-Namespace/objs_per_slab', 0o664, b'39\n')
+f('sys/kernel/slab/Acpi-Namespace/shrink', 0o664, b'')
+f('sys/kernel/slab/Acpi-Namespace/trace', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Namespace/object_size', 0o664, b'32\n')
+f('sys/kernel/slab/Acpi-Namespace/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Namespace/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Namespace/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Namespace/objects_partial', 0o664, b'32\n')
+f('sys/kernel/slab/Acpi-Namespace/objects', 0o664, b'1709\n')
+f('sys/kernel/slab/Acpi-Namespace/order', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Namespace/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/Acpi-Namespace/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/Acpi-Namespace/align', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Namespace/partial', 0o664, b'2\n')
+f('sys/kernel/slab/Acpi-Namespace/validate', 0o664, b'')
+f('sys/kernel/slab/Acpi-Namespace/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/Acpi-Namespace/free_calls', 0o664, b' 1709 <not-available> age=4303047034 pid=0 cpus=0\n')
+f('sys/kernel/slab/Acpi-Namespace/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/posix_timers_cache', 0o775)
+f('sys/kernel/slab/posix_timers_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/posix_timers_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/posix_timers_cache/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/posix_timers_cache/slab_size', 0o664, b'320\n')
+f('sys/kernel/slab/posix_timers_cache/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/posix_timers_cache/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/posix_timers_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/posix_timers_cache/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/posix_timers_cache/objs_per_slab', 0o664, b'12\n')
+f('sys/kernel/slab/posix_timers_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/posix_timers_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/posix_timers_cache/object_size', 0o664, b'248\n')
+f('sys/kernel/slab/posix_timers_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/posix_timers_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/posix_timers_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/posix_timers_cache/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/posix_timers_cache/objects', 0o664, b'0\n')
+f('sys/kernel/slab/posix_timers_cache/order', 0o664, b'0\n')
+f('sys/kernel/slab/posix_timers_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/posix_timers_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/posix_timers_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/posix_timers_cache/partial', 0o664, b'0\n')
+f('sys/kernel/slab/posix_timers_cache/validate', 0o664, b'')
+f('sys/kernel/slab/posix_timers_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/posix_timers_cache/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/posix_timers_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/scsi_cmd_cache', 0o775)
+f('sys/kernel/slab/scsi_cmd_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_cmd_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/scsi_cmd_cache/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/scsi_cmd_cache/slab_size', 0o664, b'448\n')
+f('sys/kernel/slab/scsi_cmd_cache/total_objects', 0o664, b'36\n')
+f('sys/kernel/slab/scsi_cmd_cache/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/scsi_cmd_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/scsi_cmd_cache/alloc_calls', 0o664, b' 7 scsi_pool_alloc_command+0x25/0x80 age=67290/7192324/8380005 pid=1-419 cpus=0-1\n')
+f('sys/kernel/slab/scsi_cmd_cache/objs_per_slab', 0o664, b'18\n')
+f('sys/kernel/slab/scsi_cmd_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/scsi_cmd_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_cmd_cache/object_size', 0o664, b'320\n')
+f('sys/kernel/slab/scsi_cmd_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_cmd_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_cmd_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_cmd_cache/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_cmd_cache/objects', 0o664, b'36\n')
+f('sys/kernel/slab/scsi_cmd_cache/order', 0o664, b'1\n')
+f('sys/kernel/slab/scsi_cmd_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/scsi_cmd_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/scsi_cmd_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_cmd_cache/partial', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_cmd_cache/validate', 0o664, b'')
+f('sys/kernel/slab/scsi_cmd_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/scsi_cmd_cache/free_calls', 0o664, b''' 5 <not-available> age=4303047639 pid=0 cpus=0
+ 2 scsi_pool_free_command+0x4c/0x60 age=67789/4223648/8379508 pid=0 cpus=0
+''')
+f('sys/kernel/slab/scsi_cmd_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/eventpoll_pwq', 0o775)
+f('sys/kernel/slab/eventpoll_pwq/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/eventpoll_pwq/ctor', 0o664, b'')
+f('sys/kernel/slab/eventpoll_pwq/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/eventpoll_pwq/slab_size', 0o664, b'144\n')
+f('sys/kernel/slab/eventpoll_pwq/total_objects', 0o664, b'112\n')
+f('sys/kernel/slab/eventpoll_pwq/slabs', 0o664, b'4\n')
+f('sys/kernel/slab/eventpoll_pwq/poison', 0o664, b'1\n')
+f('sys/kernel/slab/eventpoll_pwq/alloc_calls', 0o664, b' 65 ep_ptable_queue_proc+0x35/0xa0 age=2416434/8173328/8356246 pid=1690-20296 cpus=0-1\n')
+f('sys/kernel/slab/eventpoll_pwq/objs_per_slab', 0o664, b'28\n')
+f('sys/kernel/slab/eventpoll_pwq/shrink', 0o664, b'')
+f('sys/kernel/slab/eventpoll_pwq/trace', 0o664, b'0\n')
+f('sys/kernel/slab/eventpoll_pwq/object_size', 0o664, b'72\n')
+f('sys/kernel/slab/eventpoll_pwq/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/eventpoll_pwq/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/eventpoll_pwq/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/eventpoll_pwq/objects_partial', 0o664, b'7\n')
+f('sys/kernel/slab/eventpoll_pwq/objects', 0o664, b'91\n')
+f('sys/kernel/slab/eventpoll_pwq/order', 0o664, b'0\n')
+f('sys/kernel/slab/eventpoll_pwq/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/eventpoll_pwq/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/eventpoll_pwq/align', 0o664, b'0\n')
+f('sys/kernel/slab/eventpoll_pwq/partial', 0o664, b'1\n')
+f('sys/kernel/slab/eventpoll_pwq/validate', 0o664, b'')
+f('sys/kernel/slab/eventpoll_pwq/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/eventpoll_pwq/free_calls', 0o664, b''' 61 <not-available> age=4303046794 pid=0 cpus=0
+ 4 ep_unregister_pollwait+0x61/0x80 age=2416452/6864185/8356241 pid=1690-2073 cpus=0-1
+''')
+f('sys/kernel/slab/eventpoll_pwq/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/journal_handle', 0o775)
+f('sys/kernel/slab/journal_handle/reclaim_account', 0o664, b'1\n')
+f('sys/kernel/slab/journal_handle/ctor', 0o664, b'')
+f('sys/kernel/slab/journal_handle/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/journal_handle/slab_size', 0o664, b'128\n')
+f('sys/kernel/slab/journal_handle/total_objects', 0o664, b'64\n')
+f('sys/kernel/slab/journal_handle/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/journal_handle/poison', 0o664, b'1\n')
+f('sys/kernel/slab/journal_handle/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/journal_handle/objs_per_slab', 0o664, b'32\n')
+f('sys/kernel/slab/journal_handle/shrink', 0o664, b'')
+f('sys/kernel/slab/journal_handle/trace', 0o664, b'0\n')
+f('sys/kernel/slab/journal_handle/object_size', 0o664, b'56\n')
+f('sys/kernel/slab/journal_handle/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/journal_handle/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/journal_handle/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/journal_handle/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/journal_handle/objects', 0o664, b'64\n')
+f('sys/kernel/slab/journal_handle/order', 0o664, b'0\n')
+f('sys/kernel/slab/journal_handle/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/journal_handle/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/journal_handle/align', 0o664, b'0\n')
+f('sys/kernel/slab/journal_handle/partial', 0o664, b'0\n')
+f('sys/kernel/slab/journal_handle/validate', 0o664, b'')
+f('sys/kernel/slab/journal_handle/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/journal_handle/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/journal_handle/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/bsg_cmd', 0o775)
+f('sys/kernel/slab/bsg_cmd/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/bsg_cmd/ctor', 0o664, b'')
+f('sys/kernel/slab/bsg_cmd/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/bsg_cmd/slab_size', 0o664, b'384\n')
+f('sys/kernel/slab/bsg_cmd/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/bsg_cmd/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/bsg_cmd/poison', 0o664, b'1\n')
+f('sys/kernel/slab/bsg_cmd/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/bsg_cmd/objs_per_slab', 0o664, b'21\n')
+f('sys/kernel/slab/bsg_cmd/shrink', 0o664, b'')
+f('sys/kernel/slab/bsg_cmd/trace', 0o664, b'0\n')
+f('sys/kernel/slab/bsg_cmd/object_size', 0o664, b'312\n')
+f('sys/kernel/slab/bsg_cmd/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/bsg_cmd/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/bsg_cmd/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/bsg_cmd/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/bsg_cmd/objects', 0o664, b'0\n')
+f('sys/kernel/slab/bsg_cmd/order', 0o664, b'1\n')
+f('sys/kernel/slab/bsg_cmd/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/bsg_cmd/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/bsg_cmd/align', 0o664, b'0\n')
+f('sys/kernel/slab/bsg_cmd/partial', 0o664, b'0\n')
+f('sys/kernel/slab/bsg_cmd/validate', 0o664, b'')
+f('sys/kernel/slab/bsg_cmd/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/bsg_cmd/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/bsg_cmd/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/kiocb', 0o775)
+f('sys/kernel/slab/kiocb/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/kiocb/ctor', 0o664, b'')
+f('sys/kernel/slab/kiocb/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/kiocb/slab_size', 0o664, b'320\n')
+f('sys/kernel/slab/kiocb/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/kiocb/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/kiocb/poison', 0o664, b'1\n')
+f('sys/kernel/slab/kiocb/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/kiocb/objs_per_slab', 0o664, b'12\n')
+f('sys/kernel/slab/kiocb/shrink', 0o664, b'')
+f('sys/kernel/slab/kiocb/trace', 0o664, b'0\n')
+f('sys/kernel/slab/kiocb/object_size', 0o664, b'240\n')
+f('sys/kernel/slab/kiocb/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/kiocb/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/kiocb/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/kiocb/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/kiocb/objects', 0o664, b'0\n')
+f('sys/kernel/slab/kiocb/order', 0o664, b'0\n')
+f('sys/kernel/slab/kiocb/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/kiocb/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/kiocb/align', 0o664, b'8\n')
+f('sys/kernel/slab/kiocb/partial', 0o664, b'0\n')
+f('sys/kernel/slab/kiocb/validate', 0o664, b'')
+f('sys/kernel/slab/kiocb/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/kiocb/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/kiocb/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/file_lock_cache', 0o775)
+f('sys/kernel/slab/file_lock_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/file_lock_cache/ctor', 0o664, b'init_once+0x0/0x10\n')
+f('sys/kernel/slab/file_lock_cache/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/file_lock_cache/slab_size', 0o664, b'296\n')
+f('sys/kernel/slab/file_lock_cache/total_objects', 0o664, b'26\n')
+f('sys/kernel/slab/file_lock_cache/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/file_lock_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/file_lock_cache/alloc_calls', 0o664, b''' 2 flock_lock_file_wait+0x2d6/0x2f0 age=8355055/8355767/8356479 pid=1690-1807 cpus=0
+ 1 __posix_lock_file+0x3f/0x560 age=8349601 pid=2262 cpus=0
+''')
+f('sys/kernel/slab/file_lock_cache/objs_per_slab', 0o664, b'13\n')
+f('sys/kernel/slab/file_lock_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/file_lock_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/file_lock_cache/object_size', 0o664, b'224\n')
+f('sys/kernel/slab/file_lock_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/file_lock_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/file_lock_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/file_lock_cache/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/file_lock_cache/objects', 0o664, b'26\n')
+f('sys/kernel/slab/file_lock_cache/order', 0o664, b'0\n')
+f('sys/kernel/slab/file_lock_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/file_lock_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/file_lock_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/file_lock_cache/partial', 0o664, b'0\n')
+f('sys/kernel/slab/file_lock_cache/validate', 0o664, b'')
+f('sys/kernel/slab/file_lock_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/file_lock_cache/free_calls', 0o664, b' 3 locks_free_lock+0x3e/0x60 age=8351291/8355422/8359832 pid=1549-2189 cpus=0\n')
+f('sys/kernel/slab/file_lock_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/inet_peer_cache', 0o775)
+f('sys/kernel/slab/inet_peer_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/inet_peer_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/inet_peer_cache/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/inet_peer_cache/slab_size', 0o664, b'192\n')
+f('sys/kernel/slab/inet_peer_cache/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/inet_peer_cache/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/inet_peer_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/inet_peer_cache/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/inet_peer_cache/objs_per_slab', 0o664, b'21\n')
+f('sys/kernel/slab/inet_peer_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/inet_peer_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/inet_peer_cache/object_size', 0o664, b'64\n')
+f('sys/kernel/slab/inet_peer_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/inet_peer_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/inet_peer_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/inet_peer_cache/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/inet_peer_cache/objects', 0o664, b'0\n')
+f('sys/kernel/slab/inet_peer_cache/order', 0o664, b'0\n')
+f('sys/kernel/slab/inet_peer_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/inet_peer_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/inet_peer_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/inet_peer_cache/partial', 0o664, b'0\n')
+f('sys/kernel/slab/inet_peer_cache/validate', 0o664, b'')
+f('sys/kernel/slab/inet_peer_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/inet_peer_cache/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/inet_peer_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/arp_cache', 0o775)
+f('sys/kernel/slab/arp_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/arp_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/arp_cache/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/arp_cache/slab_size', 0o664, b'448\n')
+f('sys/kernel/slab/arp_cache/total_objects', 0o664, b'36\n')
+f('sys/kernel/slab/arp_cache/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/arp_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/arp_cache/alloc_calls', 0o664, b' 1 neigh_create+0x8b/0x530 age=1133499 pid=952 cpus=0\n')
+f('sys/kernel/slab/arp_cache/objs_per_slab', 0o664, b'18\n')
+f('sys/kernel/slab/arp_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/arp_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/arp_cache/object_size', 0o664, b'348\n')
+f('sys/kernel/slab/arp_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/arp_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/arp_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/arp_cache/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/arp_cache/objects', 0o664, b'36\n')
+f('sys/kernel/slab/arp_cache/order', 0o664, b'1\n')
+f('sys/kernel/slab/arp_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/arp_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/arp_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/arp_cache/partial', 0o664, b'0\n')
+f('sys/kernel/slab/arp_cache/validate', 0o664, b'')
+f('sys/kernel/slab/arp_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/arp_cache/free_calls', 0o664, b' 1 neigh_destroy+0x10c/0x160 age=1135741 pid=0 cpus=0\n')
+f('sys/kernel/slab/arp_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/biovec-4', 0o775)
+f('sys/kernel/slab/biovec-4/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-4/ctor', 0o664, b'')
+f('sys/kernel/slab/biovec-4/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-4/slab_size', 0o664, b'192\n')
+f('sys/kernel/slab/biovec-4/total_objects', 0o664, b'42\n')
+f('sys/kernel/slab/biovec-4/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/biovec-4/poison', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-4/alloc_calls', 0o664, b' 2 mempool_alloc_slab+0x11/0x20 age=8379500/8379500/8379500 pid=1 cpus=0\n')
+f('sys/kernel/slab/biovec-4/objs_per_slab', 0o664, b'21\n')
+f('sys/kernel/slab/biovec-4/shrink', 0o664, b'')
+f('sys/kernel/slab/biovec-4/trace', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-4/object_size', 0o664, b'64\n')
+f('sys/kernel/slab/biovec-4/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-4/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-4/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-4/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-4/objects', 0o664, b'42\n')
+f('sys/kernel/slab/biovec-4/order', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-4/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-4/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-4/align', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-4/partial', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-4/validate', 0o664, b'')
+f('sys/kernel/slab/biovec-4/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-4/free_calls', 0o664, b' 2 <not-available> age=4303046934 pid=0 cpus=0\n')
+f('sys/kernel/slab/biovec-4/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/scsi_sense_cache', 0o775)
+f('sys/kernel/slab/scsi_sense_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_sense_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/scsi_sense_cache/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/scsi_sense_cache/slab_size', 0o664, b'192\n')
+f('sys/kernel/slab/scsi_sense_cache/total_objects', 0o664, b'42\n')
+f('sys/kernel/slab/scsi_sense_cache/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/scsi_sense_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/scsi_sense_cache/alloc_calls', 0o664, b' 7 scsi_pool_alloc_command+0x4a/0x80 age=67299/7192333/8380014 pid=1-419 cpus=0-1\n')
+f('sys/kernel/slab/scsi_sense_cache/objs_per_slab', 0o664, b'21\n')
+f('sys/kernel/slab/scsi_sense_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/scsi_sense_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_sense_cache/object_size', 0o664, b'96\n')
+f('sys/kernel/slab/scsi_sense_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_sense_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_sense_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_sense_cache/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_sense_cache/objects', 0o664, b'42\n')
+f('sys/kernel/slab/scsi_sense_cache/order', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_sense_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/scsi_sense_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/scsi_sense_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_sense_cache/partial', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_sense_cache/validate', 0o664, b'')
+f('sys/kernel/slab/scsi_sense_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/scsi_sense_cache/free_calls', 0o664, b''' 5 <not-available> age=4303047648 pid=0 cpus=0
+ 2 scsi_pool_free_command+0x40/0x60 age=67798/4223657/8379517 pid=0 cpus=0
+''')
+f('sys/kernel/slab/scsi_sense_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/cfq_io_context', 0o775)
+f('sys/kernel/slab/cfq_io_context/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/cfq_io_context/ctor', 0o664, b'')
+f('sys/kernel/slab/cfq_io_context/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/cfq_io_context/slab_size', 0o664, b'240\n')
+f('sys/kernel/slab/cfq_io_context/total_objects', 0o664, b'85\n')
+f('sys/kernel/slab/cfq_io_context/slabs', 0o664, b'5\n')
+f('sys/kernel/slab/cfq_io_context/poison', 0o664, b'1\n')
+f('sys/kernel/slab/cfq_io_context/alloc_calls', 0o664, b' 69 cfq_set_request+0x13d/0x390 age=177/7837888/8379613 pid=1-13466 cpus=0-1\n')
+f('sys/kernel/slab/cfq_io_context/objs_per_slab', 0o664, b'17\n')
+f('sys/kernel/slab/cfq_io_context/shrink', 0o664, b'')
+f('sys/kernel/slab/cfq_io_context/trace', 0o664, b'0\n')
+f('sys/kernel/slab/cfq_io_context/object_size', 0o664, b'168\n')
+f('sys/kernel/slab/cfq_io_context/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/cfq_io_context/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/cfq_io_context/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/cfq_io_context/objects_partial', 0o664, b'16\n')
+f('sys/kernel/slab/cfq_io_context/objects', 0o664, b'84\n')
+f('sys/kernel/slab/cfq_io_context/order', 0o664, b'0\n')
+f('sys/kernel/slab/cfq_io_context/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/cfq_io_context/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/cfq_io_context/align', 0o664, b'8\n')
+f('sys/kernel/slab/cfq_io_context/partial', 0o664, b'1\n')
+f('sys/kernel/slab/cfq_io_context/validate', 0o664, b'')
+f('sys/kernel/slab/cfq_io_context/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/cfq_io_context/free_calls', 0o664, b''' 12 <not-available> age=4303047630 pid=0 cpus=0
+ 57 cfq_cic_free_rcu+0x21/0xc0 age=61842/7747595/8376055 pid=0-2535 cpus=0-1
+''')
+f('sys/kernel/slab/cfq_io_context/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/idr_layer_cache', 0o775)
+f('sys/kernel/slab/idr_layer_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/idr_layer_cache/ctor', 0o664, b'idr_cache_ctor+0x0/0x10\n')
+f('sys/kernel/slab/idr_layer_cache/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/idr_layer_cache/slab_size', 0o664, b'616\n')
+f('sys/kernel/slab/idr_layer_cache/total_objects', 0o664, b'442\n')
+f('sys/kernel/slab/idr_layer_cache/slabs', 0o664, b'34\n')
+f('sys/kernel/slab/idr_layer_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/idr_layer_cache/alloc_calls', 0o664, b' 406 idr_pre_get+0x5d/0x80 age=60336/8278969/8380018 pid=0-13355 cpus=0-1\n')
+f('sys/kernel/slab/idr_layer_cache/objs_per_slab', 0o664, b'13\n')
+f('sys/kernel/slab/idr_layer_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/idr_layer_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/idr_layer_cache/object_size', 0o664, b'544\n')
+f('sys/kernel/slab/idr_layer_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/idr_layer_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/idr_layer_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/idr_layer_cache/objects_partial', 0o664, b'82\n')
+f('sys/kernel/slab/idr_layer_cache/objects', 0o664, b'420\n')
+f('sys/kernel/slab/idr_layer_cache/order', 0o664, b'1\n')
+f('sys/kernel/slab/idr_layer_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/idr_layer_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/idr_layer_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/idr_layer_cache/partial', 0o664, b'8\n')
+f('sys/kernel/slab/idr_layer_cache/validate', 0o664, b'')
+f('sys/kernel/slab/idr_layer_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/idr_layer_cache/free_calls', 0o664, b''' 304 <not-available> age=4303047315 pid=0 cpus=0
+ 3 idr_destroy+0x2f/0x40 age=104486/3178486/4715486 pid=13211-13803 cpus=0-1
+ 4 idr_layer_rcu_free+0x17/0x20 age=8334501/8362397/8377168 pid=0-1155 cpus=0-1
+ 95 ida_get_new_above+0x141/0x210 age=812584/8292482/8380019 pid=0-2593 cpus=0-1
+''')
+f('sys/kernel/slab/idr_layer_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/vm_area_struct', 0o775)
+f('sys/kernel/slab/vm_area_struct/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/vm_area_struct/ctor', 0o664, b'')
+f('sys/kernel/slab/vm_area_struct/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/vm_area_struct/slab_size', 0o664, b'240\n')
+f('sys/kernel/slab/vm_area_struct/total_objects', 0o664, b'12087\n')
+f('sys/kernel/slab/vm_area_struct/slabs', 0o664, b'711\n')
+f('sys/kernel/slab/vm_area_struct/poison', 0o664, b'1\n')
+f('sys/kernel/slab/vm_area_struct/alloc_calls', 0o664, b''' 2751 dup_mm+0x194/0x390 age=8335622/8348807/8376522 pid=71-2467 cpus=0-1
+ 52 install_special_mapping+0x3d/0xe0 age=4109/7453125/8378118 pid=1-20296 cpus=0-1
+ 4006 split_vma+0x61/0x140 age=4107/7930710/8366050 pid=1206-20296 cpus=0-1
+ 3 copy_vma+0x125/0x1b0 age=8353805/8353815/8353824 pid=1738 cpus=0
+ 54 do_brk+0x2ec/0x360 age=4107/7486452/8378131 pid=1-20296 cpus=0-1
+ 5097 mmap_region+0x195/0x5c0 age=4105/7877577/8378131 pid=1-20296 cpus=0-1
+ 52 bprm_mm_init+0xa0/0x1b0 age=4109/7453192/8378134 pid=1-20296 cpus=0-1
+''')
+f('sys/kernel/slab/vm_area_struct/objs_per_slab', 0o664, b'17\n')
+f('sys/kernel/slab/vm_area_struct/shrink', 0o664, b'')
+f('sys/kernel/slab/vm_area_struct/trace', 0o664, b'0\n')
+f('sys/kernel/slab/vm_area_struct/object_size', 0o664, b'168\n')
+f('sys/kernel/slab/vm_area_struct/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/vm_area_struct/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/vm_area_struct/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/vm_area_struct/objects_partial', 0o664, b'47\n')
+f('sys/kernel/slab/vm_area_struct/objects', 0o664, b'12049\n')
+f('sys/kernel/slab/vm_area_struct/order', 0o664, b'0\n')
+f('sys/kernel/slab/vm_area_struct/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/vm_area_struct/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/vm_area_struct/align', 0o664, b'0\n')
+f('sys/kernel/slab/vm_area_struct/partial', 0o664, b'5\n')
+f('sys/kernel/slab/vm_area_struct/validate', 0o664, b'')
+f('sys/kernel/slab/vm_area_struct/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/vm_area_struct/free_calls', 0o664, b''' 6424 <not-available> age=4303047229 pid=0 cpus=0
+ 5590 remove_vma+0x53/0x70 age=4110/7683818/8376767 pid=71-20296 cpus=0-1
+ 1 vma_adjust+0x32c/0x570 age=8364245 pid=1371 cpus=0
+''')
+f('sys/kernel/slab/vm_area_struct/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/biovec-1', 0o775)
+f('sys/kernel/slab/biovec-1/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-1/ctor', 0o664, b'')
+f('sys/kernel/slab/biovec-1/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-1/slab_size', 0o664, b'96\n')
+f('sys/kernel/slab/biovec-1/total_objects', 0o664, b'126\n')
+f('sys/kernel/slab/biovec-1/slabs', 0o664, b'3\n')
+f('sys/kernel/slab/biovec-1/poison', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-1/alloc_calls', 0o664, b' 2 mempool_alloc_slab+0x11/0x20 age=8379509/8379509/8379509 pid=1 cpus=0\n')
+f('sys/kernel/slab/biovec-1/objs_per_slab', 0o664, b'42\n')
+f('sys/kernel/slab/biovec-1/shrink', 0o664, b'')
+f('sys/kernel/slab/biovec-1/trace', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-1/object_size', 0o664, b'16\n')
+f('sys/kernel/slab/biovec-1/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-1/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-1/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-1/objects_partial', 0o664, b'2\n')
+f('sys/kernel/slab/biovec-1/objects', 0o664, b'86\n')
+f('sys/kernel/slab/biovec-1/order', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-1/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-1/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-1/align', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-1/partial', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-1/validate', 0o664, b'')
+f('sys/kernel/slab/biovec-1/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-1/free_calls', 0o664, b' 2 <not-available> age=4303046943 pid=0 cpus=0\n')
+f('sys/kernel/slab/biovec-1/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/secpath_cache', 0o775)
+f('sys/kernel/slab/secpath_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/secpath_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/secpath_cache/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/secpath_cache/slab_size', 0o664, b'128\n')
+f('sys/kernel/slab/secpath_cache/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/secpath_cache/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/secpath_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/secpath_cache/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/secpath_cache/objs_per_slab', 0o664, b'32\n')
+f('sys/kernel/slab/secpath_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/secpath_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/secpath_cache/object_size', 0o664, b'56\n')
+f('sys/kernel/slab/secpath_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/secpath_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/secpath_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/secpath_cache/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/secpath_cache/objects', 0o664, b'0\n')
+f('sys/kernel/slab/secpath_cache/order', 0o664, b'0\n')
+f('sys/kernel/slab/secpath_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/secpath_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/secpath_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/secpath_cache/partial', 0o664, b'0\n')
+f('sys/kernel/slab/secpath_cache/validate', 0o664, b'')
+f('sys/kernel/slab/secpath_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/secpath_cache/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/secpath_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/UNIX', 0o775)
+f('sys/kernel/slab/UNIX/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/UNIX/ctor', 0o664, b'')
+f('sys/kernel/slab/UNIX/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/UNIX/slab_size', 0o664, b'1472\n')
+f('sys/kernel/slab/UNIX/total_objects', 0o664, b'506\n')
+f('sys/kernel/slab/UNIX/slabs', 0o664, b'23\n')
+f('sys/kernel/slab/UNIX/poison', 0o664, b'1\n')
+f('sys/kernel/slab/UNIX/alloc_calls', 0o664, b' 450 sk_prot_alloc+0x1e/0xb0 age=61033/8220474/8376385 pid=71-20296 cpus=0-1\n')
+f('sys/kernel/slab/UNIX/objs_per_slab', 0o664, b'22\n')
+f('sys/kernel/slab/UNIX/shrink', 0o664, b'')
+f('sys/kernel/slab/UNIX/trace', 0o664, b'0\n')
+f('sys/kernel/slab/UNIX/object_size', 0o664, b'1376\n')
+f('sys/kernel/slab/UNIX/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/UNIX/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/UNIX/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/UNIX/objects_partial', 0o664, b'178\n')
+f('sys/kernel/slab/UNIX/objects', 0o664, b'486\n')
+f('sys/kernel/slab/UNIX/order', 0o664, b'3\n')
+f('sys/kernel/slab/UNIX/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/UNIX/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/UNIX/align', 0o664, b'0\n')
+f('sys/kernel/slab/UNIX/partial', 0o664, b'9\n')
+f('sys/kernel/slab/UNIX/validate', 0o664, b'')
+f('sys/kernel/slab/UNIX/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/UNIX/free_calls', 0o664, b''' 235 <not-available> age=4303046663 pid=0 cpus=0
+ 215 sk_free+0x80/0x100 age=61050/8083366/8375930 pid=76-20292 cpus=0-1
+''')
+f('sys/kernel/slab/UNIX/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/RAWv6', 0o775)
+f('sys/kernel/slab/RAWv6/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/RAWv6/ctor', 0o664, b'')
+f('sys/kernel/slab/RAWv6/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/RAWv6/slab_size', 0o664, b'1472\n')
+f('sys/kernel/slab/RAWv6/total_objects', 0o664, b'22\n')
+f('sys/kernel/slab/RAWv6/slabs', 0o664, b'1\n')
+f('sys/kernel/slab/RAWv6/poison', 0o664, b'1\n')
+f('sys/kernel/slab/RAWv6/alloc_calls', 0o664, b' 5 sk_prot_alloc+0x1e/0xb0 age=8360545/8360552/8360555 pid=1549 cpus=0\n')
+f('sys/kernel/slab/RAWv6/objs_per_slab', 0o664, b'22\n')
+f('sys/kernel/slab/RAWv6/shrink', 0o664, b'')
+f('sys/kernel/slab/RAWv6/trace', 0o664, b'0\n')
+f('sys/kernel/slab/RAWv6/object_size', 0o664, b'1376\n')
+f('sys/kernel/slab/RAWv6/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/RAWv6/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/RAWv6/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/RAWv6/objects_partial', 0o664, b'5\n')
+f('sys/kernel/slab/RAWv6/objects', 0o664, b'5\n')
+f('sys/kernel/slab/RAWv6/order', 0o664, b'3\n')
+f('sys/kernel/slab/RAWv6/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/RAWv6/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/RAWv6/align', 0o664, b'0\n')
+f('sys/kernel/slab/RAWv6/partial', 0o664, b'1\n')
+f('sys/kernel/slab/RAWv6/validate', 0o664, b'')
+f('sys/kernel/slab/RAWv6/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/RAWv6/free_calls', 0o664, b' 5 <not-available> age=4303047773 pid=0 cpus=0\n')
+f('sys/kernel/slab/RAWv6/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/sgpool-64', 0o775)
+f('sys/kernel/slab/sgpool-64/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-64/ctor', 0o664, b'')
+f('sys/kernel/slab/sgpool-64/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-64/slab_size', 0o664, b'2176\n')
+f('sys/kernel/slab/sgpool-64/total_objects', 0o664, b'30\n')
+f('sys/kernel/slab/sgpool-64/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/sgpool-64/poison', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-64/alloc_calls', 0o664, b' 2 mempool_alloc_slab+0x11/0x20 age=8379271/8379271/8379271 pid=1 cpus=0\n')
+f('sys/kernel/slab/sgpool-64/objs_per_slab', 0o664, b'15\n')
+f('sys/kernel/slab/sgpool-64/shrink', 0o664, b'')
+f('sys/kernel/slab/sgpool-64/trace', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-64/object_size', 0o664, b'2048\n')
+f('sys/kernel/slab/sgpool-64/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-64/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-64/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-64/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-64/objects', 0o664, b'30\n')
+f('sys/kernel/slab/sgpool-64/order', 0o664, b'3\n')
+f('sys/kernel/slab/sgpool-64/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-64/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-64/align', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-64/partial', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-64/validate', 0o664, b'')
+f('sys/kernel/slab/sgpool-64/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-64/free_calls', 0o664, b' 2 <not-available> age=4303046820 pid=0 cpus=0\n')
+f('sys/kernel/slab/sgpool-64/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/bdev_cache', 0o775)
+f('sys/kernel/slab/bdev_cache/reclaim_account', 0o664, b'1\n')
+f('sys/kernel/slab/bdev_cache/ctor', 0o664, b'init_once+0x0/0x100\n')
+f('sys/kernel/slab/bdev_cache/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/bdev_cache/slab_size', 0o664, b'1536\n')
+f('sys/kernel/slab/bdev_cache/total_objects', 0o664, b'42\n')
+f('sys/kernel/slab/bdev_cache/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/bdev_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/bdev_cache/alloc_calls', 0o664, b' 13 bdev_alloc_inode+0x15/0x30 age=61383/7093434/8379778 pid=0-13333 cpus=0\n')
+f('sys/kernel/slab/bdev_cache/objs_per_slab', 0o664, b'21\n')
+f('sys/kernel/slab/bdev_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/bdev_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/bdev_cache/object_size', 0o664, b'1432\n')
+f('sys/kernel/slab/bdev_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/bdev_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/bdev_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/bdev_cache/objects_partial', 0o664, b'11\n')
+f('sys/kernel/slab/bdev_cache/objects', 0o664, b'32\n')
+f('sys/kernel/slab/bdev_cache/order', 0o664, b'3\n')
+f('sys/kernel/slab/bdev_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/bdev_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/bdev_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/bdev_cache/partial', 0o664, b'1\n')
+f('sys/kernel/slab/bdev_cache/validate', 0o664, b'')
+f('sys/kernel/slab/bdev_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/bdev_cache/free_calls', 0o664, b''' 9 <not-available> age=4303047074 pid=0 cpus=0
+ 4 bdev_destroy_inode+0x1f/0x30 age=61405/4218130/8374840 pid=488-13325 cpus=0-1
+''')
+f('sys/kernel/slab/bdev_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/fasync_cache', 0o775)
+f('sys/kernel/slab/fasync_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/fasync_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/fasync_cache/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/fasync_cache/slab_size', 0o664, b'96\n')
+f('sys/kernel/slab/fasync_cache/total_objects', 0o664, b'42\n')
+f('sys/kernel/slab/fasync_cache/slabs', 0o664, b'1\n')
+f('sys/kernel/slab/fasync_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/fasync_cache/alloc_calls', 0o664, b' 1 fasync_helper+0x115/0x130 age=8354059 pid=1738 cpus=0\n')
+f('sys/kernel/slab/fasync_cache/objs_per_slab', 0o664, b'42\n')
+f('sys/kernel/slab/fasync_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/fasync_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/fasync_cache/object_size', 0o664, b'24\n')
+f('sys/kernel/slab/fasync_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/fasync_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/fasync_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/fasync_cache/objects_partial', 0o664, b'1\n')
+f('sys/kernel/slab/fasync_cache/objects', 0o664, b'1\n')
+f('sys/kernel/slab/fasync_cache/order', 0o664, b'0\n')
+f('sys/kernel/slab/fasync_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/fasync_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/fasync_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/fasync_cache/partial', 0o664, b'1\n')
+f('sys/kernel/slab/fasync_cache/validate', 0o664, b'')
+f('sys/kernel/slab/fasync_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/fasync_cache/free_calls', 0o664, b' 1 <not-available> age=4303047449 pid=0 cpus=0\n')
+f('sys/kernel/slab/fasync_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/UDPLITEv6', 0o775)
+f('sys/kernel/slab/UDPLITEv6/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/UDPLITEv6/ctor', 0o664, b'')
+f('sys/kernel/slab/UDPLITEv6/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/UDPLITEv6/slab_size', 0o664, b'1472\n')
+f('sys/kernel/slab/UDPLITEv6/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/UDPLITEv6/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/UDPLITEv6/poison', 0o664, b'1\n')
+f('sys/kernel/slab/UDPLITEv6/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/UDPLITEv6/objs_per_slab', 0o664, b'22\n')
+f('sys/kernel/slab/UDPLITEv6/shrink', 0o664, b'')
+f('sys/kernel/slab/UDPLITEv6/trace', 0o664, b'0\n')
+f('sys/kernel/slab/UDPLITEv6/object_size', 0o664, b'1368\n')
+f('sys/kernel/slab/UDPLITEv6/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/UDPLITEv6/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/UDPLITEv6/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/UDPLITEv6/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/UDPLITEv6/objects', 0o664, b'0\n')
+f('sys/kernel/slab/UDPLITEv6/order', 0o664, b'3\n')
+f('sys/kernel/slab/UDPLITEv6/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/UDPLITEv6/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/UDPLITEv6/align', 0o664, b'0\n')
+f('sys/kernel/slab/UDPLITEv6/partial', 0o664, b'0\n')
+f('sys/kernel/slab/UDPLITEv6/validate', 0o664, b'')
+f('sys/kernel/slab/UDPLITEv6/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/UDPLITEv6/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/UDPLITEv6/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/Acpi-Operand', 0o775)
+f('sys/kernel/slab/Acpi-Operand/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Operand/ctor', 0o664, b'')
+f('sys/kernel/slab/Acpi-Operand/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Operand/slab_size', 0o664, b'144\n')
+f('sys/kernel/slab/Acpi-Operand/total_objects', 0o664, b'2688\n')
+f('sys/kernel/slab/Acpi-Operand/slabs', 0o664, b'96\n')
+f('sys/kernel/slab/Acpi-Operand/poison', 0o664, b'1\n')
+f('sys/kernel/slab/Acpi-Operand/alloc_calls', 0o664, b' 2653 acpi_ut_allocate_object_desc_dbg+0x39/0x75 age=2625/8339457/8379700 pid=0-13466 cpus=0-1\n')
+f('sys/kernel/slab/Acpi-Operand/objs_per_slab', 0o664, b'28\n')
+f('sys/kernel/slab/Acpi-Operand/shrink', 0o664, b'')
+f('sys/kernel/slab/Acpi-Operand/trace', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Operand/object_size', 0o664, b'72\n')
+f('sys/kernel/slab/Acpi-Operand/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Operand/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Operand/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Operand/objects_partial', 0o664, b'171\n')
+f('sys/kernel/slab/Acpi-Operand/objects', 0o664, b'2663\n')
+f('sys/kernel/slab/Acpi-Operand/order', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Operand/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/Acpi-Operand/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/Acpi-Operand/align', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-Operand/partial', 0o664, b'7\n')
+f('sys/kernel/slab/Acpi-Operand/validate', 0o664, b'')
+f('sys/kernel/slab/Acpi-Operand/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/Acpi-Operand/free_calls', 0o664, b''' 2267 <not-available> age=4303046997 pid=0 cpus=0
+ 386 acpi_os_release_object+0x9/0xd age=2626/8137233/8379689 pid=0-13466 cpus=0-1
+''')
+f('sys/kernel/slab/Acpi-Operand/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/xfrm_dst_cache', 0o775)
+f('sys/kernel/slab/xfrm_dst_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/xfrm_dst_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/xfrm_dst_cache/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/xfrm_dst_cache/slab_size', 0o664, b'448\n')
+f('sys/kernel/slab/xfrm_dst_cache/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/xfrm_dst_cache/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/xfrm_dst_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/xfrm_dst_cache/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/xfrm_dst_cache/objs_per_slab', 0o664, b'18\n')
+f('sys/kernel/slab/xfrm_dst_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/xfrm_dst_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/xfrm_dst_cache/object_size', 0o664, b'344\n')
+f('sys/kernel/slab/xfrm_dst_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/xfrm_dst_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/xfrm_dst_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/xfrm_dst_cache/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/xfrm_dst_cache/objects', 0o664, b'0\n')
+f('sys/kernel/slab/xfrm_dst_cache/order', 0o664, b'1\n')
+f('sys/kernel/slab/xfrm_dst_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/xfrm_dst_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/xfrm_dst_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/xfrm_dst_cache/partial', 0o664, b'0\n')
+f('sys/kernel/slab/xfrm_dst_cache/validate', 0o664, b'')
+f('sys/kernel/slab/xfrm_dst_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/xfrm_dst_cache/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/xfrm_dst_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/eventpoll_epi', 0o775)
+f('sys/kernel/slab/eventpoll_epi/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/eventpoll_epi/ctor', 0o664, b'')
+f('sys/kernel/slab/eventpoll_epi/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/eventpoll_epi/slab_size', 0o664, b'256\n')
+f('sys/kernel/slab/eventpoll_epi/total_objects', 0o664, b'96\n')
+f('sys/kernel/slab/eventpoll_epi/slabs', 0o664, b'6\n')
+f('sys/kernel/slab/eventpoll_epi/poison', 0o664, b'1\n')
+f('sys/kernel/slab/eventpoll_epi/alloc_calls', 0o664, b' 65 sys_epoll_ctl+0x1a4/0x4d0 age=2416443/8173337/8356255 pid=1690-20296 cpus=0-1\n')
+f('sys/kernel/slab/eventpoll_epi/objs_per_slab', 0o664, b'16\n')
+f('sys/kernel/slab/eventpoll_epi/shrink', 0o664, b'')
+f('sys/kernel/slab/eventpoll_epi/trace', 0o664, b'0\n')
+f('sys/kernel/slab/eventpoll_epi/object_size', 0o664, b'128\n')
+f('sys/kernel/slab/eventpoll_epi/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/eventpoll_epi/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/eventpoll_epi/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/eventpoll_epi/objects_partial', 0o664, b'15\n')
+f('sys/kernel/slab/eventpoll_epi/objects', 0o664, b'79\n')
+f('sys/kernel/slab/eventpoll_epi/order', 0o664, b'0\n')
+f('sys/kernel/slab/eventpoll_epi/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/eventpoll_epi/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/eventpoll_epi/align', 0o664, b'0\n')
+f('sys/kernel/slab/eventpoll_epi/partial', 0o664, b'2\n')
+f('sys/kernel/slab/eventpoll_epi/validate', 0o664, b'')
+f('sys/kernel/slab/eventpoll_epi/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/eventpoll_epi/free_calls', 0o664, b''' 61 <not-available> age=4303046803 pid=0 cpus=0
+ 4 ep_remove+0xae/0xc0 age=2416461/6864194/8356250 pid=1690-2073 cpus=0-1
+''')
+f('sys/kernel/slab/eventpoll_epi/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/revoke_table', 0o775)
+f('sys/kernel/slab/revoke_table/reclaim_account', 0o664, b'1\n')
+f('sys/kernel/slab/revoke_table/ctor', 0o664, b'')
+f('sys/kernel/slab/revoke_table/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/revoke_table/slab_size', 0o664, b'88\n')
+f('sys/kernel/slab/revoke_table/total_objects', 0o664, b'46\n')
+f('sys/kernel/slab/revoke_table/slabs', 0o664, b'1\n')
+f('sys/kernel/slab/revoke_table/poison', 0o664, b'1\n')
+f('sys/kernel/slab/revoke_table/alloc_calls', 0o664, b' 4 journal_init_revoke_table+0x1b/0xb0 age=8369805/8374155/8378505 pid=1-962 cpus=0\n')
+f('sys/kernel/slab/revoke_table/objs_per_slab', 0o664, b'46\n')
+f('sys/kernel/slab/revoke_table/shrink', 0o664, b'')
+f('sys/kernel/slab/revoke_table/trace', 0o664, b'0\n')
+f('sys/kernel/slab/revoke_table/object_size', 0o664, b'16\n')
+f('sys/kernel/slab/revoke_table/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/revoke_table/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/revoke_table/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/revoke_table/objects_partial', 0o664, b'4\n')
+f('sys/kernel/slab/revoke_table/objects', 0o664, b'4\n')
+f('sys/kernel/slab/revoke_table/order', 0o664, b'0\n')
+f('sys/kernel/slab/revoke_table/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/revoke_table/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/revoke_table/align', 0o664, b'0\n')
+f('sys/kernel/slab/revoke_table/partial', 0o664, b'1\n')
+f('sys/kernel/slab/revoke_table/validate', 0o664, b'')
+f('sys/kernel/slab/revoke_table/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/revoke_table/free_calls', 0o664, b' 4 <not-available> age=4303047546 pid=0 cpus=0\n')
+f('sys/kernel/slab/revoke_table/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/sgpool-32', 0o775)
+f('sys/kernel/slab/sgpool-32/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-32/ctor', 0o664, b'')
+f('sys/kernel/slab/sgpool-32/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-32/slab_size', 0o664, b'1152\n')
+f('sys/kernel/slab/sgpool-32/total_objects', 0o664, b'28\n')
+f('sys/kernel/slab/sgpool-32/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/sgpool-32/poison', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-32/alloc_calls', 0o664, b' 2 mempool_alloc_slab+0x11/0x20 age=8379280/8379280/8379280 pid=1 cpus=0\n')
+f('sys/kernel/slab/sgpool-32/objs_per_slab', 0o664, b'14\n')
+f('sys/kernel/slab/sgpool-32/shrink', 0o664, b'')
+f('sys/kernel/slab/sgpool-32/trace', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-32/object_size', 0o664, b'1024\n')
+f('sys/kernel/slab/sgpool-32/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-32/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-32/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-32/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-32/objects', 0o664, b'28\n')
+f('sys/kernel/slab/sgpool-32/order', 0o664, b'2\n')
+f('sys/kernel/slab/sgpool-32/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-32/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-32/align', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-32/partial', 0o664, b'0\n')
+f('sys/kernel/slab/sgpool-32/validate', 0o664, b'')
+f('sys/kernel/slab/sgpool-32/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/sgpool-32/free_calls', 0o664, b' 2 <not-available> age=4303046829 pid=0 cpus=0\n')
+f('sys/kernel/slab/sgpool-32/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/fib6_nodes', 0o775)
+f('sys/kernel/slab/fib6_nodes/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/fib6_nodes/ctor', 0o664, b'')
+f('sys/kernel/slab/fib6_nodes/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/fib6_nodes/slab_size', 0o664, b'128\n')
+f('sys/kernel/slab/fib6_nodes/total_objects', 0o664, b'64\n')
+f('sys/kernel/slab/fib6_nodes/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/fib6_nodes/poison', 0o664, b'1\n')
+f('sys/kernel/slab/fib6_nodes/alloc_calls', 0o664, b''' 3 fib6_add+0x112/0x6a0 [ipv6] age=8328809/8339785/8360575 pid=8-2080 cpus=0-1
+ 1 fib6_add+0x2a2/0x6a0 [ipv6] age=8329973 pid=8 cpus=1
+ 1 fib6_add+0x2b6/0x6a0 [ipv6] age=8329973 pid=8 cpus=1
+''')
+f('sys/kernel/slab/fib6_nodes/objs_per_slab', 0o664, b'32\n')
+f('sys/kernel/slab/fib6_nodes/shrink', 0o664, b'')
+f('sys/kernel/slab/fib6_nodes/trace', 0o664, b'0\n')
+f('sys/kernel/slab/fib6_nodes/object_size', 0o664, b'48\n')
+f('sys/kernel/slab/fib6_nodes/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/fib6_nodes/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/fib6_nodes/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/fib6_nodes/objects_partial', 0o664, b'5\n')
+f('sys/kernel/slab/fib6_nodes/objects', 0o664, b'5\n')
+f('sys/kernel/slab/fib6_nodes/order', 0o664, b'0\n')
+f('sys/kernel/slab/fib6_nodes/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/fib6_nodes/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/fib6_nodes/align', 0o664, b'0\n')
+f('sys/kernel/slab/fib6_nodes/partial', 0o664, b'2\n')
+f('sys/kernel/slab/fib6_nodes/validate', 0o664, b'')
+f('sys/kernel/slab/fib6_nodes/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/fib6_nodes/free_calls', 0o664, b' 5 <not-available> age=4303047799 pid=0 cpus=0\n')
+f('sys/kernel/slab/fib6_nodes/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/flow_cache', 0o775)
+f('sys/kernel/slab/flow_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/flow_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/flow_cache/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/flow_cache/slab_size', 0o664, b'168\n')
+f('sys/kernel/slab/flow_cache/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/flow_cache/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/flow_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/flow_cache/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/flow_cache/objs_per_slab', 0o664, b'24\n')
+f('sys/kernel/slab/flow_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/flow_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/flow_cache/object_size', 0o664, b'96\n')
+f('sys/kernel/slab/flow_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/flow_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/flow_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/flow_cache/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/flow_cache/objects', 0o664, b'0\n')
+f('sys/kernel/slab/flow_cache/order', 0o664, b'0\n')
+f('sys/kernel/slab/flow_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/flow_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/flow_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/flow_cache/partial', 0o664, b'0\n')
+f('sys/kernel/slab/flow_cache/validate', 0o664, b'')
+f('sys/kernel/slab/flow_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/flow_cache/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/flow_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/fat_cache', 0o775)
+f('sys/kernel/slab/fat_cache/reclaim_account', 0o664, b'1\n')
+f('sys/kernel/slab/fat_cache/ctor', 0o664, b'init_once+0x0/0x10\n')
+f('sys/kernel/slab/fat_cache/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/fat_cache/slab_size', 0o664, b'104\n')
+f('sys/kernel/slab/fat_cache/total_objects', 0o664, b'39\n')
+f('sys/kernel/slab/fat_cache/slabs', 0o664, b'1\n')
+f('sys/kernel/slab/fat_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/fat_cache/alloc_calls', 0o664, b' 14 fat_cache_add+0x11f/0x1c0 age=61297/61310/61330 pid=13349 cpus=0\n')
+f('sys/kernel/slab/fat_cache/objs_per_slab', 0o664, b'39\n')
+f('sys/kernel/slab/fat_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/fat_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/fat_cache/object_size', 0o664, b'32\n')
+f('sys/kernel/slab/fat_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/fat_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/fat_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/fat_cache/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/fat_cache/objects', 0o664, b'39\n')
+f('sys/kernel/slab/fat_cache/order', 0o664, b'0\n')
+f('sys/kernel/slab/fat_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/fat_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/fat_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/fat_cache/partial', 0o664, b'0\n')
+f('sys/kernel/slab/fat_cache/validate', 0o664, b'')
+f('sys/kernel/slab/fat_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/fat_cache/free_calls', 0o664, b' 14 <not-available> age=4303047585 pid=0 cpus=0\n')
+f('sys/kernel/slab/fat_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/sock_inode_cache', 0o775)
+f('sys/kernel/slab/sock_inode_cache/reclaim_account', 0o664, b'1\n')
+f('sys/kernel/slab/sock_inode_cache/ctor', 0o664, b'init_once+0x0/0x10\n')
+f('sys/kernel/slab/sock_inode_cache/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/sock_inode_cache/slab_size', 0o664, b'1280\n')
+f('sys/kernel/slab/sock_inode_cache/total_objects', 0o664, b'504\n')
+f('sys/kernel/slab/sock_inode_cache/slabs', 0o664, b'42\n')
+f('sys/kernel/slab/sock_inode_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/sock_inode_cache/alloc_calls', 0o664, b' 481 sock_alloc_inode+0x1a/0x70 age=61330/8214562/8379530 pid=1-20296 cpus=0-1\n')
+f('sys/kernel/slab/sock_inode_cache/objs_per_slab', 0o664, b'12\n')
+f('sys/kernel/slab/sock_inode_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/sock_inode_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/sock_inode_cache/object_size', 0o664, b'1192\n')
+f('sys/kernel/slab/sock_inode_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/sock_inode_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/sock_inode_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/sock_inode_cache/objects_partial', 0o664, b'83\n')
+f('sys/kernel/slab/sock_inode_cache/objects', 0o664, b'491\n')
+f('sys/kernel/slab/sock_inode_cache/order', 0o664, b'2\n')
+f('sys/kernel/slab/sock_inode_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/sock_inode_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/sock_inode_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/sock_inode_cache/partial', 0o664, b'8\n')
+f('sys/kernel/slab/sock_inode_cache/validate', 0o664, b'')
+f('sys/kernel/slab/sock_inode_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/sock_inode_cache/free_calls', 0o664, b''' 276 <not-available> age=4303046961 pid=0 cpus=0
+ 205 sock_destroy_inode+0x14/0x20 age=61348/8035806/8376228 pid=76-20292 cpus=0-1
+''')
+f('sys/kernel/slab/sock_inode_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/ip_fib_hash', 0o775)
+f('sys/kernel/slab/ip_fib_hash/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/ip_fib_hash/ctor', 0o664, b'')
+f('sys/kernel/slab/ip_fib_hash/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/ip_fib_hash/slab_size', 0o664, b'144\n')
+f('sys/kernel/slab/ip_fib_hash/total_objects', 0o664, b'56\n')
+f('sys/kernel/slab/ip_fib_hash/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/ip_fib_hash/poison', 0o664, b'1\n')
+f('sys/kernel/slab/ip_fib_hash/alloc_calls', 0o664, b' 11 fn_hash_insert+0x5a6/0x800 age=8323831/8347847/8367198 pid=1197-1541 cpus=0-1\n')
+f('sys/kernel/slab/ip_fib_hash/objs_per_slab', 0o664, b'28\n')
+f('sys/kernel/slab/ip_fib_hash/shrink', 0o664, b'')
+f('sys/kernel/slab/ip_fib_hash/trace', 0o664, b'0\n')
+f('sys/kernel/slab/ip_fib_hash/object_size', 0o664, b'72\n')
+f('sys/kernel/slab/ip_fib_hash/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/ip_fib_hash/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/ip_fib_hash/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/ip_fib_hash/objects_partial', 0o664, b'11\n')
+f('sys/kernel/slab/ip_fib_hash/objects', 0o664, b'11\n')
+f('sys/kernel/slab/ip_fib_hash/order', 0o664, b'0\n')
+f('sys/kernel/slab/ip_fib_hash/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/ip_fib_hash/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/ip_fib_hash/align', 0o664, b'0\n')
+f('sys/kernel/slab/ip_fib_hash/partial', 0o664, b'2\n')
+f('sys/kernel/slab/ip_fib_hash/validate', 0o664, b'')
+f('sys/kernel/slab/ip_fib_hash/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/ip_fib_hash/free_calls', 0o664, b''' 7 <not-available> age=4303046724 pid=0 cpus=0
+ 4 fn_hash_delete+0x22c/0x290 age=8367201/8367201/8367201 pid=1195 cpus=1
+''')
+f('sys/kernel/slab/ip_fib_hash/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/kmalloc_dma-512', 0o775)
+f('sys/kernel/slab/kmalloc_dma-512/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc_dma-512/ctor', 0o664, b'')
+f('sys/kernel/slab/kmalloc_dma-512/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc_dma-512/slab_size', 0o664, b'584\n')
+f('sys/kernel/slab/kmalloc_dma-512/total_objects', 0o664, b'14\n')
+f('sys/kernel/slab/kmalloc_dma-512/slabs', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc_dma-512/poison', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc_dma-512/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/kmalloc_dma-512/objs_per_slab', 0o664, b'14\n')
+f('sys/kernel/slab/kmalloc_dma-512/shrink', 0o664, b'')
+f('sys/kernel/slab/kmalloc_dma-512/trace', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc_dma-512/object_size', 0o664, b'512\n')
+f('sys/kernel/slab/kmalloc_dma-512/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc_dma-512/cache_dma', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc_dma-512/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc_dma-512/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc_dma-512/objects', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc_dma-512/order', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc_dma-512/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc_dma-512/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc_dma-512/align', 0o664, b'8\n')
+f('sys/kernel/slab/kmalloc_dma-512/partial', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc_dma-512/validate', 0o664, b'')
+f('sys/kernel/slab/kmalloc_dma-512/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc_dma-512/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/kmalloc_dma-512/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/inode_cache', 0o775)
+f('sys/kernel/slab/inode_cache/reclaim_account', 0o664, b'1\n')
+f('sys/kernel/slab/inode_cache/ctor', 0o664, b'init_once+0x0/0x10\n')
+f('sys/kernel/slab/inode_cache/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/inode_cache/slab_size', 0o664, b'1144\n')
+f('sys/kernel/slab/inode_cache/total_objects', 0o664, b'11676\n')
+f('sys/kernel/slab/inode_cache/slabs', 0o664, b'834\n')
+f('sys/kernel/slab/inode_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/inode_cache/alloc_calls', 0o664, b' 11655 alloc_inode+0x251/0x280 age=665/7686826/8379810 pid=0-13466 cpus=0-1\n')
+f('sys/kernel/slab/inode_cache/objs_per_slab', 0o664, b'14\n')
+f('sys/kernel/slab/inode_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/inode_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/inode_cache/object_size', 0o664, b'1072\n')
+f('sys/kernel/slab/inode_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/inode_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/inode_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/inode_cache/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/inode_cache/objects', 0o664, b'11676\n')
+f('sys/kernel/slab/inode_cache/order', 0o664, b'2\n')
+f('sys/kernel/slab/inode_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/inode_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/inode_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/inode_cache/partial', 0o664, b'0\n')
+f('sys/kernel/slab/inode_cache/validate', 0o664, b'')
+f('sys/kernel/slab/inode_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/inode_cache/free_calls', 0o664, b''' 11113 <not-available> age=4303047110 pid=0 cpus=0
+ 542 destroy_inode+0x4f/0x60 age=1016/6891707/8377435 pid=7-15896 cpus=0-1
+''')
+f('sys/kernel/slab/inode_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/inotify_event_cache', 0o775)
+f('sys/kernel/slab/inotify_event_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/inotify_event_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/inotify_event_cache/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/inotify_event_cache/slab_size', 0o664, b'112\n')
+f('sys/kernel/slab/inotify_event_cache/total_objects', 0o664, b'72\n')
+f('sys/kernel/slab/inotify_event_cache/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/inotify_event_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/inotify_event_cache/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/inotify_event_cache/objs_per_slab', 0o664, b'36\n')
+f('sys/kernel/slab/inotify_event_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/inotify_event_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/inotify_event_cache/object_size', 0o664, b'40\n')
+f('sys/kernel/slab/inotify_event_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/inotify_event_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/inotify_event_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/inotify_event_cache/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/inotify_event_cache/objects', 0o664, b'72\n')
+f('sys/kernel/slab/inotify_event_cache/order', 0o664, b'0\n')
+f('sys/kernel/slab/inotify_event_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/inotify_event_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/inotify_event_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/inotify_event_cache/partial', 0o664, b'0\n')
+f('sys/kernel/slab/inotify_event_cache/validate', 0o664, b'')
+f('sys/kernel/slab/inotify_event_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/inotify_event_cache/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/inotify_event_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/UDP', 0o775)
+f('sys/kernel/slab/UDP/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/UDP/ctor', 0o664, b'')
+f('sys/kernel/slab/UDP/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/UDP/slab_size', 0o664, b'1344\n')
+f('sys/kernel/slab/UDP/total_objects', 0o664, b'24\n')
+f('sys/kernel/slab/UDP/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/UDP/poison', 0o664, b'1\n')
+f('sys/kernel/slab/UDP/alloc_calls', 0o664, b' 5 sk_prot_alloc+0x1e/0xb0 age=8327731/8349275/8355457 pid=1545-2586 cpus=0-1\n')
+f('sys/kernel/slab/UDP/objs_per_slab', 0o664, b'12\n')
+f('sys/kernel/slab/UDP/shrink', 0o664, b'')
+f('sys/kernel/slab/UDP/trace', 0o664, b'0\n')
+f('sys/kernel/slab/UDP/object_size', 0o664, b'1232\n')
+f('sys/kernel/slab/UDP/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/UDP/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/UDP/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/UDP/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/UDP/objects', 0o664, b'24\n')
+f('sys/kernel/slab/UDP/order', 0o664, b'2\n')
+f('sys/kernel/slab/UDP/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/UDP/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/UDP/align', 0o664, b'0\n')
+f('sys/kernel/slab/UDP/partial', 0o664, b'0\n')
+f('sys/kernel/slab/UDP/validate', 0o664, b'')
+f('sys/kernel/slab/UDP/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/UDP/free_calls', 0o664, b''' 1 <not-available> age=4303046759 pid=0 cpus=0
+ 4 sk_free+0x80/0x100 age=8327731/8350484/8364461 pid=1371-2586 cpus=0-1
+''')
+f('sys/kernel/slab/UDP/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/Acpi-ParseExt', 0o775)
+f('sys/kernel/slab/Acpi-ParseExt/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-ParseExt/ctor', 0o664, b'')
+f('sys/kernel/slab/Acpi-ParseExt/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-ParseExt/slab_size', 0o664, b'144\n')
+f('sys/kernel/slab/Acpi-ParseExt/total_objects', 0o664, b'56\n')
+f('sys/kernel/slab/Acpi-ParseExt/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/Acpi-ParseExt/poison', 0o664, b'1\n')
+f('sys/kernel/slab/Acpi-ParseExt/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/Acpi-ParseExt/objs_per_slab', 0o664, b'28\n')
+f('sys/kernel/slab/Acpi-ParseExt/shrink', 0o664, b'')
+f('sys/kernel/slab/Acpi-ParseExt/trace', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-ParseExt/object_size', 0o664, b'72\n')
+f('sys/kernel/slab/Acpi-ParseExt/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-ParseExt/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-ParseExt/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-ParseExt/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-ParseExt/objects', 0o664, b'56\n')
+f('sys/kernel/slab/Acpi-ParseExt/order', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-ParseExt/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/Acpi-ParseExt/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/Acpi-ParseExt/align', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-ParseExt/partial', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-ParseExt/validate', 0o664, b'')
+f('sys/kernel/slab/Acpi-ParseExt/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/Acpi-ParseExt/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/Acpi-ParseExt/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/kmalloc-8', 0o775)
+f('sys/kernel/slab/kmalloc-8/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-8/ctor', 0o664, b'')
+f('sys/kernel/slab/kmalloc-8/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-8/slab_size', 0o664, b'80\n')
+f('sys/kernel/slab/kmalloc-8/total_objects', 0o664, b'3366\n')
+f('sys/kernel/slab/kmalloc-8/slabs', 0o664, b'66\n')
+f('sys/kernel/slab/kmalloc-8/poison', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-8/alloc_calls', 0o664, b''' 1 cache_k8_northbridges+0x5f/0x130 age=8379864 pid=1 cpus=0
+ 1 pm_qos_add_requirement+0x51/0xe0 age=8376100 pid=122 cpus=1
+ 5 setup_modinfo_version+0x19/0x30 age=8355991/8370769/8376336 pid=169-1766 cpus=0-1
+ 379 load_module+0x1ac4/0x1b30 age=8303091/8368856/8376330 pid=105-2754 cpus=0-1
+ 57 strndup_user+0x6d/0xc0 age=8303095/8368234/8376336 pid=105-2754 cpus=0-1
+ 4 krealloc+0x1e/0x60 age=8355270/8362240/8377141 pid=71-1849 cpus=0-1
+ 5 __vmalloc_area_node+0xfb/0x140 age=8373659/8374450/8375164 pid=181-754 cpus=0-1
+ 17 alloc_vfsmnt+0x97/0x180 age=8354102/8377143/8380122 pid=0-2064 cpus=0-1
+ 1 proc_symlink+0x4d/0xb0 age=8374163 pid=107 cpus=1
+ 1954 sysfs_new_dirent+0x10c/0x120 age=22655/7531182/8380122 pid=0-13295 cpus=0-1
+ 690 kvasprintf+0x55/0x90 age=22668/7820060/8380122 pid=0-13295 cpus=0-1
+ 1 proc_bus_pci_open+0x1d/0x50 age=8355838 pid=1738 cpus=0
+ 5 pcie_port_device_register+0x25/0x4a0 age=8379822/8379823/8379824 pid=1 cpus=1
+ 19 acpi_ds_build_internal_buffer_obj+0xe1/0x121 age=8379961/8379970/8379972 pid=1 cpus=0
+ 9 acpi_ev_pci_config_region_setup+0x162/0x270 age=8379256/8379854/8379947 pid=1-12 cpus=0-1
+ 2 acpi_ut_copy_simple_object+0x8f/0x11c age=8375678/8375686/8375694 pid=396 cpus=0
+ 35 acpi_irq_stats_init+0x1bd/0x268 age=8379979/8379979/8379979 pid=1 cpus=0
+ 8 neigh_sysctl_register+0x1cd/0x330 age=8360192/8368781/8379845 pid=1-1549 cpus=0-1
+ 7 netlink_kernel_create+0xab/0x1a0 age=8378987/8379768/8379988 pid=1 cpus=0-1
+ 5 __devinet_sysctl_register+0xb8/0x120 age=8373658/8377862/8379845 pid=1-126 cpus=0-1
+ 1 fz_hash_alloc+0x4a/0x60 age=8324525 pid=1541 cpus=0
+ 1 init_vdso_vars+0x4c/0x24a age=8379835 pid=1 cpus=1
+ 30 netlink_proto_init+0xf1/0x16b age=8379988/8379988/8379988 pid=1 cpus=0
+ 5 hub_probe+0x20b/0x820 [usbcore] age=8374075/8374568/8374921 pid=143-147 cpus=0-1
+ 3 usb_cache_string+0x65/0xa0 [usbcore] age=22742/37518/67072 pid=419 cpus=0
+ 10 usb_get_configuration+0xbd/0x1480 [usbcore] age=22743/5876145/8374941 pid=143-419 cpus=0-1
+ 35 snd_info_create_entry+0x30/0xa0 [snd] age=8355370/8370655/8374933 pid=107-1813 cpus=0-1
+ 1 async_chainiv_givencrypt_first+0x56/0x80 [crypto_blkcipher] age=8374580 pid=215 cpus=0
+ 1 md_seq_open+0x2d/0x90 [md_mod] age=8366135 pid=1371 cpus=0
+ 1 bitmap_create+0x3aa/0xad0 [md_mod] age=8370125 pid=916 cpus=0
+ 5 __addrconf_sysctl_register+0xcd/0x140 [ipv6] age=8360192/8360193/8360195 pid=1549 cpus=0
+ 1 fib6_net_init+0x5d/0x130 [ipv6] age=8360195 pid=1549 cpus=0
+''')
+f('sys/kernel/slab/kmalloc-8/objs_per_slab', 0o664, b'51\n')
+f('sys/kernel/slab/kmalloc-8/shrink', 0o664, b'')
+f('sys/kernel/slab/kmalloc-8/trace', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-8/object_size', 0o664, b'8\n')
+f('sys/kernel/slab/kmalloc-8/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-8/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-8/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-8/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-8/objects', 0o664, b'3366\n')
+f('sys/kernel/slab/kmalloc-8/order', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-8/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-8/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-8/align', 0o664, b'8\n')
+f('sys/kernel/slab/kmalloc-8/partial', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-8/validate', 0o664, b'')
+f('sys/kernel/slab/kmalloc-8/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-8/free_calls', 0o664, b''' 2657 <not-available> age=4303047420 pid=0 cpus=0
+ 3 free_sect_attrs+0x2e/0x50 age=8375066/8375066/8375066 pid=383 cpus=0
+ 6 load_module+0x73f/0x1b30 age=8374844/8375309/8376003 pid=143-332 cpus=0-1
+ 1 free_module+0xb9/0xf0 age=8375066 pid=383 cpus=0
+ 1 krealloc+0x3a/0x60 age=8375814 pid=330 cpus=0
+ 41 __vunmap+0xe9/0x120 age=8355636/8372979/8376319 pid=105-1805 cpus=0-1
+ 1 vfs_rename+0x301/0x450 age=8367176 pid=72 cpus=1
+ 254 release_sysfs_dirent+0x8c/0xd0 age=125751/7762571/8379789 pid=1-3347 cpus=0-1
+ 61 kobject_release+0xe1/0x140 age=125751/6939731/8378264 pid=1-3347 cpus=0-1
+ 1 match_number+0x95/0xb0 age=8335823 pid=2476 cpus=0
+ 2 proc_bus_pci_release+0x18/0x30 age=8355841/8356005/8356169 pid=1738 cpus=0
+ 49 acpi_ds_create_operand+0x12c/0x209 age=125757/8029619/8379980 pid=1-1442 cpus=0-1
+ 128 acpi_ns_get_node+0x92/0xa1 age=8366449/8379363/8379989 pid=1-1358 cpus=0-1
+ 2 acpi_ut_delete_internal_obj+0x15f/0x16f age=8375669/8375730/8375792 pid=330-396 cpus=0
+ 2 module_add_driver+0x66/0xd0 age=8375989/8375992/8375996 pid=144 cpus=0
+ 2 sd_media_changed+0xca/0x210 age=7839601/7929600/8019600 pid=2796 cpus=0
+ 3 get_modalias+0xd4/0x120 age=8355846/8370834/8379988 pid=1-1772 cpus=0-1
+ 1 fib_hash_free+0x35/0x40 age=8367910 pid=1185 cpus=0
+ 1 usb_release_dev+0x39/0x70 [usbcore] age=7833240 pid=419 cpus=1
+ 2 usb_release_dev+0x45/0x70 [usbcore] age=7833240/7835719/7838199 pid=419 cpus=0-1
+ 4 sg_clean+0x3e/0x80 [usbcore] age=62037/2121033/8297977 pid=2760-13294 cpus=0
+ 59 usb_control_msg+0xef/0x110 [usbcore] age=22658/5520135/8374943 pid=143-419 cpus=0-1
+ 7 usb_set_configuration+0x338/0x5f0 [usbcore] age=53566/5999072/8374935 pid=143-419 cpus=0-1
+ 4 usb_destroy_configuration+0x78/0x140 [usbcore] age=7824401/7967435/8373902 pid=419 cpus=0-1
+ 7 sr_media_change+0xeb/0x2a0 [sr_mod] age=53597/5984195/8374963 pid=558-1456 cpus=0-1
+''')
+f('sys/kernel/slab/kmalloc-8/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/revoke_record', 0o775)
+f('sys/kernel/slab/revoke_record/reclaim_account', 0o664, b'1\n')
+f('sys/kernel/slab/revoke_record/ctor', 0o664, b'')
+f('sys/kernel/slab/revoke_record/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/revoke_record/slab_size', 0o664, b'128\n')
+f('sys/kernel/slab/revoke_record/total_objects', 0o664, b'64\n')
+f('sys/kernel/slab/revoke_record/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/revoke_record/poison', 0o664, b'1\n')
+f('sys/kernel/slab/revoke_record/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/revoke_record/objs_per_slab', 0o664, b'32\n')
+f('sys/kernel/slab/revoke_record/shrink', 0o664, b'')
+f('sys/kernel/slab/revoke_record/trace', 0o664, b'0\n')
+f('sys/kernel/slab/revoke_record/object_size', 0o664, b'32\n')
+f('sys/kernel/slab/revoke_record/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/revoke_record/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/revoke_record/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/revoke_record/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/revoke_record/objects', 0o664, b'64\n')
+f('sys/kernel/slab/revoke_record/order', 0o664, b'0\n')
+f('sys/kernel/slab/revoke_record/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/revoke_record/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/revoke_record/align', 0o664, b'0\n')
+f('sys/kernel/slab/revoke_record/partial', 0o664, b'0\n')
+f('sys/kernel/slab/revoke_record/validate', 0o664, b'')
+f('sys/kernel/slab/revoke_record/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/revoke_record/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/revoke_record/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/ext3_inode_cache', 0o775)
+f('sys/kernel/slab/ext3_inode_cache/reclaim_account', 0o664, b'1\n')
+f('sys/kernel/slab/ext3_inode_cache/ctor', 0o664, b'init_once+0x0/0x70\n')
+f('sys/kernel/slab/ext3_inode_cache/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/ext3_inode_cache/slab_size', 0o664, b'1544\n')
+f('sys/kernel/slab/ext3_inode_cache/total_objects', 0o664, b'27342\n')
+f('sys/kernel/slab/ext3_inode_cache/slabs', 0o664, b'1302\n')
+f('sys/kernel/slab/ext3_inode_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/ext3_inode_cache/alloc_calls', 0o664, b' 27338 ext3_alloc_inode+0x15/0x60 age=0/2288559/8378475 pid=1-27944 cpus=0-1\n')
+f('sys/kernel/slab/ext3_inode_cache/objs_per_slab', 0o664, b'21\n')
+f('sys/kernel/slab/ext3_inode_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/ext3_inode_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/ext3_inode_cache/object_size', 0o664, b'1472\n')
+f('sys/kernel/slab/ext3_inode_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/ext3_inode_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/ext3_inode_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/ext3_inode_cache/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/ext3_inode_cache/objects', 0o664, b'27342\n')
+f('sys/kernel/slab/ext3_inode_cache/order', 0o664, b'3\n')
+f('sys/kernel/slab/ext3_inode_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/ext3_inode_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/ext3_inode_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/ext3_inode_cache/partial', 0o664, b'0\n')
+f('sys/kernel/slab/ext3_inode_cache/validate', 0o664, b'')
+f('sys/kernel/slab/ext3_inode_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/ext3_inode_cache/free_calls', 0o664, b''' 25981 <not-available> age=4303047521 pid=0 cpus=0
+ 1358 ext3_destroy_inode+0x2f/0x90 age=13089/2437961/8371953 pid=542-32759 cpus=0-1
+''')
+f('sys/kernel/slab/ext3_inode_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/ndisc_cache', 0o775)
+f('sys/kernel/slab/ndisc_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/ndisc_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/ndisc_cache/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/ndisc_cache/slab_size', 0o664, b'448\n')
+f('sys/kernel/slab/ndisc_cache/total_objects', 0o664, b'18\n')
+f('sys/kernel/slab/ndisc_cache/slabs', 0o664, b'1\n')
+f('sys/kernel/slab/ndisc_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/ndisc_cache/alloc_calls', 0o664, b' 1 neigh_create+0x8b/0x530 age=8360557 pid=1549 cpus=0\n')
+f('sys/kernel/slab/ndisc_cache/objs_per_slab', 0o664, b'18\n')
+f('sys/kernel/slab/ndisc_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/ndisc_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/ndisc_cache/object_size', 0o664, b'360\n')
+f('sys/kernel/slab/ndisc_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/ndisc_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/ndisc_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/ndisc_cache/objects_partial', 0o664, b'1\n')
+f('sys/kernel/slab/ndisc_cache/objects', 0o664, b'1\n')
+f('sys/kernel/slab/ndisc_cache/order', 0o664, b'1\n')
+f('sys/kernel/slab/ndisc_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/ndisc_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/ndisc_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/ndisc_cache/partial', 0o664, b'1\n')
+f('sys/kernel/slab/ndisc_cache/validate', 0o664, b'')
+f('sys/kernel/slab/ndisc_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/ndisc_cache/free_calls', 0o664, b' 1 <not-available> age=4303047782 pid=0 cpus=0\n')
+f('sys/kernel/slab/ndisc_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/ip_fib_alias', 0o775)
+f('sys/kernel/slab/ip_fib_alias/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/ip_fib_alias/ctor', 0o664, b'')
+f('sys/kernel/slab/ip_fib_alias/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/ip_fib_alias/slab_size', 0o664, b'104\n')
+f('sys/kernel/slab/ip_fib_alias/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/ip_fib_alias/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/ip_fib_alias/poison', 0o664, b'1\n')
+f('sys/kernel/slab/ip_fib_alias/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/ip_fib_alias/objs_per_slab', 0o664, b'39\n')
+f('sys/kernel/slab/ip_fib_alias/shrink', 0o664, b'')
+f('sys/kernel/slab/ip_fib_alias/trace', 0o664, b'0\n')
+f('sys/kernel/slab/ip_fib_alias/object_size', 0o664, b'32\n')
+f('sys/kernel/slab/ip_fib_alias/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/ip_fib_alias/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/ip_fib_alias/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/ip_fib_alias/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/ip_fib_alias/objects', 0o664, b'0\n')
+f('sys/kernel/slab/ip_fib_alias/order', 0o664, b'0\n')
+f('sys/kernel/slab/ip_fib_alias/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/ip_fib_alias/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/ip_fib_alias/align', 0o664, b'0\n')
+f('sys/kernel/slab/ip_fib_alias/partial', 0o664, b'0\n')
+f('sys/kernel/slab/ip_fib_alias/validate', 0o664, b'')
+f('sys/kernel/slab/ip_fib_alias/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/ip_fib_alias/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/ip_fib_alias/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/proc_inode_cache', 0o775)
+f('sys/kernel/slab/proc_inode_cache/reclaim_account', 0o664, b'1\n')
+f('sys/kernel/slab/proc_inode_cache/ctor', 0o664, b'init_once+0x0/0x10\n')
+f('sys/kernel/slab/proc_inode_cache/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/proc_inode_cache/slab_size', 0o664, b'1192\n')
+f('sys/kernel/slab/proc_inode_cache/total_objects', 0o664, b'1677\n')
+f('sys/kernel/slab/proc_inode_cache/slabs', 0o664, b'129\n')
+f('sys/kernel/slab/proc_inode_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/proc_inode_cache/alloc_calls', 0o664, b' 1627 proc_alloc_inode+0x1b/0x90 age=61424/8163415/8379746 pid=0-19241 cpus=0-1\n')
+f('sys/kernel/slab/proc_inode_cache/objs_per_slab', 0o664, b'13\n')
+f('sys/kernel/slab/proc_inode_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/proc_inode_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/proc_inode_cache/object_size', 0o664, b'1120\n')
+f('sys/kernel/slab/proc_inode_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/proc_inode_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/proc_inode_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/proc_inode_cache/objects_partial', 0o664, b'78\n')
+f('sys/kernel/slab/proc_inode_cache/objects', 0o664, b'1651\n')
+f('sys/kernel/slab/proc_inode_cache/order', 0o664, b'2\n')
+f('sys/kernel/slab/proc_inode_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/proc_inode_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/proc_inode_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/proc_inode_cache/partial', 0o664, b'8\n')
+f('sys/kernel/slab/proc_inode_cache/validate', 0o664, b'')
+f('sys/kernel/slab/proc_inode_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/proc_inode_cache/free_calls', 0o664, b''' 1124 <not-available> age=4303047043 pid=0 cpus=0
+ 503 proc_destroy_inode+0x14/0x20 age=61430/7970819/8372808 pid=1-12336 cpus=0-1
+''')
+f('sys/kernel/slab/proc_inode_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/biovec-16', 0o775)
+f('sys/kernel/slab/biovec-16/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-16/ctor', 0o664, b'')
+f('sys/kernel/slab/biovec-16/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-16/slab_size', 0o664, b'384\n')
+f('sys/kernel/slab/biovec-16/total_objects', 0o664, b'63\n')
+f('sys/kernel/slab/biovec-16/slabs', 0o664, b'3\n')
+f('sys/kernel/slab/biovec-16/poison', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-16/alloc_calls', 0o664, b' 2 mempool_alloc_slab+0x11/0x20 age=8379491/8379491/8379491 pid=1 cpus=0\n')
+f('sys/kernel/slab/biovec-16/objs_per_slab', 0o664, b'21\n')
+f('sys/kernel/slab/biovec-16/shrink', 0o664, b'')
+f('sys/kernel/slab/biovec-16/trace', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-16/object_size', 0o664, b'256\n')
+f('sys/kernel/slab/biovec-16/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-16/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-16/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-16/objects_partial', 0o664, b'2\n')
+f('sys/kernel/slab/biovec-16/objects', 0o664, b'44\n')
+f('sys/kernel/slab/biovec-16/order', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-16/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-16/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-16/align', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-16/partial', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-16/validate', 0o664, b'')
+f('sys/kernel/slab/biovec-16/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-16/free_calls', 0o664, b' 2 <not-available> age=4303046925 pid=0 cpus=0\n')
+f('sys/kernel/slab/biovec-16/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/Acpi-State', 0o775)
+f('sys/kernel/slab/Acpi-State/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-State/ctor', 0o664, b'')
+f('sys/kernel/slab/Acpi-State/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-State/slab_size', 0o664, b'152\n')
+f('sys/kernel/slab/Acpi-State/total_objects', 0o664, b'52\n')
+f('sys/kernel/slab/Acpi-State/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/Acpi-State/poison', 0o664, b'1\n')
+f('sys/kernel/slab/Acpi-State/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/Acpi-State/objs_per_slab', 0o664, b'26\n')
+f('sys/kernel/slab/Acpi-State/shrink', 0o664, b'')
+f('sys/kernel/slab/Acpi-State/trace', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-State/object_size', 0o664, b'80\n')
+f('sys/kernel/slab/Acpi-State/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-State/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-State/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-State/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-State/objects', 0o664, b'52\n')
+f('sys/kernel/slab/Acpi-State/order', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-State/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/Acpi-State/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/Acpi-State/align', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-State/partial', 0o664, b'0\n')
+f('sys/kernel/slab/Acpi-State/validate', 0o664, b'')
+f('sys/kernel/slab/Acpi-State/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/Acpi-State/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/Acpi-State/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/ip6_dst_cache', 0o775)
+f('sys/kernel/slab/ip6_dst_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/ip6_dst_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/ip6_dst_cache/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/ip6_dst_cache/slab_size', 0o664, b'384\n')
+f('sys/kernel/slab/ip6_dst_cache/total_objects', 0o664, b'42\n')
+f('sys/kernel/slab/ip6_dst_cache/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/ip6_dst_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/ip6_dst_cache/alloc_calls', 0o664, b' 4 dst_alloc+0x2b/0x90 age=8329964/8337614/8360566 pid=8-1549 cpus=0-1\n')
+f('sys/kernel/slab/ip6_dst_cache/objs_per_slab', 0o664, b'21\n')
+f('sys/kernel/slab/ip6_dst_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/ip6_dst_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/ip6_dst_cache/object_size', 0o664, b'304\n')
+f('sys/kernel/slab/ip6_dst_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/ip6_dst_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/ip6_dst_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/ip6_dst_cache/objects_partial', 0o664, b'4\n')
+f('sys/kernel/slab/ip6_dst_cache/objects', 0o664, b'4\n')
+f('sys/kernel/slab/ip6_dst_cache/order', 0o664, b'1\n')
+f('sys/kernel/slab/ip6_dst_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/ip6_dst_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/ip6_dst_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/ip6_dst_cache/partial', 0o664, b'2\n')
+f('sys/kernel/slab/ip6_dst_cache/validate', 0o664, b'')
+f('sys/kernel/slab/ip6_dst_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/ip6_dst_cache/free_calls', 0o664, b' 4 <not-available> age=4303047790 pid=0 cpus=0\n')
+f('sys/kernel/slab/ip6_dst_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/task_xstate', 0o775)
+f('sys/kernel/slab/task_xstate/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/task_xstate/ctor', 0o664, b'')
+f('sys/kernel/slab/task_xstate/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/task_xstate/slab_size', 0o664, b'592\n')
+f('sys/kernel/slab/task_xstate/total_objects', 0o664, b'169\n')
+f('sys/kernel/slab/task_xstate/slabs', 0o664, b'13\n')
+f('sys/kernel/slab/task_xstate/poison', 0o664, b'1\n')
+f('sys/kernel/slab/task_xstate/alloc_calls', 0o664, b''' 99 arch_dup_task_struct+0x51/0xa0 age=125559/8275901/8376574 pid=71-13212 cpus=0-1
+ 51 init_fpu+0xef/0x110 age=4157/7436734/8378165 pid=1-20296 cpus=0-1
+''')
+f('sys/kernel/slab/task_xstate/objs_per_slab', 0o664, b'13\n')
+f('sys/kernel/slab/task_xstate/shrink', 0o664, b'')
+f('sys/kernel/slab/task_xstate/trace', 0o664, b'0\n')
+f('sys/kernel/slab/task_xstate/object_size', 0o664, b'512\n')
+f('sys/kernel/slab/task_xstate/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/task_xstate/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/task_xstate/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/task_xstate/objects_partial', 0o664, b'57\n')
+f('sys/kernel/slab/task_xstate/objects', 0o664, b'161\n')
+f('sys/kernel/slab/task_xstate/order', 0o664, b'1\n')
+f('sys/kernel/slab/task_xstate/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/task_xstate/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/task_xstate/align', 0o664, b'16\n')
+f('sys/kernel/slab/task_xstate/partial', 0o664, b'5\n')
+f('sys/kernel/slab/task_xstate/validate', 0o664, b'')
+f('sys/kernel/slab/task_xstate/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/task_xstate/free_calls', 0o664, b''' 53 <not-available> age=4303047277 pid=0 cpus=0
+ 97 free_thread_xstate+0x24/0x40 age=7199/7795238/8375118 pid=0-20296 cpus=0-1
+''')
+f('sys/kernel/slab/task_xstate/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/scsi_io_context', 0o775)
+f('sys/kernel/slab/scsi_io_context/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_io_context/ctor', 0o664, b'')
+f('sys/kernel/slab/scsi_io_context/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_io_context/slab_size', 0o664, b'184\n')
+f('sys/kernel/slab/scsi_io_context/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_io_context/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_io_context/poison', 0o664, b'1\n')
+f('sys/kernel/slab/scsi_io_context/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/scsi_io_context/objs_per_slab', 0o664, b'22\n')
+f('sys/kernel/slab/scsi_io_context/shrink', 0o664, b'')
+f('sys/kernel/slab/scsi_io_context/trace', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_io_context/object_size', 0o664, b'112\n')
+f('sys/kernel/slab/scsi_io_context/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_io_context/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_io_context/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_io_context/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_io_context/objects', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_io_context/order', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_io_context/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/scsi_io_context/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/scsi_io_context/align', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_io_context/partial', 0o664, b'0\n')
+f('sys/kernel/slab/scsi_io_context/validate', 0o664, b'')
+f('sys/kernel/slab/scsi_io_context/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/scsi_io_context/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/scsi_io_context/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/anon_vma', 0o775)
+f('sys/kernel/slab/anon_vma/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/anon_vma/ctor', 0o664, b'anon_vma_ctor+0x0/0x40\n')
+f('sys/kernel/slab/anon_vma/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/anon_vma/slab_size', 0o664, b'144\n')
+f('sys/kernel/slab/anon_vma/total_objects', 0o664, b'3304\n')
+f('sys/kernel/slab/anon_vma/slabs', 0o664, b'118\n')
+f('sys/kernel/slab/anon_vma/poison', 0o664, b'1\n')
+f('sys/kernel/slab/anon_vma/alloc_calls', 0o664, b' 3234 anon_vma_prepare+0xe0/0x100 age=4177/7981073/8378201 pid=1-20296 cpus=0-1\n')
+f('sys/kernel/slab/anon_vma/objs_per_slab', 0o664, b'28\n')
+f('sys/kernel/slab/anon_vma/shrink', 0o664, b'')
+f('sys/kernel/slab/anon_vma/trace', 0o664, b'0\n')
+f('sys/kernel/slab/anon_vma/object_size', 0o664, b'72\n')
+f('sys/kernel/slab/anon_vma/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/anon_vma/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/anon_vma/destroy_by_rcu', 0o664, b'1\n')
+f('sys/kernel/slab/anon_vma/objects_partial', 0o664, b'185\n')
+f('sys/kernel/slab/anon_vma/objects', 0o664, b'3265\n')
+f('sys/kernel/slab/anon_vma/order', 0o664, b'0\n')
+f('sys/kernel/slab/anon_vma/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/anon_vma/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/anon_vma/align', 0o664, b'0\n')
+f('sys/kernel/slab/anon_vma/partial', 0o664, b'8\n')
+f('sys/kernel/slab/anon_vma/validate', 0o664, b'')
+f('sys/kernel/slab/anon_vma/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/anon_vma/free_calls', 0o664, b''' 1575 <not-available> age=4303047296 pid=0 cpus=0
+ 1659 anon_vma_unlink+0x5f/0x70 age=7225/7638870/8377152 pid=56-20292 cpus=0-1
+''')
+f('sys/kernel/slab/anon_vma/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/uhci_urb_priv', 0o775)
+f('sys/kernel/slab/uhci_urb_priv/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/uhci_urb_priv/ctor', 0o664, b'')
+f('sys/kernel/slab/uhci_urb_priv/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/uhci_urb_priv/slab_size', 0o664, b'128\n')
+f('sys/kernel/slab/uhci_urb_priv/total_objects', 0o664, b'32\n')
+f('sys/kernel/slab/uhci_urb_priv/slabs', 0o664, b'1\n')
+f('sys/kernel/slab/uhci_urb_priv/poison', 0o664, b'1\n')
+f('sys/kernel/slab/uhci_urb_priv/alloc_calls', 0o664, b' 1 uhci_urb_enqueue+0xb6/0xa30 [uhci_hcd] age=53794 pid=419 cpus=0\n')
+f('sys/kernel/slab/uhci_urb_priv/objs_per_slab', 0o664, b'32\n')
+f('sys/kernel/slab/uhci_urb_priv/shrink', 0o664, b'')
+f('sys/kernel/slab/uhci_urb_priv/trace', 0o664, b'0\n')
+f('sys/kernel/slab/uhci_urb_priv/object_size', 0o664, b'56\n')
+f('sys/kernel/slab/uhci_urb_priv/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/uhci_urb_priv/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/uhci_urb_priv/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/uhci_urb_priv/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/uhci_urb_priv/objects', 0o664, b'32\n')
+f('sys/kernel/slab/uhci_urb_priv/order', 0o664, b'0\n')
+f('sys/kernel/slab/uhci_urb_priv/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/uhci_urb_priv/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/uhci_urb_priv/align', 0o664, b'0\n')
+f('sys/kernel/slab/uhci_urb_priv/partial', 0o664, b'0\n')
+f('sys/kernel/slab/uhci_urb_priv/validate', 0o664, b'')
+f('sys/kernel/slab/uhci_urb_priv/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/uhci_urb_priv/free_calls', 0o664, b' 1 uhci_free_urb_priv+0x79/0xd0 [uhci_hcd] age=53806 pid=0 cpus=0\n')
+f('sys/kernel/slab/uhci_urb_priv/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/shmem_inode_cache', 0o775)
+f('sys/kernel/slab/shmem_inode_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/shmem_inode_cache/ctor', 0o664, b'init_once+0x0/0x40\n')
+f('sys/kernel/slab/shmem_inode_cache/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/shmem_inode_cache/slab_size', 0o664, b'1400\n')
+f('sys/kernel/slab/shmem_inode_cache/total_objects', 0o664, b'1173\n')
+f('sys/kernel/slab/shmem_inode_cache/slabs', 0o664, b'51\n')
+f('sys/kernel/slab/shmem_inode_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/shmem_inode_cache/alloc_calls', 0o664, b' 1144 shmem_alloc_inode+0x15/0x30 age=21584/7506265/8379043 pid=1-13453 cpus=0-1\n')
+f('sys/kernel/slab/shmem_inode_cache/objs_per_slab', 0o664, b'23\n')
+f('sys/kernel/slab/shmem_inode_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/shmem_inode_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/shmem_inode_cache/object_size', 0o664, b'1328\n')
+f('sys/kernel/slab/shmem_inode_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/shmem_inode_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/shmem_inode_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/shmem_inode_cache/objects_partial', 0o664, b'42\n')
+f('sys/kernel/slab/shmem_inode_cache/objects', 0o664, b'1169\n')
+f('sys/kernel/slab/shmem_inode_cache/order', 0o664, b'3\n')
+f('sys/kernel/slab/shmem_inode_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/shmem_inode_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/shmem_inode_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/shmem_inode_cache/partial', 0o664, b'2\n')
+f('sys/kernel/slab/shmem_inode_cache/validate', 0o664, b'')
+f('sys/kernel/slab/shmem_inode_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/shmem_inode_cache/free_calls', 0o664, b''' 741 <not-available> age=4303046628 pid=0 cpus=0
+ 403 shmem_destroy_inode+0x24/0x30 age=21598/7406739/8375758 pid=72-13332 cpus=0-1
+''')
+f('sys/kernel/slab/shmem_inode_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/fat_inode_cache', 0o775)
+f('sys/kernel/slab/fat_inode_cache/reclaim_account', 0o664, b'1\n')
+f('sys/kernel/slab/fat_inode_cache/ctor', 0o664, b'init_once+0x0/0x60\n')
+f('sys/kernel/slab/fat_inode_cache/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/fat_inode_cache/slab_size', 0o664, b'1272\n')
+f('sys/kernel/slab/fat_inode_cache/total_objects', 0o664, b'100\n')
+f('sys/kernel/slab/fat_inode_cache/slabs', 0o664, b'4\n')
+f('sys/kernel/slab/fat_inode_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/fat_inode_cache/alloc_calls', 0o664, b' 76 fat_alloc_inode+0x15/0x30 age=61228/61276/61657 pid=13348-13354 cpus=0-1\n')
+f('sys/kernel/slab/fat_inode_cache/objs_per_slab', 0o664, b'25\n')
+f('sys/kernel/slab/fat_inode_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/fat_inode_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/fat_inode_cache/object_size', 0o664, b'1200\n')
+f('sys/kernel/slab/fat_inode_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/fat_inode_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/fat_inode_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/fat_inode_cache/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/fat_inode_cache/objects', 0o664, b'100\n')
+f('sys/kernel/slab/fat_inode_cache/order', 0o664, b'3\n')
+f('sys/kernel/slab/fat_inode_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/fat_inode_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/fat_inode_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/fat_inode_cache/partial', 0o664, b'0\n')
+f('sys/kernel/slab/fat_inode_cache/validate', 0o664, b'')
+f('sys/kernel/slab/fat_inode_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/fat_inode_cache/free_calls', 0o664, b' 76 <not-available> age=4303047594 pid=0 cpus=0\n')
+f('sys/kernel/slab/fat_inode_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/kmalloc-256', 0o775)
+f('sys/kernel/slab/kmalloc-256/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-256/ctor', 0o664, b'')
+f('sys/kernel/slab/kmalloc-256/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-256/slab_size', 0o664, b'328\n')
+f('sys/kernel/slab/kmalloc-256/total_objects', 0o664, b'516\n')
+f('sys/kernel/slab/kmalloc-256/slabs', 0o664, b'43\n')
+f('sys/kernel/slab/kmalloc-256/poison', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-256/alloc_calls', 0o664, b''' 2 mempool_kmalloc+0x11/0x20 age=8379928/8379928/8379928 pid=1 cpus=0
+ 2 __vmalloc_area_node+0xfb/0x140 age=8374585/8375388/8376192 pid=122-126 cpus=0-1
+ 32 dma_pool_create+0x90/0x1e0 age=8374074/8374505/8374905 pid=143-147 cpus=0-1
+ 28 __percpu_alloc_mask+0xbc/0x140 age=8360136/8365750/8379780 pid=1-1549 cpus=0
+ 2 seq_open+0x84/0xa0 age=8355780/8360929/8366079 pid=1371-1738 cpus=0
+ 19 inotify_init+0x1b/0x90 age=8333719/8353284/8379778 pid=1-2544 cpus=0-1
+ 1 mounts_open_common+0x11e/0x210 age=8365844 pid=1371 cpus=0
+ 347 __proc_create+0xa5/0x150 age=8355314/8375854/8380066 pid=0-1813 cpus=0-1
+ 6 start_this_handle+0x3f5/0x410 age=4241/38502/142468 pid=21-13466 cpus=0-1
+ 3 elevator_alloc+0x1b/0xc0 age=62010/5606790/8379345 pid=1-13295 cpus=0-1
+ 2 acpi_ds_build_internal_buffer_obj+0xe1/0x121 age=8379913/8379914/8379915 pid=1 cpus=0
+ 1 find_dock+0x414/0x426 age=8379931 pid=1 cpus=0
+ 6 con_insert_unipair+0x96/0x110 age=8355034/8367399/8379765 pid=1-1898 cpus=1
+ 2 neigh_resolve_output+0x226/0x2e0 age=1134112/4736669/8339226 pid=0-2401 cpus=0-1
+ 1 genl_register_family+0x1b6/0x1e0 age=8375014 pid=126 cpus=0
+ 5 ip_mc_inc_group+0x6b/0x280 age=8325482/8352347/8367852 pid=1185-1849 cpus=0-1
+ 2 cache_add_dev+0x17b/0x546 age=8379779/8379779/8379780 pid=1 cpus=0-1
+ 10 audit_register_class+0x1e/0xa1 age=8379779/8379779/8379779 pid=1 cpus=1
+ 1 proc_net_ns_init+0x1b/0x81 age=8380066 pid=0 cpus=0
+ 3 snd_malloc_sgbuf_pages+0xfa/0x1f0 [snd_page_alloc] age=8374129/8374129/8374129 pid=107 cpus=1
+ 1 usb_get_configuration+0x18f/0x1480 [usbcore] age=8372709 pid=419 cpus=0
+ 1 acpi_ac_add+0x3a/0x1b1 [ac] age=8375784 pid=392 cpus=0
+ 1 acpi_processor_register_performance+0x2a0/0x3a6 [processor] age=8366391 pid=1358 cpus=0
+ 3 snd_ctl_open+0x8e/0x180 [snd] age=8333026/8337179/8339273 pid=2400-2425 cpus=0
+ 8 ieee80211_rx_bss_add+0x4e/0x140 [mac80211] age=8354793/8355457/8355979 pid=0-1951 cpus=0
+ 2 ipv6_add_addr+0x199/0x3c0 [ipv6] age=8329536/8344837/8360138 pid=8-1549 cpus=0-1
+ 5 ipv6_dev_mc_inc+0x141/0x3f0 [ipv6] age=8329536/8354016/8360138 pid=8-1549 cpus=0-1
+''')
+f('sys/kernel/slab/kmalloc-256/objs_per_slab', 0o664, b'12\n')
+f('sys/kernel/slab/kmalloc-256/shrink', 0o664, b'')
+f('sys/kernel/slab/kmalloc-256/trace', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-256/object_size', 0o664, b'256\n')
+f('sys/kernel/slab/kmalloc-256/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-256/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-256/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-256/objects_partial', 0o664, b'60\n')
+f('sys/kernel/slab/kmalloc-256/objects', 0o664, b'504\n')
+f('sys/kernel/slab/kmalloc-256/order', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-256/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-256/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-256/align', 0o664, b'8\n')
+f('sys/kernel/slab/kmalloc-256/partial', 0o664, b'6\n')
+f('sys/kernel/slab/kmalloc-256/validate', 0o664, b'')
+f('sys/kernel/slab/kmalloc-256/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-256/free_calls', 0o664, b''' 389 <not-available> age=4303047363 pid=0 cpus=0
+ 1 __vunmap+0xe9/0x120 age=8374878 pid=107 cpus=1
+ 38 do_execve+0x2b1/0x2d0 age=7303/7294190/8377088 pid=71-13465 cpus=0-1
+ 51 seq_release+0x20/0x30 age=23541/7877166/8376202 pid=105-2535 cpus=0-1
+ 3 free_proc_entry+0x73/0x90 age=8356279/8369643/8378992 pid=1-1541 cpus=0
+ 3 __journal_drop_transaction+0xe6/0x170 age=8360317/8363466/8366128 pid=32 cpus=0
+ 1 acpi_pci_irq_add_prt+0xc2/0x324 age=8379845 pid=1 cpus=0
+ 2 acpi_pci_bind+0x26b/0x28d age=8379844/8379845/8379846 pid=1 cpus=0
+ 1 wireless_send_event+0x172/0x330 age=8329538 pid=742 cpus=1
+ 3 usb_string+0x17c/0x1e0 [usbcore] age=8374367/8374614/8374886 pid=143 cpus=0
+ 3 snd_ctl_release+0xf9/0x130 [snd] age=8333027/8337180/8339274 pid=2400-2425 cpus=0
+ 1 ieee80211_set_associated+0x421/0x520 [mac80211] age=8329538 pid=742 cpus=1
+''')
+f('sys/kernel/slab/kmalloc-256/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/biovec-64', 0o775)
+f('sys/kernel/slab/biovec-64/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-64/ctor', 0o664, b'')
+f('sys/kernel/slab/biovec-64/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-64/slab_size', 0o664, b'1152\n')
+f('sys/kernel/slab/biovec-64/total_objects', 0o664, b'28\n')
+f('sys/kernel/slab/biovec-64/slabs', 0o664, b'2\n')
+f('sys/kernel/slab/biovec-64/poison', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-64/alloc_calls', 0o664, b' 2 mempool_alloc_slab+0x11/0x20 age=8379482/8379482/8379482 pid=1 cpus=0\n')
+f('sys/kernel/slab/biovec-64/objs_per_slab', 0o664, b'14\n')
+f('sys/kernel/slab/biovec-64/shrink', 0o664, b'')
+f('sys/kernel/slab/biovec-64/trace', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-64/object_size', 0o664, b'1024\n')
+f('sys/kernel/slab/biovec-64/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-64/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-64/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-64/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-64/objects', 0o664, b'28\n')
+f('sys/kernel/slab/biovec-64/order', 0o664, b'2\n')
+f('sys/kernel/slab/biovec-64/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-64/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-64/align', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-64/partial', 0o664, b'0\n')
+f('sys/kernel/slab/biovec-64/validate', 0o664, b'')
+f('sys/kernel/slab/biovec-64/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/biovec-64/free_calls', 0o664, b' 2 <not-available> age=4303046917 pid=0 cpus=0\n')
+f('sys/kernel/slab/biovec-64/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/sysfs_dir_cache', 0o775)
+f('sys/kernel/slab/sysfs_dir_cache/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/sysfs_dir_cache/ctor', 0o664, b'')
+f('sys/kernel/slab/sysfs_dir_cache/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/sysfs_dir_cache/slab_size', 0o664, b'152\n')
+f('sys/kernel/slab/sysfs_dir_cache/total_objects', 0o664, b'11518\n')
+f('sys/kernel/slab/sysfs_dir_cache/slabs', 0o664, b'443\n')
+f('sys/kernel/slab/sysfs_dir_cache/poison', 0o664, b'1\n')
+f('sys/kernel/slab/sysfs_dir_cache/alloc_calls', 0o664, b' 11488 sysfs_new_dirent+0x38/0x120 age=22320/7764235/8379787 pid=0-13295 cpus=0-1\n')
+f('sys/kernel/slab/sysfs_dir_cache/objs_per_slab', 0o664, b'26\n')
+f('sys/kernel/slab/sysfs_dir_cache/shrink', 0o664, b'')
+f('sys/kernel/slab/sysfs_dir_cache/trace', 0o664, b'0\n')
+f('sys/kernel/slab/sysfs_dir_cache/object_size', 0o664, b'80\n')
+f('sys/kernel/slab/sysfs_dir_cache/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/sysfs_dir_cache/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/sysfs_dir_cache/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/sysfs_dir_cache/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/sysfs_dir_cache/objects', 0o664, b'11518\n')
+f('sys/kernel/slab/sysfs_dir_cache/order', 0o664, b'0\n')
+f('sys/kernel/slab/sysfs_dir_cache/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/sysfs_dir_cache/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/sysfs_dir_cache/align', 0o664, b'0\n')
+f('sys/kernel/slab/sysfs_dir_cache/partial', 0o664, b'0\n')
+f('sys/kernel/slab/sysfs_dir_cache/validate', 0o664, b'')
+f('sys/kernel/slab/sysfs_dir_cache/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/sysfs_dir_cache/free_calls', 0o664, b''' 11006 <not-available> age=4303047087 pid=0 cpus=0
+ 482 release_sysfs_dirent+0x5c/0xd0 age=61294/6319346/8379456 pid=1-2141 cpus=0-1
+''')
+f('sys/kernel/slab/sysfs_dir_cache/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/request_sock_TCP', 0o775)
+f('sys/kernel/slab/request_sock_TCP/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCP/ctor', 0o664, b'')
+f('sys/kernel/slab/request_sock_TCP/hwcache_align', 0o664, b'1\n')
+f('sys/kernel/slab/request_sock_TCP/slab_size', 0o664, b'192\n')
+f('sys/kernel/slab/request_sock_TCP/total_objects', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCP/slabs', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCP/poison', 0o664, b'1\n')
+f('sys/kernel/slab/request_sock_TCP/alloc_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/request_sock_TCP/objs_per_slab', 0o664, b'21\n')
+f('sys/kernel/slab/request_sock_TCP/shrink', 0o664, b'')
+f('sys/kernel/slab/request_sock_TCP/trace', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCP/object_size', 0o664, b'88\n')
+f('sys/kernel/slab/request_sock_TCP/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCP/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCP/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCP/objects_partial', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCP/objects', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCP/order', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCP/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/request_sock_TCP/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/request_sock_TCP/align', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCP/partial', 0o664, b'0\n')
+f('sys/kernel/slab/request_sock_TCP/validate', 0o664, b'')
+f('sys/kernel/slab/request_sock_TCP/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/request_sock_TCP/free_calls', 0o664, b'No data\n')
+f('sys/kernel/slab/request_sock_TCP/aliases', 0o664, b'0\n')
+d('sys/kernel/slab/kmalloc-4096', 0o775)
+f('sys/kernel/slab/kmalloc-4096/reclaim_account', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-4096/ctor', 0o664, b'')
+f('sys/kernel/slab/kmalloc-4096/hwcache_align', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-4096/slab_size', 0o664, b'4168\n')
+f('sys/kernel/slab/kmalloc-4096/total_objects', 0o664, b'385\n')
+f('sys/kernel/slab/kmalloc-4096/slabs', 0o664, b'55\n')
+f('sys/kernel/slab/kmalloc-4096/poison', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-4096/alloc_calls', 0o664, b''' 1 load_module+0x18d5/0x1b30 age=8375716 pid=330 cpus=0
+ 1 __vmalloc_area_node+0xfb/0x140 age=8371983 pid=867 cpus=0
+ 24 __percpu_alloc_mask+0xbc/0x140 age=8360098/8363374/8379742 pid=1-1549 cpus=0
+ 1 seq_read+0x2f0/0x360 age=8365263 pid=1371 cpus=0
+ 2 ext3_fill_super+0x68/0x1a20 age=8369599/8373987/8378375 pid=1-962 cpus=0
+ 4 journal_init_revoke_table+0x4d/0xb0 age=8369583/8373933/8378283 pid=1-962 cpus=0
+ 2 journal_init_inode+0x8d/0x130 age=8369583/8373933/8378283 pid=1-962 cpus=0
+ 1 fat_fill_super+0x40/0xdd0 age=61388 pid=13348 cpus=1
+ 7 scsi_host_alloc+0x35/0x360 age=66976/7192011/8379690 pid=1-419 cpus=0-1
+ 3 scsi_alloc_sdev+0x6a/0x270 age=61972/5606752/8379307 pid=1-13295 cpus=0-1
+ 8 input_allocate_device+0x1a/0xb0 age=53455/7335718/8378931 pid=17-419 cpus=0-1
+ 1 reqsk_queue_alloc+0x112/0x120 age=8354535 pid=1920 cpus=0
+ 3 alloc_netdev_mq+0x4f/0x180 age=8373564/8375671/8379766 pid=1-126 cpus=0-1
+ 1 pidmap_init+0x15/0x4e age=8380028 pid=0 cpus=0
+ 1 netlink_proto_init+0x47/0x16b age=8379894 pid=1 cpus=0
+ 2 acpi_processor_add+0x25/0x6d [processor] age=8375653/8375684/8375715 pid=330 cpus=0
+ 1 yenta_probe+0x38/0x6cd [yenta_socket] age=8373766 pid=352 cpus=0
+ 281 iwl3945_rx_allocate+0xd5/0x160 [iwl3945] age=2011/7577/13684 pid=733 cpus=0
+ 1 skcipher_geniv_alloc+0x304/0x3f0 [crypto_blkcipher] age=8374372 pid=215 cpus=1
+ 2 bitmap_get_counter+0x153/0x220 [md_mod] age=8370027/8370029/8370031 pid=916 cpus=0
+ 1 bitmap_create+0x2bc/0xad0 [md_mod] age=8370031 pid=916 cpus=0
+ 6 __addrconf_sysctl_register+0x7b/0x140 [ipv6] age=8360098/8360099/8360101 pid=1549 cpus=0
+ 1 acm_probe+0x34c/0xa50 [cdc_acm] age=22641 pid=419 cpus=0
+''')
+f('sys/kernel/slab/kmalloc-4096/objs_per_slab', 0o664, b'7\n')
+f('sys/kernel/slab/kmalloc-4096/shrink', 0o664, b'')
+f('sys/kernel/slab/kmalloc-4096/trace', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-4096/object_size', 0o664, b'4096\n')
+f('sys/kernel/slab/kmalloc-4096/cpu_slabs', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-4096/cache_dma', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-4096/destroy_by_rcu', 0o664, b'0\n')
+f('sys/kernel/slab/kmalloc-4096/objects_partial', 0o664, b'17\n')
+f('sys/kernel/slab/kmalloc-4096/objects', 0o664, b'367\n')
+f('sys/kernel/slab/kmalloc-4096/order', 0o664, b'3\n')
+f('sys/kernel/slab/kmalloc-4096/sanity_checks', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-4096/store_user', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-4096/align', 0o664, b'8\n')
+f('sys/kernel/slab/kmalloc-4096/partial', 0o664, b'5\n')
+f('sys/kernel/slab/kmalloc-4096/validate', 0o664, b'')
+f('sys/kernel/slab/kmalloc-4096/red_zone', 0o664, b'1\n')
+f('sys/kernel/slab/kmalloc-4096/free_calls', 0o664, b''' 187 <not-available> age=4303047324 pid=0 cpus=0
+ 5 seq_release+0x18/0x30 age=61430/6709712/8374782 pid=107-1371 cpus=0-1
+ 1 cryptomgr_probe+0x81/0xf0 age=8373564 pid=745 cpus=0
+ 30 kobject_uevent_env+0x122/0x470 age=22643/7542644/8379894 pid=1-1549 cpus=0-1
+ 1 show_uevent+0xee/0x110 age=2013 pid=13466 cpus=0
+ 1 input_dev_release+0x23/0x40 age=8378913 pid=17 cpus=0
+ 130 skb_release_data+0x85/0xd0 age=2011/73374/8354535 pid=0-13466 cpus=0-1
+''')
+f('sys/kernel/slab/kmalloc-4096/aliases', 0o664, b'0\n')
+d('sys/kernel/debug', 0o775)
+d('sys/kernel/debug/x86', 0o775)
+f('sys/kernel/debug/x86/pat_memtype_list', 0o664, b'')
+d('sys/kernel/debug/bdi', 0o775)
+d('sys/kernel/debug/bdi/7:1', 0o775)
+f('sys/kernel/debug/bdi/7:1/stats', 0o664, b'''BdiWriteback: 0 kB
+BdiReclaimable: 0 kB
+BdiDirtyThresh: 0 kB
+DirtyThresh: 189288 kB
+BackgroundThresh: 94644 kB
+''')
+d('sys/kernel/debug/bdi/7:0', 0o775)
+f('sys/kernel/debug/bdi/7:0/stats', 0o664, b'''BdiWriteback: 0 kB
+BdiReclaimable: 0 kB
+BdiDirtyThresh: 0 kB
+DirtyThresh: 189292 kB
+BackgroundThresh: 94644 kB
+''')
+d('sys/kernel/debug/bdi/7:2', 0o775)
+f('sys/kernel/debug/bdi/7:2/stats', 0o664, b'''BdiWriteback: 0 kB
+BdiReclaimable: 0 kB
+BdiDirtyThresh: 0 kB
+DirtyThresh: 189288 kB
+BackgroundThresh: 94644 kB
+''')
+d('sys/kernel/debug/bdi/7:4', 0o775)
+f('sys/kernel/debug/bdi/7:4/stats', 0o664, b'''BdiWriteback: 0 kB
+BdiReclaimable: 0 kB
+BdiDirtyThresh: 0 kB
+DirtyThresh: 189288 kB
+BackgroundThresh: 94644 kB
+''')
+d('sys/kernel/debug/bdi/7:3', 0o775)
+f('sys/kernel/debug/bdi/7:3/stats', 0o664, b'''BdiWriteback: 0 kB
+BdiReclaimable: 0 kB
+BdiDirtyThresh: 0 kB
+DirtyThresh: 189288 kB
+BackgroundThresh: 94644 kB
+''')
+d('sys/kernel/debug/bdi/11:0', 0o775)
+f('sys/kernel/debug/bdi/11:0/stats', 0o664, b'''BdiWriteback: 0 kB
+BdiReclaimable: 0 kB
+BdiDirtyThresh: 0 kB
+DirtyThresh: 189292 kB
+BackgroundThresh: 94644 kB
+''')
+d('sys/kernel/debug/bdi/7:5', 0o775)
+f('sys/kernel/debug/bdi/7:5/stats', 0o664, b'''BdiWriteback: 0 kB
+BdiReclaimable: 0 kB
+BdiDirtyThresh: 0 kB
+DirtyThresh: 189288 kB
+BackgroundThresh: 94644 kB
+''')
+d('sys/kernel/debug/bdi/8:0', 0o775)
+f('sys/kernel/debug/bdi/8:0/stats', 0o664, b'''BdiWriteback: 0 kB
+BdiReclaimable: 13696 kB
+BdiDirtyThresh: 83368 kB
+DirtyThresh: 189292 kB
+BackgroundThresh: 94644 kB
+''')
+d('sys/kernel/debug/bdi/default', 0o775)
+f('sys/kernel/debug/bdi/default/stats', 0o664, b'''BdiWriteback: 0 kB
+BdiReclaimable: 0 kB
+BdiDirtyThresh: 0 kB
+DirtyThresh: 189292 kB
+BackgroundThresh: 94644 kB
+''')
+d('sys/kernel/debug/bdi/0:16', 0o775)
+f('sys/kernel/debug/bdi/0:16/stats', 0o664, b'''BdiWriteback: 0 kB
+BdiReclaimable: 0 kB
+BdiDirtyThresh: 0 kB
+DirtyThresh: 189272 kB
+BackgroundThresh: 94636 kB
+''')
+d('sys/kernel/debug/bdi/8:16', 0o775)
+f('sys/kernel/debug/bdi/8:16/stats', 0o664, b'''BdiWriteback: 0 kB
+BdiReclaimable: 0 kB
+BdiDirtyThresh: 0 kB
+DirtyThresh: 189272 kB
+BackgroundThresh: 94636 kB
+''')
+d('sys/kernel/debug/bdi/9:0', 0o775)
+f('sys/kernel/debug/bdi/9:0/stats', 0o664, b'''BdiWriteback: 0 kB
+BdiReclaimable: 0 kB
+BdiDirtyThresh: 0 kB
+DirtyThresh: 189292 kB
+BackgroundThresh: 94644 kB
+''')
+d('sys/kernel/debug/bdi/7:7', 0o775)
+f('sys/kernel/debug/bdi/7:7/stats', 0o664, b'''BdiWriteback: 0 kB
+BdiReclaimable: 0 kB
+BdiDirtyThresh: 0 kB
+DirtyThresh: 189288 kB
+BackgroundThresh: 94644 kB
+''')
+d('sys/kernel/debug/bdi/7:6', 0o775)
+f('sys/kernel/debug/bdi/7:6/stats', 0o664, b'''BdiWriteback: 0 kB
+BdiReclaimable: 0 kB
+BdiDirtyThresh: 0 kB
+DirtyThresh: 189288 kB
+BackgroundThresh: 94644 kB
+''')
+d('sys/kernel/uids', 0o775)
+d('sys/kernel/uids/100', 0o775)
+f('sys/kernel/uids/100/cpu_share', 0o664, b'1024\n')
+d('sys/kernel/uids/103', 0o775)
+f('sys/kernel/uids/103/cpu_share', 0o664, b'1024\n')
+d('sys/kernel/uids/51', 0o775)
+f('sys/kernel/uids/51/cpu_share', 0o664, b'1024\n')
+d('sys/kernel/uids/105', 0o775)
+f('sys/kernel/uids/105/cpu_share', 0o664, b'1024\n')
+d('sys/kernel/uids/2702', 0o775)
+f('sys/kernel/uids/2702/cpu_share', 0o664, b'1024\n')
+d('sys/kernel/uids/0', 0o775)
+f('sys/kernel/uids/0/cpu_share', 0o664, b'2048\n')
+d('sys/power', 0o775)
+f('sys/power/state', 0o664, b'mem\n')
+d('sys/firmware', 0o775)
+d('sys/firmware/memmap', 0o775)
+d('sys/firmware/memmap/8', 0o775)
+f('sys/firmware/memmap/8/start', 0o664, b'0xfec00000\n')
+f('sys/firmware/memmap/8/type', 0o664, b'reserved\n')
+f('sys/firmware/memmap/8/end', 0o664, b'0xfec0ffff\n')
+d('sys/firmware/memmap/11', 0o775)
+f('sys/firmware/memmap/11/start', 0o664, b'0xfed1c000\n')
+f('sys/firmware/memmap/11/type', 0o664, b'reserved\n')
+f('sys/firmware/memmap/11/end', 0o664, b'0xfed8ffff\n')
+d('sys/firmware/memmap/6', 0o775)
+f('sys/firmware/memmap/6/start', 0o664, b'0x7ff00000\n')
+f('sys/firmware/memmap/6/type', 0o664, b'reserved\n')
+f('sys/firmware/memmap/6/end', 0o664, b'0x7fffffff\n')
+d('sys/firmware/memmap/5', 0o775)
+f('sys/firmware/memmap/5/start', 0o664, b'0x7fedf000\n')
+f('sys/firmware/memmap/5/type', 0o664, b'ACPI Non-volatile Storage\n')
+f('sys/firmware/memmap/5/end', 0o664, b'0x7fefffff\n')
+d('sys/firmware/memmap/9', 0o775)
+f('sys/firmware/memmap/9/start', 0o664, b'0xfed00000\n')
+f('sys/firmware/memmap/9/type', 0o664, b'reserved\n')
+f('sys/firmware/memmap/9/end', 0o664, b'0xfed003ff\n')
+d('sys/firmware/memmap/2', 0o775)
+f('sys/firmware/memmap/2/start', 0o664, b'0xdc000\n')
+f('sys/firmware/memmap/2/type', 0o664, b'reserved\n')
+f('sys/firmware/memmap/2/end', 0o664, b'0xfffff\n')
+d('sys/firmware/memmap/12', 0o775)
+f('sys/firmware/memmap/12/start', 0o664, b'0xfee00000\n')
+f('sys/firmware/memmap/12/type', 0o664, b'reserved\n')
+f('sys/firmware/memmap/12/end', 0o664, b'0xfee00fff\n')
+d('sys/firmware/memmap/4', 0o775)
+f('sys/firmware/memmap/4/start', 0o664, b'0x7fed0000\n')
+f('sys/firmware/memmap/4/type', 0o664, b'ACPI Tables\n')
+f('sys/firmware/memmap/4/end', 0o664, b'0x7fedefff\n')
+d('sys/firmware/memmap/3', 0o775)
+f('sys/firmware/memmap/3/start', 0o664, b'0x100000\n')
+f('sys/firmware/memmap/3/type', 0o664, b'System RAM\n')
+f('sys/firmware/memmap/3/end', 0o664, b'0x7fecffff\n')
+d('sys/firmware/memmap/10', 0o775)
+f('sys/firmware/memmap/10/start', 0o664, b'0xfed14000\n')
+f('sys/firmware/memmap/10/type', 0o664, b'reserved\n')
+f('sys/firmware/memmap/10/end', 0o664, b'0xfed19fff\n')
+d('sys/firmware/memmap/0', 0o775)
+f('sys/firmware/memmap/0/start', 0o664, b'0x0\n')
+f('sys/firmware/memmap/0/type', 0o664, b'System RAM\n')
+f('sys/firmware/memmap/0/end', 0o664, b'0x9efff\n')
+d('sys/firmware/memmap/7', 0o775)
+f('sys/firmware/memmap/7/start', 0o664, b'0xf0000000\n')
+f('sys/firmware/memmap/7/type', 0o664, b'reserved\n')
+f('sys/firmware/memmap/7/end', 0o664, b'0xf3ffffff\n')
+d('sys/firmware/memmap/1', 0o775)
+f('sys/firmware/memmap/1/start', 0o664, b'0x9f000\n')
+f('sys/firmware/memmap/1/type', 0o664, b'reserved\n')
+f('sys/firmware/memmap/1/end', 0o664, b'0x9ffff\n')
+d('sys/firmware/memmap/13', 0o775)
+f('sys/firmware/memmap/13/start', 0o664, b'0xff800000\n')
+f('sys/firmware/memmap/13/type', 0o664, b'reserved\n')
+f('sys/firmware/memmap/13/end', 0o664, b'0xffffffff\n')
+d('sys/firmware/edd', 0o775)
+d('sys/firmware/edd/int13_dev80', 0o775)
+l('sys/firmware/edd/int13_dev80/pci_dev', '../../../devices/pci0000:00/0000:00:1f.2')
+f('sys/firmware/edd/int13_dev80/version', 0o664, b'0x30\n')
+f('sys/firmware/edd/int13_dev80/raw_data', 0o664, b'J\x00\x01\x00\xff?\x00\x00\x10\x00\x00\x00?\x00\x00\x000"\xa5\x0b\x00\x00\x00\x00\x00\x02\xc6\x00@\x00\xdd\xbe,\x00\x00\x00PCI ATA \x00\x1f\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa5')
+f('sys/firmware/edd/int13_dev80/sectors', 0o664, b'195371568\n')
+f('sys/firmware/edd/int13_dev80/default_sectors_per_track', 0o664, b'63\n')
+f('sys/firmware/edd/int13_dev80/legacy_max_cylinder', 0o664, b'1022\n')
+f('sys/firmware/edd/int13_dev80/interface', 0o664, b'ATA \tdevice: 0\n')
+f('sys/firmware/edd/int13_dev80/host_bus', 0o664, b'PCI \t00:1f.2 channel: 1\n')
+f('sys/firmware/edd/int13_dev80/legacy_max_head', 0o664, b'239\n')
+f('sys/firmware/edd/int13_dev80/mbr_signature', 0o664, b'0x00087b5f\n')
+f('sys/firmware/edd/int13_dev80/info_flags', 0o664, b'DMA boundary error transparent\n')
+f('sys/firmware/edd/int13_dev80/default_heads', 0o664, b'16\n')
+f('sys/firmware/edd/int13_dev80/default_cylinders', 0o664, b'16383\n')
+f('sys/firmware/edd/int13_dev80/legacy_sectors_per_track', 0o664, b'63\n')
+f('sys/firmware/edd/int13_dev80/extensions', 0o664, b'''Fixed disk access
+Enhanced Disk Drive support
+''')
+d('sys/firmware/acpi', 0o775)
+d('sys/firmware/acpi/tables', 0o775)
+f('sys/firmware/acpi/tables/DSDT', 0o664, b'''DSDT4\xd2\x00\x00\x01\x9aLENOVOTP-7I \x11\x00\x00MSFT\x0e\x00\x00\x01\x10 \\_PR_[\x83\x0bCPU0\x00\x10\x10\x00\x00\x06[\x83\x0bCPU1\x01\x10\x10\x00\x00\x06\x10\x83I\x0b\\_SB_\x14C2_INI\x00\xa0(\x93\\SCMP\\_OS_\rMicrosoft Windows\x00\x00p
+\x01\\W98F\xa1C\x11\xa0F\t[\x12\\_OSI`\xa0,\\_OSI\rWindows 2001\x00p
+\x01\\WNTFp
+\x01\\WXPFp
+\x00\\WSPV\xa0 \\_OSI\rWindows 2001 SP1\x00p
+\x01\\WSPV\xa0 \\_OSI\rWindows 2001 SP2\x00p
+\x02\\WSPV\xa0\x1c\\_OSI\rWindows 2006\x00p
+\x01\\WVIS\xa1I\x07\xa0+\x93\\SCMP\\_OS_\rMicrosoft Windows NT\x00\x00p
+\x01\\WNTF\xa1J\x04\xa0G\x04\x93\\SCMP\\_OS_\rMicrosoft WindowsME: Millennium Edition\x00\x00p
+\x01\\WMEFp
+\x01\\W98F\xa0\x12\x92\x95\\_REV
+\x02p
+\x01\\H8DRp
+\x01\\OSIF\\/\x05_SB_PCI0LPC_MOU_MHIDp\\SRAH\\/\x03_SB_PCI0RID_\xa0\x1eVIGDp\\SRHE\\/\x04_SB_PCI0VID_RID_\xa1\x1ap\\SRHE\\/\x04_SB_PCI0AGP_RID_p\\SRE0\\/\x04_SB_PCI0EXP0RID_p\\SRE1\\/\x04_SB_PCI0EXP1RID_p\\SRE2\\/\x04_SB_PCI0EXP2RID_p\\SRE3\\/\x04_SB_PCI0EXP3RID_p\\SRU0\\/\x04_SB_PCI0USB0RID_p\\SRU1\\/\x04_SB_PCI0USB1RID_p\\SRU2\\/\x04_SB_PCI0USB2RID_p\\SRU3\\/\x04_SB_PCI0USB3RID_p\\SRU7\\/\x04_SB_PCI0USB7RID_p\\SRPB\\/\x04_SB_PCI0PCI1RID_p\\SRLP\\/\x04_SB_PCI0LPC_RID_p\\SRSA\\/\x04_SB_PCI0IDE0RID_p\\SRSA\\/\x04_SB_PCI0SATARID_p\\SRSM\\/\x04_SB_PCI0SMBURID_[\x82K\x11LNKA\x08_HID\x0cA\xd0\x0c\x0f\x08_UID
+\x01\x14(_STA\x00\xa0\x1c\x92VPIR\\/\x04_SB_PCI0LPC_PIRA\xa4
+\t\xa1\x04\xa4
+\x0b\x08_PRS\x11\t
+\x06#\xf8\x0e\x18y\x00\x14/_DIS\x00}\\/\x04_SB_PCI0LPC_PIRA
+\x80\\/\x04_SB_PCI0LPC_PIRA\x08BUFA\x11\t
+\x06#\x00\x00\x18y\x00\x8bBUFA
+\x01IRA1\x14:_CRS\x00{\\/\x04_SB_PCI0LPC_PIRA
+\x8f`\xa0\x0eVPIR`y
+\x01`IRA1\xa1\x08p
+\x00IRA1\xa4BUFA\x14F\x04_SRS\x01\x8bh
+\x01IRA2\x82IRA2`{\\/\x04_SB_PCI0LPC_PIRA
+pa}av`apa\\/\x04_SB_PCI0LPC_PIRA[\x82K\x11LNKB\x08_HID\x0cA\xd0\x0c\x0f\x08_UID
+\x02\x14(_STA\x00\xa0\x1c\x92VPIR\\/\x04_SB_PCI0LPC_PIRB\xa4
+\t\xa1\x04\xa4
+\x0b\x08_PRS\x11\t
+\x06#\xf8\x0e\x18y\x00\x14/_DIS\x00}\\/\x04_SB_PCI0LPC_PIRB
+\x80\\/\x04_SB_PCI0LPC_PIRB\x08BUFB\x11\t
+\x06#\x00\x00\x18y\x00\x8bBUFB
+\x01IRB1\x14:_CRS\x00{\\/\x04_SB_PCI0LPC_PIRB
+\x8f`\xa0\x0eVPIR`y
+\x01`IRB1\xa1\x08p
+\x00IRB1\xa4BUFB\x14F\x04_SRS\x01\x8bh
+\x01IRB2\x82IRB2`{\\/\x04_SB_PCI0LPC_PIRB
+pa}av`apa\\/\x04_SB_PCI0LPC_PIRB[\x82K\x11LNKC\x08_HID\x0cA\xd0\x0c\x0f\x08_UID
+\x03\x14(_STA\x00\xa0\x1c\x92VPIR\\/\x04_SB_PCI0LPC_PIRC\xa4
+\t\xa1\x04\xa4
+\x0b\x08_PRS\x11\t
+\x06#\xf8\x0e\x18y\x00\x14/_DIS\x00}\\/\x04_SB_PCI0LPC_PIRC
+\x80\\/\x04_SB_PCI0LPC_PIRC\x08BUFC\x11\t
+\x06#\x00\x00\x18y\x00\x8bBUFC
+\x01IRC1\x14:_CRS\x00{\\/\x04_SB_PCI0LPC_PIRC
+\x8f`\xa0\x0eVPIR`y
+\x01`IRC1\xa1\x08p
+\x00IRC1\xa4BUFC\x14F\x04_SRS\x01\x8bh
+\x01IRC2\x82IRC2`{\\/\x04_SB_PCI0LPC_PIRC
+pa}av`apa\\/\x04_SB_PCI0LPC_PIRC[\x82K\x11LNKD\x08_HID\x0cA\xd0\x0c\x0f\x08_UID
+\x04\x14(_STA\x00\xa0\x1c\x92VPIR\\/\x04_SB_PCI0LPC_PIRD\xa4
+\t\xa1\x04\xa4
+\x0b\x08_PRS\x11\t
+\x06#\xf8\x0e\x18y\x00\x14/_DIS\x00}\\/\x04_SB_PCI0LPC_PIRD
+\x80\\/\x04_SB_PCI0LPC_PIRD\x08BUFD\x11\t
+\x06#\x00\x00\x18y\x00\x8bBUFD
+\x01IRD1\x14:_CRS\x00{\\/\x04_SB_PCI0LPC_PIRD
+\x8f`\xa0\x0eVPIR`y
+\x01`IRD1\xa1\x08p
+\x00IRD1\xa4BUFD\x14F\x04_SRS\x01\x8bh
+\x01IRD2\x82IRD2`{\\/\x04_SB_PCI0LPC_PIRD
+pa}av`apa\\/\x04_SB_PCI0LPC_PIRD[\x82K\x11LNKE\x08_HID\x0cA\xd0\x0c\x0f\x08_UID
+\x05\x14(_STA\x00\xa0\x1c\x92VPIR\\/\x04_SB_PCI0LPC_PIRE\xa4
+\t\xa1\x04\xa4
+\x0b\x08_PRS\x11\t
+\x06#\xf8\x0e\x18y\x00\x14/_DIS\x00}\\/\x04_SB_PCI0LPC_PIRE
+\x80\\/\x04_SB_PCI0LPC_PIRE\x08BUFE\x11\t
+\x06#\x00\x00\x18y\x00\x8bBUFE
+\x01IRE1\x14:_CRS\x00{\\/\x04_SB_PCI0LPC_PIRE
+\x8f`\xa0\x0eVPIR`y
+\x01`IRE1\xa1\x08p
+\x00IRE1\xa4BUFE\x14F\x04_SRS\x01\x8bh
+\x01IRE2\x82IRE2`{\\/\x04_SB_PCI0LPC_PIRE
+pa}av`apa\\/\x04_SB_PCI0LPC_PIRE[\x82K\x11LNKF\x08_HID\x0cA\xd0\x0c\x0f\x08_UID
+\x06\x14(_STA\x00\xa0\x1c\x92VPIR\\/\x04_SB_PCI0LPC_PIRF\xa4
+\t\xa1\x04\xa4
+\x0b\x08_PRS\x11\t
+\x06#\xf8\x0e\x18y\x00\x14/_DIS\x00}\\/\x04_SB_PCI0LPC_PIRF
+\x80\\/\x04_SB_PCI0LPC_PIRF\x08BUFF\x11\t
+\x06#\x00\x00\x18y\x00\x8bBUFF
+\x01IRF1\x14:_CRS\x00{\\/\x04_SB_PCI0LPC_PIRF
+\x8f`\xa0\x0eVPIR`y
+\x01`IRF1\xa1\x08p
+\x00IRF1\xa4BUFF\x14F\x04_SRS\x01\x8bh
+\x01IRF2\x82IRF2`{\\/\x04_SB_PCI0LPC_PIRF
+pa}av`apa\\/\x04_SB_PCI0LPC_PIRF[\x82K\x11LNKG\x08_HID\x0cA\xd0\x0c\x0f\x08_UID
+\x07\x14(_STA\x00\xa0\x1c\x92VPIR\\/\x04_SB_PCI0LPC_PIRG\xa4
+\t\xa1\x04\xa4
+\x0b\x08_PRS\x11\t
+\x06#\xf8\x0e\x18y\x00\x14/_DIS\x00}\\/\x04_SB_PCI0LPC_PIRG
+\x80\\/\x04_SB_PCI0LPC_PIRG\x08BUFG\x11\t
+\x06#\x00\x00\x18y\x00\x8bBUFG
+\x01IRG1\x14:_CRS\x00{\\/\x04_SB_PCI0LPC_PIRG
+\x8f`\xa0\x0eVPIR`y
+\x01`IRG1\xa1\x08p
+\x00IRG1\xa4BUFG\x14F\x04_SRS\x01\x8bh
+\x01IRG2\x82IRG2`{\\/\x04_SB_PCI0LPC_PIRG
+pa}av`apa\\/\x04_SB_PCI0LPC_PIRG[\x82K\x11LNKH\x08_HID\x0cA\xd0\x0c\x0f\x08_UID
+\x08\x14(_STA\x00\xa0\x1c\x92VPIR\\/\x04_SB_PCI0LPC_PIRH\xa4
+\t\xa1\x04\xa4
+\x0b\x08_PRS\x11\t
+\x06#\xf8\x0e\x18y\x00\x14/_DIS\x00}\\/\x04_SB_PCI0LPC_PIRH
+\x80\\/\x04_SB_PCI0LPC_PIRH\x08BUFH\x11\t
+\x06#\x00\x00\x18y\x00\x8bBUFH
+\x01IRH1\x14:_CRS\x00{\\/\x04_SB_PCI0LPC_PIRH
+\x8f`\xa0\x0eVPIR`y
+\x01`IRH1\xa1\x08p
+\x00IRH1\xa4BUFH\x14F\x04_SRS\x01\x8bh
+\x01IRH2\x82IRH2`{\\/\x04_SB_PCI0LPC_PIRH
+pa}av`apa\\/\x04_SB_PCI0LPC_PIRH\x149VPIR\x01p
+\x01`\xa0
+{h
+\x80\x00p
+\x00`\xa1!{h
+\x0fa\xa0\t\x95a
+\x03p
+\x00`\xa1\x10\xa0\x0e\x91\x93a
+\x08\x93a
+\rp
+\x00`\xa4`[\x82HhMEM_\x08_HID\x0cA\xd0\x0c\x01\x08ME98\x11B\x04
+>\x86\t\x00\x01\x00\x00\x00\x00\x00\x00
+\x00\x86\t\x00\x00\x00\x00\x0e\x00\x00\x00\x02\x00\x86\t\x00\x01\x00\x00\x10\x00\x00\x00\xee\x01\x86\t\x00\x00\x00\x00\xc0\xfe\x00\x00\x14\x00\x86\t\x00\x00\x00\x10\xd4\xfe\x00\xf0+\x01y\x00\x8aME98
+\x1cMEB0\x8aME98
+ MEL0\x08MGAP\x11\x11
+\x0e\x86\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00y\x00\x8aMGAP
+\x04MGPB\x8aMGAP
+\x08MGPL\x08MEMS\x11B\r
+\xce\x86\t\x00\x01\x00\x00\x00\x00\x00\x00
+\x00\x86\t\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x86\t\x00\x00\x00@\x0c\x00\x00\x00\x00\x00\x86\t\x00\x00\x00\x80\x0c\x00\x00\x00\x00\x00\x86\t\x00\x00\x00\xc0\x0c\x00\x00\x00\x00\x00\x86\t\x00\x00\x00\x00\r\x00\x00\x00\x00\x00\x86\t\x00\x00\x00@\r\x00\x00\x00\x00\x00\x86\t\x00\x00\x00\x80\r\x00\x00\x00\x00\x00\x86\t\x00\x00\x00\xc0\r\x00\x00\x00\x00\x00\x86\t\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x86\t\x00\x00\x00@\x0e\x00\x00\x00\x00\x00\x86\t\x00\x00\x00\x80\x0e\x00\x00\x00\x00\x00\x86\t\x00\x00\x00\xc0\x0e\x00\x00\x00\x00\x00\x86\t\x00\x00\x00\x00\x0f\x00\x00\x00\x01\x00\x86\t\x00\x01\x00\x00\x10\x00\x00\x00\xee\x01\x86\t\x00\x00\x00\x00\xc0\xfe\x00\x00\x14\x00\x86\t\x00\x00\x00\x10\xd4\xfe\x00\xf0+\x01y\x00\x8aMEMS
+\x14MC0L\x8aMEMS
+ MC4L\x8aMEMS
+,MC8L\x8aMEMS
+8MCCL\x8aMEMS
+DMD0L\x8aMEMS
+PMD4L\x8aMEMS
+\\MD8L\x8aMEMS
+hMDCL\x8aMEMS
+tME0L\x8aMEMS
+\x80ME4L\x8aMEMS
+\x8cME8L\x8aMEMS
+\x98MECL\x8dMEMS
+xMC0W\x8dMEMS
+\xd8MC4W\x8dMEMS\x0b8\x01MC8W\x8dMEMS\x0b\x98\x01MCCW\x8dMEMS\x0b\xf8\x01MD0W\x8dMEMS\x0bX\x02MD4W\x8dMEMS\x0b\xb8\x02MD8W\x8dMEMS\x0b\x18\x03MDCW\x8dMEMS\x0bx\x03ME0W\x8dMEMS\x0b\xd8\x03ME4W\x8dMEMS\x0b8\x04ME8W\x8dMEMS\x0b\x98\x04MECW\x8aMEMS
+\xacMEB1\x8aMEMS
+\xb0MEL1\x8aMEMS
+\xbcMEL2\x8aMEMS
+\xc8MEL3\x14F=_CRS\x00\xa0M\x17\\W98Ft\\MEMXMEB0MEL0p\\GAPAMGPBp\\GAPLMGPL\xa0I\x0c\x90MGPBMGPLt\x87ME98
+\x02`\x08MBF0\x11\x02`r`\x87MGAP`\x08MBF1\x11\x02`pME98MBF0sMBF0MGAPMBF1\xa0O\x07\x92\x93\\/\x05_SB_PCI0LPC_TPM__STA
+\x0ft\x87MBF1
+\x02`\x08MBF2\x11\x02`r`\x87\\/\x05_SB_PCI0LPC_TPM__CRS`\x08MBF3\x11\x02`pMBF1MBF2sMBF2\\/\x05_SB_PCI0LPC_TPM__CRSMBF3\xa4MBF3\xa1\x06\xa4MBF1\xa1I\x08\xa0O\x07\x92\x93\\/\x05_SB_PCI0LPC_TPM__STA
+\x0ft\x87ME98
+\x02`\x08MBF4\x11\x02`r`\x87\\/\x05_SB_PCI0LPC_TPM__CRS`\x08MBF5\x11\x02`pME98MBF4sMBF4\\/\x05_SB_PCI0LPC_TPM__CRSMBF5\xa4MBF5\xa1\x06\xa4ME98{\\/\x03_SB_PCI0PAM1
+\x03`\xa0\x18`p\x0b\x00@MC0L\xa0\r{`
+\x02\x00p
+\x01MC0W{\\/\x03_SB_PCI0PAM1
+0`\xa0\x18`p\x0b\x00@MC4L\xa0\r{`
+ \x00p
+\x01MC4W{\\/\x03_SB_PCI0PAM2
+\x03`\xa0\x18`p\x0b\x00@MC8L\xa0\r{`
+\x02\x00p
+\x01MC8W{\\/\x03_SB_PCI0PAM2
+0`\xa0\x18`p\x0b\x00@MCCL\xa0\r{`
+ \x00p
+\x01MCCW{\\/\x03_SB_PCI0PAM3
+\x03`\xa0\x18`p\x0b\x00@MD0L\xa0\r{`
+\x02\x00p
+\x01MD0W{\\/\x03_SB_PCI0PAM3
+0`\xa0\x18`p\x0b\x00@MD4L\xa0\r{`
+ \x00p
+\x01MD4W{\\/\x03_SB_PCI0PAM4
+\x03`\xa0\x18`p\x0b\x00@MD8L\xa0\r{`
+\x02\x00p
+\x01MD8W{\\/\x03_SB_PCI0PAM4
+0`\xa0\x18`p\x0b\x00@MDCL\xa0\r{`
+ \x00p
+\x01MDCW{\\/\x03_SB_PCI0PAM5
+\x03`\xa0\x18`p\x0b\x00@ME0L\xa0\r{`
+\x02\x00p
+\x01ME0W{\\/\x03_SB_PCI0PAM5
+0`\xa0\x18`p\x0b\x00@ME4L\xa0\r{`
+ \x00p
+\x01ME4W{\\/\x03_SB_PCI0PAM6
+\x03`\xa0\x18`p\x0b\x00@ME8L\xa0\r{`
+\x02\x00p
+\x01ME8W{\\/\x03_SB_PCI0PAM6
+0`\xa0\x18`p\x0b\x00@MECL\xa0\r{`
+ \x00p
+\x01MECWt\\MEMXMEB1MEL1\xa0-\x92\x93\\/\x05_SB_PCI0LPC_TPM__STA
+\x0fp\x0c\x00\x00@\x01MEL2p
+\x00MEL3\xa4MEMS[\x82I\rLID_\x08_HID\x0cA\xd0\x0c\r\x14<_LID\x00\xa0\x1e\\H8DR\xa4\\/\x05_SB_PCI0LPC_EC__HPLD\xa1\x16\xa0\x0f{\\RBEC
+F
+\x04\x00\xa4
+\x01\xa1\x04\xa4
+\x00\x14&_PRW\x00\xa0\x15\x90\\W98F\x92\\WMEF\xa4\x12\x06\x02
+\x18
+\x04\xa1\t\xa4\x12\x06\x02
+\x18
+\x03\x14D\x06_PSW\x01\xa0?\\H8DR\xa0\x1chp
+\x01\\/\x05_SB_PCI0LPC_EC__HWLO\xa1\x1bp
+\x00\\/\x05_SB_PCI0LPC_EC__HWLO\xa1\x1c\xa0\rh\\MBEC
+2
+\xff
+\x04\xa1\x0c\\MBEC
+2
+\xfb
+\x00[\x82L\tSLPB\x08_HID\x0cA\xd0\x0c\x0e\x14&_PRW\x00\xa0\x15\x90\\W98F\x92\\WMEF\xa4\x12\x06\x02
+\x18
+\x04\xa1\t\xa4\x12\x06\x02
+\x18
+\x03\x14D\x06_PSW\x01\xa0?\\H8DR\xa0\x1chp
+\x01\\/\x05_SB_PCI0LPC_EC__HWFN\xa1\x1bp
+\x00\\/\x05_SB_PCI0LPC_EC__HWFN\xa1\x1c\xa0\rh\\MBEC
+2
+\xff
+\x10\xa1\x0c\\MBEC
+2
+\xef
+\x00[\x82\x8fH\x07PCI0[\x82\x8a\x96\x04LPC_\x08_ADR\x0c\x00\x00\x1f\x00\x08_S3D
+\x03\x08RID_
+\x00[\x82M\x1aSIO_\x08_HID\x0cA\xd0\x0c\x02\x08_UID
+\x00\x08SCRS\x11B\x10
+\xfeG\x01\x10\x00\x10\x00\x01\x10G\x01\x90\x00\x90\x00\x01\x10G\x01$\x00$\x00\x01\x02G\x01(\x00(\x00\x01\x02G\x01,\x00,\x00\x01\x02G\x010\x000\x00\x01\x02G\x014\x004\x00\x01\x02G\x018\x008\x00\x01\x02G\x01<\x00<\x00\x01\x02G\x01\xa4\x00\xa4\x00\x01\x02G\x01\xa8\x00\xa8\x00\x01\x02G\x01\xac\x00\xac\x00\x01\x02G\x01\xb0\x00\xb0\x00\x01\x06G\x01\xb8\x00\xb8\x00\x01\x02G\x01\xbc\x00\xbc\x00\x01\x02G\x01P\x00P\x00\x01\x04G\x01r\x00r\x00\x01\x06G\x01N\x16N\x16\x01\x02G\x01.\x00.\x00\x01\x02G\x01\x00\x10\x00\x10\x01\x80G\x01\x80\x11\x80\x11\x01@G\x01\x00\x08\x00\x08\x01\x10G\x01\xe0\x15\xe0\x15\x01\x10G\x01\x00\x16\x00\x16\x01`\x86\t\x00\x01\x00\x00\x00\xf0\x00\x00\x00\x04\x86\t\x00\x01\x00\xc0\xd1\xfe\x00@\x00\x00\x86\t\x00\x01\x00@\xd1\xfe\x00@\x00\x00\x86\t\x00\x01\x00\x80\xd1\xfe\x00\x10\x00\x00\x86\t\x00\x01\x00\x90\xd1\xfe\x00\x10\x00\x00y\x00\x14M\x08_CRS\x00\xa0 \x93\\/\x05_SB_PCI0LPC_TPM__STA
+\x0f\xa4SCRS\xa1D\x06t\x87SCRS
+\x02`\x08BUF0\x11\x02`r`\x87\\/\x05_SB_PCI0LPC_TPM__CRS`\x08BUF1\x11\x02`pSCRSBUF0sBUF0\\/\x05_SB_PCI0LPC_TPM__CRSBUF1\xa4BUF1[\x80LPCS\x02
+\x00\x0b\x00\x01[\x81G
+LPCS\x00\x00@0PIRA\x08PIRB\x08PIRC\x08PIRD\x08SERQ\x08\x00\x18PIRE\x08PIRF\x08PIRG\x08PIRH\x08\x00@
+XU1A\x03\x00\x01XU2A\x03\x00\x01XPA_\x02\x00\x02XFA_\x01\x00\x03XU1E\x01XU2E\x01XPE_\x01XFE_\x01\x00\x0cXG1E\x01\x00\x06XG1A\t\x00\x10XG2E\x01\x00\x03XG2A\x0c\x00@\x0b\x00\x02CLKR\x01GYEN\x01\x00\x03C4C3\x01\x00\x02EXPE\x01\x00\x05[\x80LPIO\x01\x0b\x80\x11
+@[\x81O
+LPIO\x03GU00\x08GU01\x08GU02\x08GU03\x08GI00\x08GI01\x08GI02\x08GI03\x08\x00 GL00\x08GL01\x08GL02\x08GL03\x08\x00@\x04GB00\x08GB01\x08GB02\x08GB03\x08\x00@\x08GV00\x08GV01\x08GV02\x08GV03\x08GU04\x08GU05\x08GU06\x08GU07\x08GI04\x08GI05\x08GI06\x08GI07\x08GL04\x08GL05\x08GL06\x08GL07\x08[\x80PMIO\x01\x0b\x00\x10
+\x80[\x81\x10PMIO\x00\x00@!\x00\x01SWGE\x01[\x823PIC_\x08_HID\x0bA\xd0\x08_CRS\x11
+\x1dG\x01 \x00 \x00\x01\x02G\x01\xa0\x00\xa0\x00\x01\x02G\x01\xd0\x04\xd0\x04\x01\x02"\x04\x00y\x00[\x82%TIMR\x08_HID\x0cA\xd0\x01\x00\x08_CRS\x11\x10
+\rG\x01@\x00@\x00\x01\x04"\x01\x00y\x00[\x82B\x05HPET\x08_HID\x0cA\xd0\x01\x03\x14*_STA\x00\xa0\x08W98F\xa4
+\x00\xa1\x17\xa0\x10\x90\\WNTF\x92\\WXPF\xa4
+\x00\xa1\x04\xa4
+\x0f\xa4
+\x00\x08_CRS\x11\x11
+\x0e\x86\t\x00\x00\x00\x00\xd0\xfe\x00\x04\x00\x00y\x00[\x825DMAC\x08_HID\x0cA\xd0\x02\x00\x08_CRS\x11
+\x1dG\x01\x00\x00\x00\x00\x01\x10G\x01\x80\x00\x80\x00\x01\x10G\x01\xc0\x00\xc0\x00\x01 *\x10\x05y\x00[\x82"SPKR\x08_HID\x0cA\xd0\x08\x00\x08_CRS\x11\r
+
+G\x01a\x00a\x00\x01\x01y\x00[\x82%FPU_\x08_HID\x0cA\xd0\x0c\x04\x08_CRS\x11\x10
+\rG\x01\xf0\x00\xf0\x00\x01\x01"\x00 y\x00[\x82%RTC_\x08_HID\x0cA\xd0\x0b\x00\x08_CRS\x11\x10
+\rG\x01p\x00p\x00\x01\x02"\x00\x01y\x00[\x82-KBD_\x08_HID\x0cA\xd0\x03\x03\x08_CRS\x11\x18
+\x15G\x01`\x00`\x00\x01\x01G\x01d\x00d\x00\x01\x01"\x02\x00y\x00[\x82J\x05MOU_\x08_HID\x0c$M7\x80\x08_CID\x0cA\xd0\x0f\x13\x08_CRS\x11\x08
+\x05"\x00\x10y\x00\x141MHID\x00\xa0\x1e\\/\x04_SB_PCI0LPC_PADDp\x0c$M7\x80_HID\xa1\x0bp\x0c$M\x00W_HID[\x80IMGA\x01\x0b\xe0\x15
+\x10[\x81!IMGA\x01\x00\x08\x00\x08\x00\x08WAKR\x10\x008GAIX\x08\x00\x08GADT\x08\x00\x08[\x86I\x0bGAIXGADT\x01\x00H VAUX\x02\x00\x01WOLE\x01\x00\x04\x00@\x07\x00\x01CBPW\x01CBSL\x01VDPW\x01PDNE\x01BLPL\x01\x00\x01LEDS\x01TP4R\x01PADR\x01BPAD\x01\x00\x01\x00\x01PADD\x01\x00
+DLAN\x01\x00G\x06BUSC\x01BUSD\x01\x00\x01DSCI\x01\x00\x04EPWG\x01\x00\x02DSCS\x01\x00\x04CSON\x01URST\x01\x00N\x06GDR0\x01GDR1\x01GDR2\x01\x00\x05GDT0\x01GDT1\x01GDT2\x01\x00E(GAID\x08[\x80NCFG\x01
+.
+\x02[\x81\x10NCFG\x01INDX\x08DATA\x08[\x86B
+INDXDATA\x01\x008LDN_\x08\x00@\x0cSIOD\x08\x00\x08SCF2\x08\x00\x08SCF4\x08\x00\x02PPSE\x01\x00\x04PNF_\x01FDCD\x01PPD_\x01SP2D\x01SP1D\x01\x00\x01GPSR\x02\x00\x01SRID\x08\x00\x08SCF9\x08\x00\x08\x00(LDA_\x01\x00\x07\x00H\x17IOHI\x08IOLW\x08\x00@\x07IRQN\x04IRQW\x01\x00\x03IRQT\x01IRQL\x01\x00\x06\x00\x10DMA0\x03\x00\x05DMA1\x03\x00\x05[\x86#INDXDATA\x01\x00@xPTRS\x01PPMC\x01\x00\x02PERA\x01PMDS\x03[\x86#INDXDATA\x01\x00@xSTRS\x01SPMC\x01SBSY\x01\x00\x04SBSE\x01[\x86\x1cINDXDATA\x01\x00@xGPPS\x08GPPC\x08GPER\x08[\x80CFGS\x01\x0bN\x16
+\x02[\x81\x10CFGS\x01NDXS\x08ATAS\x08[\x86J
+NDXSATAS\x01\x008LDNS\x08\x00@\x0c\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x02PSES\x01\x00\x04PNFS\x01DCDS\x01PPDS\x01SP2S\x01SP1S\x01\x00\x01PSRS\x02\x00\x01RIDS\x08\x00\x08CCSS\x02CCES\x01MCSS\x01MESS\x01\x00\x03\x00\x08\x00(LDAS\x01\x00\x07\x00H\x17OHIS\x08OLWS\x08\x00@\x07RQNS\x04RQWS\x01\x00\x03RQTS\x01RQLS\x01\x00\x06\x00\x10MA0S\x03\x00\x05MA1S\x03\x00\x05[\x86#NDXSATAS\x01\x00@xTRSS\x01PMCS\x01BSYS\x01\x00\x04SESS\x01[\x80NSDL\x01\x0bL\x16
+\x01[\x81\x0bNSDL\x01DLPC\x08[\x80NSIO\x01\x0b\x80\x16
+\x0c[\x81\'NSIO\x01DRST\x01DLPD\x01\x00\x06\x00\x04DKI0\x01\x00\x03\x008DKI1\x01DKI2\x01[\x80DSIO\x01\x0b \x16
+\x0c[\x81\x0fDSIO\x01\x00\x01DUSB\x01\x00\x06[\x82K\x18FDC_\x08_HID\x0cA\xd0\x07\x00\x14 _STA\x00\xa0\x14\\LFDC\xa0\x08XFE_\xa4
+\x0f\xa1\x04\xa4
+\r\xa1\x04\xa4
+\x00\x14)_DIS\x00p
+\x00XFE_p
+\x00LDN_p
+\x00IRQNp
+\x00LDA_p
+\x01FDCD\x08_CRS\x11\x1b
+\x18G\x01\xf0\x03\xf0\x03\x01\x06G\x01\xf7\x03\xf7\x03\x01\x01"@\x00*\x04\x00y\x00\x08_PRS\x11\x1b
+\x18G\x01\xf0\x03\xf0\x03\x01\x06G\x01\xf7\x03\xf7\x03\x01\x01"@\x00*\x04\x00y\x00\x14M\x04_SRS\x01p
+\x00LDN_p
+\x00LDA_p
+\x03IOHIp
+\xf0IOLWp
+\x06IRQNp
+\x02DMA0p
+\x00FDCDp
+\x01LDA_p
+\x00XFA_p
+\x01XFE_\x14\x1b_PSC\x00p
+\x00LDN_\xa0\x08LDA_\xa4
+\x00\xa1\x04\xa4
+\x03\x14\x14_PS0\x00p
+\x00LDN_p
+\x01LDA_\x14\x14_PS3\x00p
+\x00LDN_p
+\x00LDA_\x14#SLFD\x01\xa0\x0eh\\MISA\x0b\xf3\x03
+\xf3
+\x04\xa1\r\\MISA\x0b\xf3\x03
+\xf3
+\x00[\x824FDD0\x08_ADR
+\x00\x08_FDI\x12"\x10
+\x00
+\x04
+O
+\x12
+\x01
+\xdf
+\x02
+%
+\x02
+\x12
+\x1b
+\xff
+l
+\xf6
+\x0f
+\x05\x10\x86/\x01\\/\x03_SB_PCI0LPC_[\x82A-LURT\x08_UID
+\x00\x14-_STA\x00\xa0\x16\x93\\/\x03_SB_LCIO_STA
+\x00\xa4
+\x00\xa1\x0f\xa0\x08XU1E\xa4
+\x0f\xa1\x04\xa4
+\r\x08_HID\x0cA\xd0\x05\x01\x08_PRW\x12\x06\x02
+\x18
+\x03\x14D\x06_PSW\x01\xa0?\\H8DR\xa0\x1chp
+\x01\\/\x05_SB_PCI0LPC_EC__HWRI\xa1\x1bp
+\x00\\/\x05_SB_PCI0LPC_EC__HWRI\xa1\x1c\xa0\rh\\MBEC
+2
+\xff
+@\xa1\x0c\\MBEC
+2
+\xbf
+\x00\x14)_DIS\x00p
+\x00XU1Ep
+\x03LDN_p
+\x00IRQNp
+\x00LDA_p
+\x01SP1D\x08U1BF\x11\x10
+\rG\x01\x00\x00\x00\x00\x01\x08"\x00\x00y\x00\x8bU1BF
+\x02U1MN\x8bU1BF
+\x04U1MX\x8bU1BF
+\tU1IQ\x14J\x04_CRS\x00p
+\x03LDN_}yIOHI
+\x08\x00IOLW`p`U1MNp`U1MXpIRQN`\xa0\r`y
+\x01IRQNU1IQ\xa1\x08p
+\x00U1IQ\xa4U1BF\x08_PRS\x11O\x06
+k1\x00G\x01\xf8\x03\xf8\x03\x01\x08"\x10\x001\x01G\x01\xf8\x02\xf8\x02\x01\x08"\x08\x001\x01G\x01\xe8\x03\xe8\x03\x01\x08"\x10\x001\x01G\x01\xe8\x02\xe8\x02\x01\x08"\x08\x001\x02G\x01\xf8\x03\xf8\x03\x01\x08"\xa8\x001\x02G\x01\xf8\x02\xf8\x02\x01\x08"\xb0\x001\x02G\x01\xe8\x03\xe8\x03\x01\x08"\xa8\x001\x02G\x01\xe8\x02\xe8\x02\x01\x08"\xb0\x008y\x00\x14O\x0c_SRS\x01\x8ch
+\x02RUIL\x8ch
+\x03RUIH\x8bh
+\x02RUIO\x8bh
+\tRUIQp
+\x03LDN_p
+\x00LDA_pRUILIOLWpRUIHIOHI\xa0\x12RUIQ\x82RUIQ`pv`IRQN\xa1\x08p
+\x00IRQNp
+\x00SP1Dp
+\x01LDA_\xa0\x10\x93RUIO\x0b\xf8\x03p
+\x00XU1A\xa1E\x04\xa0\x10\x93RUIO\x0b\xf8\x02p
+\x01XU1A\xa11\xa0\x10\x93RUIO\x0b\xe8\x03p
+\x07XU1A\xa1\x1e\xa0\x10\x93RUIO\x0b\xe8\x02p
+\x05XU1A\xa1\x0b[2\x02\x00\x00\x02\x90\x0b\xb5\x01p
+\x01XU1E\x14\x1b_PSC\x00p
+\x03LDN_\xa0\x08LDA_\xa4
+\x00\xa1\x04\xa4
+\x03\x14\x06_PS0\x00\x14\x06_PS3\x00[\x82G-DURT\x08_UID
+\x01\x143_STA\x00\xa0\x1c\x92{
+\x08\\/\x04_SB_PCI0LPC_DLPC\x00\xa4
+\x00\xa1\x0f\xa0\x08XU1E\xa4
+\x0f\xa1\x04\xa4
+\r\x08_HID\x0cA\xd0\x05\x01\x08_PRW\x12\x06\x02
+\x18
+\x03\x14D\x06_PSW\x01\xa0?\\H8DR\xa0\x1chp
+\x01\\/\x05_SB_PCI0LPC_EC__HWRI\xa1\x1bp
+\x00\\/\x05_SB_PCI0LPC_EC__HWRI\xa1\x1c\xa0\rh\\MBEC
+2
+\xff
+@\xa1\x0c\\MBEC
+2
+\xbf
+\x00\x14)_DIS\x00p
+\x00XU1Ep
+\x03LDN_p
+\x00IRQNp
+\x00LDA_p
+\x01SP1D\x08U1BF\x11\x10
+\rG\x01\x00\x00\x00\x00\x01\x08"\x00\x00y\x00\x8bU1BF
+\x02U1MN\x8bU1BF
+\x04U1MX\x8bU1BF
+\tU1IQ\x14J\x04_CRS\x00p
+\x03LDN_}yIOHI
+\x08\x00IOLW`p`U1MNp`U1MXpIRQN`\xa0\r`y
+\x01IRQNU1IQ\xa1\x08p
+\x00U1IQ\xa4U1BF\x08_PRS\x11O\x06
+k1\x00G\x01\xf8\x03\xf8\x03\x01\x08"\x10\x001\x01G\x01\xf8\x02\xf8\x02\x01\x08"\x08\x001\x01G\x01\xe8\x03\xe8\x03\x01\x08"\x10\x001\x01G\x01\xe8\x02\xe8\x02\x01\x08"\x08\x001\x02G\x01\xf8\x03\xf8\x03\x01\x08"\xa8\x001\x02G\x01\xf8\x02\xf8\x02\x01\x08"\xb0\x001\x02G\x01\xe8\x03\xe8\x03\x01\x08"\xa8\x001\x02G\x01\xe8\x02\xe8\x02\x01\x08"\xb0\x008y\x00\x14O\x0c_SRS\x01\x8ch
+\x02RUIL\x8ch
+\x03RUIH\x8bh
+\x02RUIO\x8bh
+\tRUIQp
+\x03LDN_p
+\x00LDA_pRUILIOLWpRUIHIOHI\xa0\x12RUIQ\x82RUIQ`pv`IRQN\xa1\x08p
+\x00IRQNp
+\x00SP1Dp
+\x01LDA_\xa0\x10\x93RUIO\x0b\xf8\x03p
+\x00XU1A\xa1E\x04\xa0\x10\x93RUIO\x0b\xf8\x02p
+\x01XU1A\xa11\xa0\x10\x93RUIO\x0b\xe8\x03p
+\x07XU1A\xa1\x1e\xa0\x10\x93RUIO\x0b\xe8\x02p
+\x05XU1A\xa1\x0b[2\x02\x00\x00\x02\x90\x0b\xb5\x01p
+\x01XU1E\x14\x1b_PSC\x00p
+\x03LDN_\xa0\x08LDA_\xa4
+\x00\xa1\x04\xa4
+\x03\x14\x06_PS0\x00\x14\x06_PS3\x00[\x82L1LLPT\x08_UID
+\x00\x14=_STA\x00\xa0\x16\x93\\/\x03_SB_LCIO_STA
+\x00\xa4
+\x00\xa1\x1f\xa0\x18\x92\x93\\PMOD
+\x03\xa0\x08XPE_\xa4
+\x0f\xa1\x04\xa4
+\r\xa1\x04\xa4
+\x00\x08_HID\x0cA\xd0\x04\x00\x14)_DIS\x00p
+\x00XPE_p
+\x01LDN_p
+\x00IRQNp
+\x00LDA_p
+\x01PPD_\x08PPBF\x11\x10
+\rG\x01\x00\x00\x00\x00\x01\x00"\x00\x00y\x00\x8bPPBF
+\x02LPN0\x8bPPBF
+\x04LPX0\x8cPPBF
+\x07LPL0\x8bPPBF
+\tLPIQ\x14@\x07_CRS\x00\xa0\x0e\x93\\PMOD
+\x03\xa4PPBFp
+\x01LDN_}yIOHI
+\x08\x00IOLW`p`LPN0p`LPX0\xa0\r\x93`\x0b\xbc\x03p
+\x03LPL0\xa1\x08p
+\x08LPL0pIRQN`\xa0\r`y
+\x01IRQNLPIQ\xa1\x08p
+\x00LPIQ\xa4PPBF\x14\x19_PRS\x00\xa0\x0b\\PMOD\xa4PEPP\xa1\x06\xa4PLPT\x08PLPT\x11O\x04
+K0G\x01\xbc\x03\xbc\x03\x01\x03"\x80\x000G\x01x\x03x\x03\x01\x08"\x80\x000G\x01x\x02x\x02\x01\x08" \x000G\x01\xbc\x03\xbc\x03\x01\x03" \x000G\x01x\x03x\x03\x01\x08" \x000G\x01x\x02x\x02\x01\x08"\x80\x008y\x00\x08PEPP\x116
+30G\x01x\x03x\x03\x01\x08"\x80\x000G\x01x\x02x\x02\x01\x08" \x000G\x01x\x03x\x03\x01\x08" \x000G\x01x\x02x\x02\x01\x08"\x80\x008y\x00\x14H\x0f_SRS\x01\x8ch
+\x02RLIL\x8ch
+\x03RLIH\x8bh
+\x02RLIO\x8bh
+\tRLIQp
+\x01LDN_p
+\x00LDA_pRLILIOLWpRLIHIOHI\xa0\x12RLIQ\x82RLIQ`pv`IRQN\xa1\x08p
+\x00IRQN\xa0 \x93\\PMOD
+\x00\xa0\r\\PDIRp
+\x01PMDS\xa1\x08p
+\x00PMDS\xa1\x1b\xa0\x10\x93\\PMOD
+\x01p
+\x02PMDS\xa1\x08p
+\x03PMDSp
+\x00PPD_p
+\x01LDA_\xa0\x10\x93RLIO\x0bx\x03p
+\x00XPA_\xa11\xa0\x10\x93RLIO\x0bx\x02p
+\x01XPA_\xa1\x1e\xa0\x10\x93RLIO\x0b\xbc\x03p
+\x02XPA_\xa1\x0b[2\x02\x00\x00\x02\x90\x0b\xce\x01p
+\x01XPE_\x14\x1b_PSC\x00p
+\x01LDN_\xa0\x08LDA_\xa4
+\x00\xa1\x04\xa4
+\x03\x14\x14_PS0\x00p
+\x01LDN_p
+\x01LDA_\x14\x14_PS3\x00p
+\x01LDN_p
+\x00LDA_[\x82C2DLPT\x08_UID
+\x01\x14D\x04_STA\x00\xa0\x1c\x92{
+\x08\\/\x04_SB_PCI0LPC_DLPC\x00\xa4
+\x00\xa1\x1f\xa0\x18\x92\x93\\PMOD
+\x03\xa0\x08XPE_\xa4
+\x0f\xa1\x04\xa4
+\r\xa1\x04\xa4
+\x00\x08_HID\x0cA\xd0\x04\x00\x14)_DIS\x00p
+\x00XPE_p
+\x01LDN_p
+\x00IRQNp
+\x00LDA_p
+\x01PPD_\x08PPBF\x11\x10
+\rG\x01\x00\x00\x00\x00\x01\x00"\x00\x00y\x00\x8bPPBF
+\x02LPN0\x8bPPBF
+\x04LPX0\x8cPPBF
+\x07LPL0\x8bPPBF
+\tLPIQ\x14@\x07_CRS\x00\xa0\x0e\x93\\PMOD
+\x03\xa4PPBFp
+\x01LDN_}yIOHI
+\x08\x00IOLW`p`LPN0p`LPX0\xa0\r\x93`\x0b\xbc\x03p
+\x03LPL0\xa1\x08p
+\x08LPL0pIRQN`\xa0\r`y
+\x01IRQNLPIQ\xa1\x08p
+\x00LPIQ\xa4PPBF\x14\x19_PRS\x00\xa0\x0b\\PMOD\xa4PEPP\xa1\x06\xa4PLPT\x08PLPT\x11O\x04
+K0G\x01\xbc\x03\xbc\x03\x01\x03"\x80\x000G\x01x\x03x\x03\x01\x08"\x80\x000G\x01x\x02x\x02\x01\x08" \x000G\x01\xbc\x03\xbc\x03\x01\x03" \x000G\x01x\x03x\x03\x01\x08" \x000G\x01x\x02x\x02\x01\x08"\x80\x008y\x00\x08PEPP\x116
+30G\x01x\x03x\x03\x01\x08"\x80\x000G\x01x\x02x\x02\x01\x08" \x000G\x01x\x03x\x03\x01\x08" \x000G\x01x\x02x\x02\x01\x08"\x80\x008y\x00\x14H\x0f_SRS\x01\x8ch
+\x02RLIL\x8ch
+\x03RLIH\x8bh
+\x02RLIO\x8bh
+\tRLIQp
+\x01LDN_p
+\x00LDA_pRLILIOLWpRLIHIOHI\xa0\x12RLIQ\x82RLIQ`pv`IRQN\xa1\x08p
+\x00IRQN\xa0 \x93\\PMOD
+\x00\xa0\r\\PDIRp
+\x01PMDS\xa1\x08p
+\x00PMDS\xa1\x1b\xa0\x10\x93\\PMOD
+\x01p
+\x02PMDS\xa1\x08p
+\x03PMDSp
+\x00PPD_p
+\x01LDA_\xa0\x10\x93RLIO\x0bx\x03p
+\x00XPA_\xa11\xa0\x10\x93RLIO\x0bx\x02p
+\x01XPA_\xa1\x1e\xa0\x10\x93RLIO\x0b\xbc\x03p
+\x02XPA_\xa1\x0b[2\x02\x00\x00\x02\x90\x0b\xce\x01p
+\x01XPE_\x14\x1b_PSC\x00p
+\x01LDN_\xa0\x08LDA_\xa4
+\x00\xa1\x04\xa4
+\x03\x14\x14_PS0\x00p
+\x01LDN_p
+\x01LDA_\x14\x14_PS3\x00p
+\x01LDN_p
+\x00LDA_[\x82E7LECP\x08_UID
+\x00\x14<_STA\x00\xa0\x16\x93\\/\x03_SB_LCIO_STA
+\x00\xa4
+\x00\xa1\x1e\xa0\x17\x93\\PMOD
+\x03\xa0\x08XPE_\xa4
+\x0f\xa1\x04\xa4
+\r\xa1\x04\xa4
+\x00\x08_HID\x0cA\xd0\x04\x01\x14)_DIS\x00p
+\x00XPE_p
+\x01LDN_p
+\x00IRQNp
+\x00LDA_p
+\x01PPD_\x08EPBF\x11\x1b
+\x18G\x01\x00\x00\x00\x00\x01\x00G\x01\x00\x00\x00\x00\x01\x00"\x00\x00*\x00\x00y\x00\x8bEPBF
+\x02ECN0\x8bEPBF
+\x04ECX0\x8cEPBF
+\x07ECL0\x8bEPBF
+
+ECN1\x8bEPBF
+\x0cECX1\x8cEPBF
+\x0fECL1\x8bEPBF
+\x11ECIQ\x8bEPBF
+\x14ECDQ\x14N
+_CRS\x00\xa0\x0f\x92\x93\\PMOD
+\x03\xa4EPBFp
+\x01LDN_}yIOHI
+\x08\x00IOLW`p`ECN0p`ECX0r`\x0b\x00\x04ECN1r`\x0b\x00\x04ECX1\xa0\x14\x93`\x0b\xbc\x03p
+\x03ECL0p
+\x03ECL1\xa1\x0fp
+\x08ECL0p
+\x08ECL1pIRQN`\xa0\r`y
+\x01IRQNECIQ\xa1\x08p
+\x00ECIQpDMA0`\xa0\r\x95`
+\x04y
+\x01`ECDQ\xa1\x08p
+\x00ECDQ\xa4EPBF\x08_PRS\x11A\t
+\x8d0G\x01x\x03x\x03\x01\x08G\x01x\x07x\x07\x01\x08"\x80\x00*\x0b\x000G\x01x\x02x\x02\x01\x08G\x01x\x06x\x06\x01\x08" \x00*\x0b\x000G\x01\xbc\x03\xbc\x03\x01\x03G\x01\xbc\x07\xbc\x07\x01\x03"\x80\x00*\x0b\x000G\x01x\x03x\x03\x01\x08G\x01x\x07x\x07\x01\x08" \x00*\x0b\x000G\x01x\x02x\x02\x01\x08G\x01x\x06x\x06\x01\x08"\x80\x00*\x0b\x000G\x01\xbc\x03\xbc\x03\x01\x03G\x01\xbc\x07\xbc\x07\x01\x03" \x00*\x0b\x008y\x00\x14A\x0f_SRS\x01\x8ch
+\x02RLIL\x8ch
+\x03RLIH\x8bh
+\x02RLIO\x8bh
+\x11RLIQ\x8ch
+\x14RLDQp
+\x01LDN_p
+\x00LDA_p
+\x07PMDSp
+\x01PERApRLILIOLWpRLIHIOHI\xa0\x12RLIQ\x82RLIQ`pv`IRQN\xa1\x08p
+\x00IRQN\xa0\x16{RLDQ
+\x0f\x00\x82RLDQ`pv`DMA0\xa1\x08p
+\x04DMA0p
+\x00PPD_p
+\x01LDA_\xa0\x10\x93RLIO\x0bx\x03p
+\x00XPA_\xa11\xa0\x10\x93RLIO\x0bx\x02p
+\x01XPA_\xa1\x1e\xa0\x10\x93RLIO\x0b\xbc\x03p
+\x02XPA_\xa1\x0b[2\x02\x00\x00\x02\x90\x0b\x9f\x01p
+\x01XPE_\x14\x1b_PSC\x00p
+\x01LDN_\xa0\x08LDA_\xa4
+\x00\xa1\x04\xa4
+\x03\x14\x14_PS0\x00p
+\x01LDN_p
+\x01LDA_\x14\x14_PS3\x00p
+\x01LDN_p
+\x00LDA_[\x82L7DECP\x08_UID
+\x01\x14C\x04_STA\x00\xa0\x1c\x92{
+\x08\\/\x04_SB_PCI0LPC_DLPC\x00\xa4
+\x00\xa1\x1e\xa0\x17\x93\\PMOD
+\x03\xa0\x08XPE_\xa4
+\x0f\xa1\x04\xa4
+\r\xa1\x04\xa4
+\x00\x08_HID\x0cA\xd0\x04\x01\x14)_DIS\x00p
+\x00XPE_p
+\x01LDN_p
+\x00IRQNp
+\x00LDA_p
+\x01PPD_\x08EPBF\x11\x1b
+\x18G\x01\x00\x00\x00\x00\x01\x00G\x01\x00\x00\x00\x00\x01\x00"\x00\x00*\x00\x00y\x00\x8bEPBF
+\x02ECN0\x8bEPBF
+\x04ECX0\x8cEPBF
+\x07ECL0\x8bEPBF
+
+ECN1\x8bEPBF
+\x0cECX1\x8cEPBF
+\x0fECL1\x8bEPBF
+\x11ECIQ\x8bEPBF
+\x14ECDQ\x14N
+_CRS\x00\xa0\x0f\x92\x93\\PMOD
+\x03\xa4EPBFp
+\x01LDN_}yIOHI
+\x08\x00IOLW`p`ECN0p`ECX0r`\x0b\x00\x04ECN1r`\x0b\x00\x04ECX1\xa0\x14\x93`\x0b\xbc\x03p
+\x03ECL0p
+\x03ECL1\xa1\x0fp
+\x08ECL0p
+\x08ECL1pIRQN`\xa0\r`y
+\x01IRQNECIQ\xa1\x08p
+\x00ECIQpDMA0`\xa0\r\x95`
+\x04y
+\x01`ECDQ\xa1\x08p
+\x00ECDQ\xa4EPBF\x08_PRS\x11A\t
+\x8d0G\x01x\x03x\x03\x01\x08G\x01x\x07x\x07\x01\x08"\x80\x00*\x0b\x000G\x01x\x02x\x02\x01\x08G\x01x\x06x\x06\x01\x08" \x00*\x0b\x000G\x01\xbc\x03\xbc\x03\x01\x03G\x01\xbc\x07\xbc\x07\x01\x03"\x80\x00*\x0b\x000G\x01x\x03x\x03\x01\x08G\x01x\x07x\x07\x01\x08" \x00*\x0b\x000G\x01x\x02x\x02\x01\x08G\x01x\x06x\x06\x01\x08"\x80\x00*\x0b\x000G\x01\xbc\x03\xbc\x03\x01\x03G\x01\xbc\x07\xbc\x07\x01\x03" \x00*\x0b\x008y\x00\x14A\x0f_SRS\x01\x8ch
+\x02RLIL\x8ch
+\x03RLIH\x8bh
+\x02RLIO\x8bh
+\x11RLIQ\x8ch
+\x14RLDQp
+\x01LDN_p
+\x00LDA_p
+\x07PMDSp
+\x01PERApRLILIOLWpRLIHIOHI\xa0\x12RLIQ\x82RLIQ`pv`IRQN\xa1\x08p
+\x00IRQN\xa0\x16{RLDQ
+\x0f\x00\x82RLDQ`pv`DMA0\xa1\x08p
+\x04DMA0p
+\x00PPD_p
+\x01LDA_\xa0\x10\x93RLIO\x0bx\x03p
+\x00XPA_\xa11\xa0\x10\x93RLIO\x0bx\x02p
+\x01XPA_\xa1\x1e\xa0\x10\x93RLIO\x0b\xbc\x03p
+\x02XPA_\xa1\x0b[2\x02\x00\x00\x02\x90\x0b\x9f\x01p
+\x01XPE_\x14\x1b_PSC\x00p
+\x01LDN_\xa0\x08LDA_\xa4
+\x00\xa1\x04\xa4
+\x03\x14\x14_PS0\x00p
+\x01LDN_p
+\x01LDA_\x14\x14_PS3\x00p
+\x01LDN_p
+\x00LDA_\x10#\\/\x04_SB_PCI0LPC_LURT\x08_EJD\r_SB.LCIO\x00\x10#\\/\x04_SB_PCI0LPC_DURT\x08_EJD\r_SB.GDCK\x00\x10#\\/\x04_SB_PCI0LPC_LLPT\x08_EJD\r_SB.LCIO\x00\x10#\\/\x04_SB_PCI0LPC_DLPT\x08_EJD\r_SB.GDCK\x00\x10#\\/\x04_SB_PCI0LPC_LECP\x08_EJD\r_SB.LCIO\x00\x10#\\/\x04_SB_PCI0LPC_DECP\x08_EJD\r_SB.GDCK\x00[\x82H.FIR_\x08_HID\x0c$M\x00q\x08_CID\x0cA\xd0\x05\x11\x14\x1d_STA\x00\xa0\x08HDIR\xa4
+\x00\xa0\x08XU2E\xa4
+\x0f\xa1\x04\xa4
+\r\x14)_DIS\x00p
+\x00XU2Ep
+\x02LDNSp
+\x00RQNSp
+\x00LDASp
+\x01SP2S\x08U2BF\x11\x13
+\x10G\x01\x00\x00\x00\x00\x01\x08"\x00\x00*\x00\x00y\x00\x8bU2BF
+\x02IRMN\x8bU2BF
+\x04IRMX\x8bU2BF
+\tIRIQ\x8cU2BF
+\x0cIRDQ\x14G\x06_CRS\x00p
+\x02LDNS}yOHIS
+\x08\x00OLWS`p`IRMNp`IRMXpRQNS`\xa0\r`y
+\x01RQNSIRIQ\xa1\x08p
+\x00IRIQpMA0S`\xa0\r\x95`
+\x04y
+\x01`IRDQ\xa1\x08p
+\x00IRDQ\xa4U2BF\x08_PRS\x11G\x08
+\x831\x00G\x01\xf8\x02\xf8\x02\x01\x08"\x08\x00*\x0b\x001\x01G\x01\xf8\x03\xf8\x03\x01\x08"\x10\x00*\x0b\x001\x01G\x01\xe8\x02\xe8\x02\x01\x08"\x08\x00*\x0b\x001\x01G\x01\xe8\x03\xe8\x03\x01\x08"\x10\x00*\x0b\x001\x02G\x01\xf8\x02\xf8\x02\x01\x08"\xb0\x00*\x0b\x001\x02G\x01\xf8\x03\xf8\x03\x01\x08"\xa8\x00*\x0b\x001\x02G\x01\xe8\x02\xe8\x02\x01\x08"\xb0\x00*\x0b\x001\x02G\x01\xe8\x03\xe8\x03\x01\x08"\xa8\x00*\x0b\x008y\x00\x14E\x10_SRS\x01\x8ch
+\x02RIIL\x8ch
+\x03RIIH\x8bh
+\x02RIIO\x8bh
+\tRIIQ\x8ch
+\x0cRIDQp
+\x02LDNSp
+\x00LDASpRIILOLWSpRIIHOHIS\xa0\x12RIIQ\x82RIIQ`pv`RQNS\xa1\x08p
+\x00RQNS\xa0\x16{RIDQ
+\x0f\x00\x82RIDQ`pv`MA0S\xa1\x08p
+\x04MA0Sp
+\x04MA1Sp
+\x01SESSp
+\x00SP2Sp
+\x01LDAS\xa0\x10\x93RIIO\x0b\xf8\x03p
+\x00XU2A\xa1E\x04\xa0\x10\x93RIIO\x0b\xf8\x02p
+\x01XU2A\xa11\xa0\x10\x93RIIO\x0b\xe8\x03p
+\x07XU2A\xa1\x1e\xa0\x10\x93RIIO\x0b\xe8\x02p
+\x05XU2A\xa1\x0b[2\x02\x00\x00\x02\x90\x0b\xa4\x01p
+\x01XU2E\x14\x1b_PSC\x00p
+\x02LDNS\xa0\x08LDAS\xa4
+\x00\xa1\x04\xa4
+\x03\x14\x14_PS0\x00p
+\x02LDNSp
+\x01LDAS\x14\x14_PS3\x00p
+\x02LDNSp
+\x00LDAS\x10C\x0e\\/\x03_SB_PCI0LPC_\x14A\rLCON\x01\xa0K
+h\xa0G
+EPWGp
+\x01DLPDp
+\x07DLPC\xa2\x0e\x92{
+\x08DLPC\x00["
+\x01p
+\x01DRST\xa0L\x07\x92\x93SIOD
+\xff}SCF9
+\xa0SCF9\xa2\x0e\x92{
+\x10SCF9\x00["
+\x01}SCF2
+\xebSCF2p
+\x07LDN_{\x0b \x16
+\xff`p`IOLWz\x0b \x16
+\x08`{`
+\xffIOHIp
+\x01LDA_p
+\x01GPPSp
+\x03GPPCp
+\x02GPPSp
+\x03GPPCp
+\x00DUSB\xa1\x1dp
+\x01DUSBp
+\x00DRSTp
+\x00DLPDp
+\x00DLPC[\x82GKTPM_\x08_HID\x0c\x06\x8d\x12\x00\x08_CID\x0cA\xd0\x0c1\x14\x1d_STA\x00\xa0\x0e{\\TPMP
+\x01\x00p
+\x0f`\xa1\x05p
+\x00`\xa4`\x08_CRS\x11\x11
+\x0e\x86\t\x00\x01\x00\x00\xd4\xfe\x00\x10\x00\x00y\x00\x14GF_DSM\x0c\x08TMPB\x11\x05
+\x02\x00\x00\x8cTMPB
+\x00LPCT\x8cTMPB
+\x01SSUM\x08LRSP
+\x00\x08PPRC
+\x00\x08RQS1\x12\x06\x02
+\x0c
+\r\x08PTOP\x12\x06\x02
+\x00
+\x00\x08RTOP\x12\x08\x03
+\x00
+\x00
+\x00\x8ah
+\x00IID0\x8ah
+\x04IID1\x8ah
+\x08IID2\x8ah
+\x0cIID3\x08UID0\x11\x13
+\x10\xa6\xfa\xdd=\x1b6\xb4N\xa4$\x8d\x10\x08\x9d\x16S\x8aUID0
+\x00EID0\x8aUID0
+\x04EID1\x8aUID0
+\x08EID2\x8aUID0
+\x0cEID3\xa0I,\x90\x90\x93IID0EID0\x93IID1EID1\x90\x93IID2EID2\x93IID3EID3\xa0\x0b\x93j
+\x00\xa4\x11\x04
+\x01?\xa0\x0b\x93j
+\x01\xa4\r1.0\x00\xa0L\x1c\x93j
+\x02p
+\x00PPRCTPHY
+\x00p\\PH02LPCT\xa0@\x1aLPCTp
+\x00SSUMrSSUM\\PH01SSUMrSSUM\\PH02SSUMrSSUM\\PH03SSUMrSSUM\\PH04SSUMrSSUM\\PH05SSUMrSSUM\\PH06SSUMrSSUM\\PH07SSUMrSSUM\\PH08SSUMrSSUM\\PH09SSUMrSSUM\\PH0ASSUMrSSUM\\PH0BSSUM\xa0\x0cSSUMp
+\x02PPRC\xa1K\x0ep\x83\x88k
+\x00\x00\\PH04p\x89RQS1\x01\\PH04\x00
+\x00
+\x00`\xa0\x0c\x92\x93`\xffp
+\x01PPRC\xa1M\x0bp
+\x00\\PH03p
+\x00SSUMrSSUM\\PH01SSUMrSSUM\\PH02SSUMrSSUM\\PH03SSUMrSSUM\\PH04SSUMrSSUM\\PH05SSUMrSSUM\\PH06SSUMrSSUM\\PH07SSUMrSSUM\\PH08SSUMrSSUM\\PH09SSUMrSSUM\\PH0ASSUMrSSUM\\PH0BSSUMt
+\x00SSUM\\PH03TPHY
+\x01\xa1\x08p
+\x02PPRC\xa4PPRC\xa0\x1e\x93j
+\x03TPHY
+\x00p\\PH04\x88PTOP
+\x01\x00\xa4PTOP\xa0\x08\x93j
+\x04\xa4
+\x01\xa0I\x08\x93j
+\x05TPHY
+\x00p\\PH07`p\\PH06LRSPp}y`
+\x08`LRSP\x00LRSP\xa0\x1c\x90\x93\\PH06
+\xf0\x93\\PH07
+\xffp\x0c\xf0\xff\xff\xffLRSP\xa1\x1e\xa0\x1c\x90\x93\\PH06
+\xf1\x93\\PH07
+\xffp\x0c\xf1\xff\xff\xffLRSPpLRSP\x88RTOP
+\x02\x00p\\PH05\x88RTOP
+\x01\x00\xa4RTOP\xa0\x08\x93j
+\x06\xa4
+\x02\x08UID1\x11\x13
+\x10\xedT`7\x13\xccuF\x90\x1cGV\xd7\xf2\xd4]\x8aUID1
+\x00EID4\x8aUID1
+\x04EID5\x8aUID1
+\x08EID6\x8aUID1
+\x0cEID7\xa0@\t\x90\x90\x93IID0EID4\x93IID1EID5\x90\x93IID2EID6\x93IID3EID7pj[1pk[1\xa0\x0b\x93j
+\x00\xa4\x11\x04
+\x01\x01\xa0O\x04\x93j
+\x01\xa0\x12\x93\x83\x88k
+\x00\x00
+\x00p
+\x00\\TCG0\xa0\x12\x93\x83\x88k
+\x00\x00
+\x01p
+\x01\\TCG0\xa0\x0f\x93\\TCG0
+\x00TMOR
+\x00\xa0\x0f\x93\\TCG0
+\x01TMOR
+\x01\xa4
+\x00\xa4
+\x01\xa4\x11\x04
+\x01\x00[\x80TSES\x00\x0c\x00\x00\xe8\xff\x0b\x00\x02[\x81F\x08TSES\x01\x00@\x06TSCM\x08\x00@(TCT0\x08TCT1\x08TCT2\x08\x00@\x05TMT0\x08\x00H\x04TMT1\x08\x00H\x04TMT2\x08\x00HzTLD0\x08TLD1\x08TLD2\x08TLDL\x18TLDB\x18TLDS\x10TSB0\x08TSB1\x08TSB2\x08TSBL\x08TSBBH\x04TSBF\x10TSBC\x10\x00@\x1aTSIM\x08[\x81\x0fTSES\x01\x00H.TCTAH\x11[\x81\x0fTSES\x01\x00@\xbaTCTLH\x05[\x81\x0fTSES\x01\x00H\xbfTCTBH\x08\x148TCSZ\x02\xa01\x92\x93TSCM
+\x12\xa0\x0b\x93
+\x01hpiTCZ1\xa1\x1b\xa0\x0b\x93
+\x02hpiTCZ2\xa1\r\xa0\x0b\x93
+\x03hpiTCZ3\x14I\x0cTCST\x02\xa0A\x0c\x92\x93TSCM
+\x12p
+\x00`\xa0\x1e\x93
+\x01h\xa0\x18\x94iTMT0p
+\x04TSIMpiTMT0p
+\x01`\xa1B\x04\xa0\x1e\x93
+\x02h\xa0\x18\x94iTMT1p
+\x04TSIMpiTMT1p
+\x01`\xa1 \xa0\x1e\x93
+\x03h\xa0\x18\x94iTMT2p
+\x04TSIMpiTMT2p
+\x01`\xa0@\x05`p
+\x00TCT2\x08TCTC\x11\x03
+#pTCTATCTCp
+"cp
+\x00a\xa2\x12cp\x83\x88TCTCc\x00brabavcp\x80a\x00bub{b
+\xffapaTCT2p
+\xfeTSIM\x14I\x08TCBS\x04\xa0A\x08\x92\x93TSCM
+\x12\xa0F\x07\x93{h
+\x07\x00
+\x00p
+\x12TSIMphTSBLpiTSBBpjTSBFpkTSBCp
+\x00TSB2\x08TCTD\x11\x03
+#pTCTBTCTDp
+\x10`p
+\x00a\xa2\x12`p\x83\x88TCTD`\x00brabav`p\x80a\x00bub{b
+\xffapaTSB2p
+\xfeTSIM\x14@\x07TSCL\x02\xa0H\x06\x92\x93TSCM
+\x12p
+\x15TSIMrTLDSiTLDSp
+\x00TLD2\x08TLDD\x11\x03
+\x0bpTCTLTLDDp
+
+`p
+\x00a\xa2\x12`p\x83\x88TLDD`\x00brabav`p\x80a\x00bub{b
+\xffapaTLD2p
+\xfeTSIM[\x82\x8e\x00\x02EC__\x08_HID\x0cA\xd0\x0c\t\x08_UID
+\x00\x08_GPE
+\x1c\x14\x13_REG\x02\xa0\x0c\x93h
+\x03pi\\H8DR[\x80ECOR\x03
+\x00\x0b\x00\x01[\x81J+ECOR\x01HDBM\x01\x00\x01\x00\x01HFNE\x01\x00\x01\x00\x01HLDM\x01\x00\x01\x00\x01BTCM\x01\x00\x01\x00\x01\x00\x01HBPR\x01BTPC\x01\x00\x01HDUE\x01\x00\x07\x00\x01HETE\x01\x00\x0eHSPA\x01\x00\x07HSUN\x08HSRP\x08\x00 HLCL\x08\x00\x08HFNS\x02\x00\x06\x00\x04HAAA\x03\x00\x01HAM0\x08HAM1\x08HAM2\x08HAM3\x08HAM4\x08HAM5\x08HAM6\x08HAM7\x08HAM8\x08HAM9\x08HAMA\x08HAMB\x08HAMC\x08HAMD\x08HAME\x08HAMF\x08HT00\x01HT01\x01HT02\x01HT03\x01HT10\x01HT11\x01HT12\x01HT13\x01\x00\x10HANT\x08\x00\x10\x00\x01\x00\x01HANA\x02\x00\x01\x00\x01\x00\x1aHATR\x08HT0H\x08HT0L\x08HT1H\x08HT1L\x08HFSP\x08\x00\x06HMUT\x01\x00\x01HBRV\x08HWPM\x01HWLB\x01HWLO\x01HWDK\x01HWFN\x01HWBT\x01HWRI\x01HWBU\x01HWLU\x01\x00\x07\x00\x07HPLO\x01\x00\x08\x00\x10HB0S\x07HB0A\x01HB1S\x07HB1A\x01HCMU\x01\x00\x02OVRQ\x01DCBD\x01DCWL\x01DCWW\x01HB1I\x01\x00\x01KBLT\x01BTPW\x01BTDT\x01HUBS\x01BDPW\x01BDDT\x01HUBB\x01\x00@\x05\x00\x01BTWK\x01HPLD\x01\x00\x01HPAC\x01BTST\x01\x00\x02HPBU\x01\x00\x01HBID\x04HBCS\x01HPNF\x01\x00\x01GSTS\x01\x00\x02HLBU\x01BDST\x01HCBL\x01\x00)HWAK\x10HMPR\x08HMST\x05\x00\x02HMDN\x01HMAD\x08HMCM\x08\x00@\x10HMBC\x08\x00\x18TMP0\x08TMP1\x08TMP2\x08TMP3\x08TMP4\x08TMP5\x08TMP6\x08TMP7\x08\x00\x08HIID\x08\x00\x08HFNI\x08\x00 HDEC\x08HDEO\x08\x00\x18HDAA\x03HDAB\x03HDAC\x02\x00@\x11HDEN HDEP HDEM\x08HDES\x08\x00@\x07ATMX\x08HWAT\x08\x00H\x11\x00\x04HDDD\x01\x14A\x04_INI\x00\xa0\r\\H8DRp
+\x00HSPA\xa1\x0c\\MBEC
+\x05
+\xfe
+\x00BINI\\/\x06_SB_PCI0LPC_EC__HKEYWGIN\x08_CRS\x11\x15
+\x12G\x01b\x00b\x00\x01\x01G\x01f\x00f\x00\x01\x01y\x00\x14!LED_\x02}hi`\xa0\x0c\\H8DRp`HLCL\xa1\t\\WBEC
+\x0c`\x08BAON
+\x00\x08WBON
+\x00\x14N\x18BEEP\x01\xa0\x0c\x93h
+\x05p
+\x00WBONpWBONb\xa0O\x04BAON\xa0$\x93h
+\x00p
+\x00BAON\xa0\rWBONp
+\x03`p
+\x08a\xa1\tp
+\x00`p
+\x00a\xa1#p
+\xff`p
+\xffa\xa0\x0c\x93h
+\x11p
+\x00WBON\xa0\x0c\x93h
+\x10p
+\x01WBON\xa1G\x04ph`p
+\xffa\xa0\x13\x93h
+\x0fph`p
+\x08ap
+\x01BAON\xa0\x14\x93h
+\x11p
+\x00`p
+\x00ap
+\x00WBON\xa0\x14\x93h
+\x10p
+\x03`p
+\x08ap
+\x01WBON\xa02\x93h
+\x03p
+\x00WBON\xa0%bp
+\x07`\xa0\x1e\x91\x93\\SPS_
+\x03\x93\\SPS_
+\x04p
+\x00bp
+\xff`p
+\xffa\xa0\x14\x93h
+\x07\xa0\x0ebp
+\x00bp
+\xff`p
+\xffa\xa0C\x04\x90\\H8DR\x92\\W98F\xa0\x1a\x90b\x92WBONp
+\x00HSRPp
+\x00HSUN["
+d\xa0\x0c\x92\x93a
+\xffpaHSRP\xa0\x0c\x92\x93`
+\xffp`HSUN\xa1>\xa0\x1e\x90b\x92WBON\\WBEC
+\x07
+\x00\\WBEC
+\x06
+\x00["
+d\xa0\x0e\x92\x93a
+\xff\\WBEC
+\x07a\xa0\x0e\x92\x93`
+\xff\\WBEC
+\x06`\xa0\x05\x93h
+\x03\xa0
+\x93h
+\x07["\x0b\xf4\x01\x14C\tEVNT\x01\xa07\\H8DR\xa0\x18h}HAM7
+\x01HAM7}HAM5
+\x04HAM5\xa1\x17{HAM7
+\xfeHAM7{HAM5
+\xfbHAM5\xa1C\x05\xa0(h\\MBEC
+\x17
+\xff
+\x01\\MBEC
+\x15
+\xff
+\x04\xa0\x0f\\W98F\\WBEC
+\x18
+\xff\xa1\'\\MBEC
+\x17
+\xfe
+\x00\\MBEC
+\x15
+\xfb
+\x00\xa0\x0f\\W98F\\WBEC
+\x18
+\x00\x14K\x07PNST\x01\xa0=\x90hBSTA
+\x02\xa0\x1b\x90\\H8DR\x92\\W98Fp
+\x01HBPRp
+\x01HUBB\xa1\x17\\MBEC
+\x01
+\xff
+ \\MBEC
+;
+\xff
+\x80\xa15\xa0\x1b\x90\\H8DR\x92\\W98Fp
+\x00HBPRp
+\x00HUBB\xa1\x17\\MBEC
+\x01
+\xdf
+\x00\\MBEC
+;
+\x7f
+\x00[\x84I\x07PUBS\x03\x00\x00\x14+_STA\x00\xa0\x0c\\H8DRpHUBS`\xa1\x0c{\\RBEC
+;
+\x10`\xa0\x05`\xa4
+\x01\xa1\x04\xa4
+\x00\x14!_ON_\x00\xa0\r\\H8DRp
+\x01HUBS\xa1\x0c\\MBEC
+;
+\xff
+\x10\x14!_OFF\x00\xa0\r\\H8DRp
+\x00HUBS\xa1\x0c\\MBEC
+;
+\xef
+\x00\x14E\x0fLPMD\x00p
+\x00`p
+\x00ap
+\x00b\xa0B\x06\\H8DR\xa0J\x05HPLO\xa0J\x04HPAC\xa0C\x04\x95HWAT
+Z\xa0\x16\x91\x92HB0A\x95{HB0S
+\x0f\x00
+\x03p
+\x01a\xa0\x16\x91\x92HB1A\x95{HB1S
+\x0f\x00
+\x03p
+\x01b\xa0\x0b\x90abp\\LPST`\xa1\x08p\\LPST`\xa1L\x07\xa0I\x07{\\RBEC
+4
+\x80\x00\xa0B\x06{\\RBEC
+F
+\x10\x00\xa0D\x05\x95\\RBEC
+\xc9
+Zp\\RBEC
+8c\xa0\x14\x91\x92{c
+\x80\x00\x95{c
+\x0f\x00
+\x03p
+\x01ap\\RBEC
+9c\xa0\x14\x91\x92{c
+\x80\x00\x95{c
+\x0f\x00
+\x03p
+\x01b\xa0\x0b\x90abp\\LPST`\xa1\x08p\\LPST`\xa4`[\x01MCPU\x07\x14D\x04_Q10\x00\xa0<\\/\x06_SB_PCI0LPC_EC__HKEYMHKK
+\x01\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x01\x10\x14G\x04_Q11\x00\xa0<\\/\x06_SB_PCI0LPC_EC__HKEYMHKK
+\x02\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x02\x10\xa1\x02\xa3\x14$_Q12\x00\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x03\x10\x14A\x05_Q13\x00\xa0:\\/\x06_SB_PCI0LPC_EC__HKEYDHKC\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x04\x10\xa1\x0e\x86\\._SB_SLPB
+\x80\x14M\x10_Q64\x00\xa0<\\/\x06_SB_PCI0LPC_EC__HKEYMHKK
+\x10\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x05\x10\xa1H\x0c\xa0>\x92{\\/\x06_SB_PCI0LPC_EC__HKEYWGFL
+ \x00\\/\x06_SB_PCI0LPC_EC__HKEYBPWC
+\x01\xa1F\x08\\/\x06_SB_PCI0LPC_EC__HKEYBPWC
+\x00\xa0F\x06\x92\\WVIS\xa0>\x92{\\/\x06_SB_PCI0LPC_EC__HKEYWGFL
+\x02\x00\\/\x06_SB_PCI0LPC_EC__HKEYWPWC
+\x01\xa1\x1e\\/\x06_SB_PCI0LPC_EC__HKEYWPWC
+\x00\x14D\x04_Q65\x00\xa0<\\/\x06_SB_PCI0LPC_EC__HKEYMHKK
+ \\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x06\x10\x14C
+_Q16\x00\xa0\'\\VPDFp
+\x00\\VPDF\xa0\x18VIGD\\/\x04_SB_PCI0VID_VSPD\xa1C\x07\xa0<\\/\x06_SB_PCI0LPC_EC__HKEYMHKK
+@\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x07\x10\xa13\xa0\x18VIGD\\/\x04_SB_PCI0VID_VSWT\xa1\x18\\/\x05_SB_PCI0AGP_VID_VSWT\x14B\x05_Q17\x00\xa0<\\/\x06_SB_PCI0LPC_EC__HKEYMHKK
+\x80\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x08\x10\xa1\r\xa0\x0b\x92\\WNTFVEXP\x14F\x04_Q18\x00\xa0=\\/\x06_SB_PCI0LPC_EC__HKEYMHKK\x0b\x00\x01\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\t\x10\xa3\x14E\x04_Q66\x00\xa0=\\/\x06_SB_PCI0LPC_EC__HKEYMHKK\x0b\x00\x02\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b
+\x10\x14E\x04_Q1A\x00\xa0=\\/\x06_SB_PCI0LPC_EC__HKEYMHKK\x0b\x00\x04\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x0b\x10\x14$_Q1B\x00\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x0c\x10\x14E\x04_Q62\x00\xa0=\\/\x06_SB_PCI0LPC_EC__HKEYMHKK\x0b\x00\x10\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\r\x10\x14E\x04_Q60\x00\xa0=\\/\x06_SB_PCI0LPC_EC__HKEYMHKK\x0b\x00 \\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x0e\x10\x14E\x04_Q61\x00\xa0=\\/\x06_SB_PCI0LPC_EC__HKEYMHKK\x0b\x00@\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x0f\x10\x14N\x04_Q1F\x00\xa0?\\/\x06_SB_PCI0LPC_EC__HKEYMHKK\x0c\x00\x00\x02\x00\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x12\x10\\UCMS
+\x0e\x14G\x04_Q67\x00\xa0?\\/\x06_SB_PCI0LPC_EC__HKEYMHKK\x0c\x00\x00\x04\x00\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x13\x10\x14O\x0e_Q26\x00\\UCMS
+\x12DSPD
+\x00["\x0b\xf4\x01\x86AC__
+\x80\x86\\._TZ_THM0
+\x80\x86\\._TZ_THM1
+\x80\xa0\x0e\\WXPF[#MCPU\xff\xff\xa07\\SPEN\xa0\'\\OSPX\x86\\._PR_CPU0
+\x80\xa0\x13\\MPEN\x86\\._PR_CPU1
+\x80\xa1\x08\\STEP
+\x00\xa0
+\\WXPF["
+d\xa0\'\\OSC4\x86\\._PR_CPU0
+\x81\xa0\x13\\MPEN\x86\\._PR_CPU1
+\x81\xa0\x0c\\WXPF[\'MCPU\xa0#\x90\x92\\WXPF\\WNTFp
+\x00\\/\x04_SB_PCI0LPC_C4C3ATMCDSPD
+\x01\x14K\x12_Q27\x00\\UCMS
+\x12["\x0b\xf4\x01\x86AC__
+\x80\x86\\._TZ_THM0
+\x80\x86\\._TZ_THM1
+\x80\xa0\x0e\\WXPF[#MCPU\xff\xff\xa07\\SPEN\xa0\'\\OSPX\x86\\._PR_CPU0
+\x80\xa0\x13\\MPEN\x86\\._PR_CPU1
+\x80\xa1\x08\\STEP
+\x01\xa0
+\\WXPF["
+d\xa0\'\\OSC4\x86\\._PR_CPU0
+\x81\xa0\x13\\MPEN\x86\\._PR_CPU1
+\x81\xa0\x0c\\WXPF[\'MCPU\xa01\x90\\CWAC\x92\\CWAS\xa0#\x90\x92\\WXPF\\WNTFp
+\x01\\/\x04_SB_PCI0LPC_C4C3ATMC\xa09\x91\x93\\/\x03_SB_GDCKGDID\x0c$M\x00L\x93\\/\x03_SB_GDCKGDID\x0c$M\x00D\x86\\._SB_GDCK
+\x01\x14H\x06_Q2A\x00\xa0\x1aVIGD\\/\x04_SB_PCI0VID_VLOC
+\x01\xa1\x1a\\/\x05_SB_PCI0AGP_VID_VLOC
+\x01\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x02P\x86\\._SB_LID_
+\x80\x148_Q2B\x00\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x01P\\UCMS
+\r\x86\\._SB_LID_
+\x80\x14\x06_Q3D\x00\x14>_Q48\x00\xa07\\SPEN\xa0\'\\OSPX\x86\\._PR_CPU0
+\x80\xa0\x13\\MPEN\x86\\._PR_CPU1
+\x80\xa1\x08\\STEP
+\x04\x14>_Q49\x00\xa07\\SPEN\xa0\'\\OSPX\x86\\._PR_CPU0
+\x80\xa0\x13\\MPEN\x86\\._PR_CPU1
+\x80\xa1\x08\\STEP
+\x05\x14\x10_Q7F\x00[2\x01\x00\x00\x01\x80\x0b+\x03\x14$_Q4E\x00\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x11`\x14$_Q4F\x00\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x12`\x14\x1d_Q75\x00\\/\x05_SB_PCI0LPC_EC__TATR\x14$_Q46\x00\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x12`\x14 _Q22\x00\xa0\x0cHB0A\x86BAT0
+\x80\xa0\x0cHB1A\x86BAT1
+\x80\x14\r_Q4A\x00\x86BAT0
+\x81\x14\r_Q4B\x00\x86BAT0
+\x80\x14
+_Q4C\x00_Q38\x14%_Q4D\x00\xa0\x1e{^.BAT1B1ST^.BAT1XB1S\x00\x86BAT1
+\x80\x14\r_Q24\x00\x86BAT0
+\x80\x14%_Q25\x00\xa0\x1e{^.BAT1B1ST^.BAT1XB1S\x00\x86BAT1
+\x80[\x811ECOR\x01\x00@PSBRC\x10SBFC\x10SBAE\x10SBRS\x10SBAC\x10SBVO\x10SBAF\x10SBBS\x10[\x81\x1aECOR\x01\x00@P\x00\x0fSBCM\x01SBMD\x10SBCC\x10[\x81\'ECOR\x01\x00@PSBDC\x10SBDV\x10SBOM\x10SBSI\x10SBDT\x10SBSN\x10[\x81\x0eECOR\x01\x00@PSBCH [\x81\x0fECOR\x01\x00@PSBMN@\x08[\x81\x0fECOR\x01\x00@PSBDN@\x08[\x01BATM\x07\x14C\x16GBIF\x03[#BATM\xff\xff\xa0C\x12j}h
+\x01HIIDpSBCMg\x7fg
+\x01\x88i
+\x00\x00phHIID\xa0
+gwSBFC
+
+a\xa1\x07pSBFCapa\x88i
+\x02\x00}h
+\x02HIID\xa0
+gwSBDC
+
+`\xa1\x07pSBDC`p`\x88i
+\x01\x00xa
+\x14b\x88i
+\x05\x00\xa0
+gp
+\xc8\x88i
+\x06\x00\xa1!\xa0\x15SBDVx\x0c@\r\x03\x00SBDVb\x88i
+\x06\x00\xa1\tp
+\x00\x88i
+\x06\x00pSBDV\x88i
+\x04\x00pSBSN`\x08SERN\x11\t
+\x06 \x00p
+\x04b\xa2\x15`x`
+
+a`ra
+0\x88SERNb\x00vbpSERN\x88i
+
+\x00}h
+\x06HIIDpSBDN\x88i
+\t\x00}h
+\x04HIID\x08BTYP\x11\x08
+\x05\x00\x00\x00\x00\x00pSBCHBTYPpBTYP\x88i
+\x0b\x00}h
+\x05HIIDpSBMN\x88i
+\x0c\x00\xa1\'p\x0c\xff\xff\xff\xff\x88i
+\x01\x00p
+\x00\x88i
+\x05\x00p
+\x00\x88i
+\x06\x00p\x0c\xff\xff\xff\xff\x88i
+\x02\x00[\'BATM\xa4i\x14J\rGBST\x04[#BATM\xff\xff\xa0
+{i
+ \x00p
+\x02`\xa1\x12\xa0
+{i
+@\x00p
+\x01`\xa1\x05p
+\x00`\xa0\x06{i
+\x0f\x00\xa1\x06}`
+\x04`\xa0\x19\x93{i
+\x0f\x00
+\x0fp
+\x04`p
+\x00ap
+\x00bp
+\x00c\xa1@\x06phHIIDpSBVOc\xa0
+jwSBRC
+
+b\xa1\x07pSBRCbpSBACa\xa0\x1c\x92\x95a\x0b\x00\x80\xa0\x0e{`
+\x01\x00t\x0c\x00\x00\x01\x00aa\xa1\x05p
+\x00a\xa1\r\xa0\x0b\x92{`
+\x02\x00p
+\x00a\xa0\rjwcaaxa\x0b\xe8\x03gap`\x88k
+\x00\x00pa\x88k
+\x01\x00pb\x88k
+\x02\x00pc\x88k
+\x03\x00[\'BATM\xa4k[\x82G\x15BAT0\x08_HID\x0cA\xd0\x0c
+\x08_UID
+\x00\x08_PCL\x12\x07\x01\\_SB_\x08B0ST
+\x00\x08BT0I\x12#\r
+\x00\x0c\xff\xff\xff\xff\x0c\xff\xff\xff\xff
+\x01\x0b0*
+\x00
+\x00
+\x01
+\x01\r\x00\r\x00\r\x00\r\x00\x08BT0P\x12\x02\x04\x14D\x04_STA\x00\xa0\x0f\\H8DRpHB0AB0ST\xa1\x1e\xa0\x13{\\RBEC
+8
+\x80\x00p
+\x01B0ST\xa1\x08p
+\x00B0ST\xa0\x08B0ST\xa4
+\x1f\xa1\x04\xa4
+\x0f\x14G\x04_BIF\x00p
+\x00gp
+
+f\xa2+\x90\x92gf\xa0\x1fHB0A\xa0\x13\x93{HB0S
+\x0f\x00
+\x0f["\x0b\xe8\x03vf\xa1\x05p
+\x01g\xa1\x05p
+\x00f\xa4GBIF
+\x00BT0Ig\x14#_BST\x00\x7f\x83\x88BT0I
+\x00\x00
+\x01`\xa4GBST
+\x00HB0S`BT0P\x14I\x04_BTP\x01{HAM4
+\xefHAM4\xa06hpha\xa0\x11\x92\x83\x88BT0I
+\x00\x00xa
+
+`a{a
+\xffHT0L{za
+\x08\x00
+\xffHT0H}HAM4
+\x10HAM4[\x82A\x18BAT1\x08_HID\x0cA\xd0\x0c
+\x08_UID
+\x01\x08_PCL\x12\x07\x01\\_SB_\x08B1ST
+\x00\x08XB1S
+\x01\x08BT1I\x12#\r
+\x00\x0c\xff\xff\xff\xff\x0c\xff\xff\xff\xff
+\x01\x0b0*
+\x00
+\x00
+\x01
+\x01\r\x00\r\x00\r\x00\r\x00\x08BT1P\x12\x02\x04\x14G\x06_STA\x00\xa0\x0f\\H8DRpHB1AB1ST\xa1\x1e\xa0\x13{\\RBEC
+9
+\x80\x00p
+\x01B1ST\xa1\x08p
+\x00B1ST\xa0\x1fB1ST\xa0\x08XB1S\xa4
+\x1f\xa1\x10\xa0\t\\WNTF\xa4
+\x00\xa1\x04\xa4
+\x1f\xa1\x10\xa0\t\\WNTF\xa4
+\x00\xa1\x04\xa4
+\x0f\x14G\x04_BIF\x00p
+\x00gp
+
+f\xa2+\x90\x92gf\xa0\x1fHB1A\xa0\x13\x93{HB1S
+\x0f\x00
+\x0f["\x0b\xe8\x03vf\xa1\x05p
+\x01g\xa1\x05p
+\x00f\xa4GBIF
+\x10BT1Ig\x14#_BST\x00\x7f\x83\x88BT1I
+\x00\x00
+\x01`\xa4GBST
+\x10HB1S`BT1P\x14I\x04_BTP\x01{HAM4
+\xdfHAM4\xa06hpha\xa0\x11\x92\x83\x88BT1I
+\x00\x00xa
+
+`a{a
+\xffHT1L{za
+\x08\x00
+\xffHT1H}HAM4
+ HAM4[\x82>AC__\x08_HID\rACPI0003\x00\x08_UID
+\x00\x08_PCL\x12\x07\x01\\_SB_\x14\x0b_PSR\x00\xa4HPAC\x14\t_STA\x00\xa4
+\x0f[\x82IQHKEY\x08_HID\x0c$M\x00h\x14\t_STA\x00\xa4
+\x0f\x14
+MHKV\x00\xa4\x0b\x00\x01\x08DHKC
+\x00\x08DHKB
+\x01[\x01XDHK\x07\x08DHKH
+\x00\x08DHKW
+\x00\x08DHKS
+\x00\x08DHKD
+\x00\x08DHKN\x0b\x0c\x08\x08DHKT
+\x00\x08DHWW
+\x00\x14\x0cMHKA\x00\xa4\x0c\xff\xff\xff\x00\x14\x0bMHKN\x00\xa4DHKN\x14\x18MHKK\x01\xa0\rDHKC\xa4{DHKNh\x00\xa1\x03\xa4\x00\x14@\x05MHKM\x02[#XDHK\xff\xff\xa0\x06\x94h
+ \xa3\xa13y\x01vh`\xa0){`\x0c\xff\xff\xff\x00\x00\xa0\x0ci}`DHKNDHKN\xa1\x12{DHKN\x7f`\x0c\xff\xff\xff\xff\x00DHKN\xa1\x02\xa3[\'XDHK\x14\x13MHKS\x00\x86\\._SB_SLPB
+\x80\x14\x0cMHKC\x01phDHKC\x14I\x08MHKP\x00[#XDHK\xff\xff\xa0\x11DHWWpDHWWap\x00DHWW\xa1O\x05\xa0\x11DHKWpDHKWap\x00DHKW\xa1J\x04\xa0\x11DHKDpDHKDap\x00DHKD\xa15\xa0\x11DHKSpDHKSap\x00DHKS\xa1!\xa0\x11DHKTpDHKTap\x00DHKT\xa1\rpDHKHap\x00DHKH[\'XDHK\xa4a\x14>MHKE\x01phDHKB[#XDHK\xff\xffp\x00DHKHp\x00DHKWp\x00DHKSp\x00DHKDp\x00DHKTp\x00DHWW[\'XDHK\x14E\x0bMHKQ\x01\xa0M
+DHKB\xa0@\tDHKC[#XDHK\xff\xff\xa0\x06\x95h\x0b\x00\x10\xa1M\x06\xa0\x0c\x95h\x0b\x00 phDHKH\xa1M\x05\xa0\x0c\x95h\x0b\x000phDHKW\xa1M\x04\xa0\x0c\x95h\x0b\x00@phDHKS\xa1=\xa0\x0c\x95h\x0b\x00PphDHKD\xa1.\xa0\x0c\x95h\x0b\x00`phDHKH\xa1\x1f\xa0\x0c\x95h\x0b\x00pphDHKT\xa1\x10\xa0\x0c\x95h\x0b\x00\x80phDHWW\xa1\x01[\'XDHK\x86HKEY
+\x80\xa1\x15\xa0\x13\x93h\x0b\x04\x10\x86\\._SB_SLPB
+\x80\x14I\x05MHKB\x01\xa0&\x93h
+\x00\\/\x05_SB_PCI0LPC_EC__BEEP
+\x11p
+\x00\\LIDB\xa1*\xa0&\x93h
+\x01\\/\x05_SB_PCI0LPC_EC__BEEP
+\x10p
+\x01\\LIDB\xa1\x01\x14<MHKD\x00\xa0\x1aVIGD\\/\x04_SB_PCI0VID_VLOC
+\x00\xa1\x1a\\/\x05_SB_PCI0AGP_VID_VLOC
+\x00\x14>MHQC\x01\xa01\\WNTF\xa0\x0b\x93h
+\x00\xa4\\CWAC\xa1\x1e\xa0\x0b\x93h
+\x01\xa4\\CWAP\xa1\x10\xa0\x0b\x93h
+\x02\xa4\\CWAT\xa1\x02\xa3\xa1\x02\xa3\xa4
+\x00\x14A\x08MHGC\x00\xa0C\x07\\WNTF[#XDHK\xff\xff\xa0:\\OSC4\xa0 \\/\x06_SB_PCI0LPC_EC__AC___PSRp
+\x03`\xa1\x12\xa0
+\\C4NAp
+\x03`\xa1\x05p
+\x04`\xa1 \xa0\x18\\/\x04_SB_PCI0LPC_C4C3p
+\x04`\xa1\x05p
+\x03`[\'XDHK\xa4`\xa1\x02\xa3\xa4
+\x00\x14A\x13MHSC\x01\xa0F\x12\x90\\CWAC\\WNTF[#XDHK\xff\xff\xa0J\x08\\OSC4\xa0>\x93h
+\x03\xa08\x92\\CWAS\x86\\._PR_CPU0
+\x81\xa0\x13\\MPEN\x86\\._PR_CPU1
+\x81p
+\x01\\CWASp
+\x01\\C4NA\xa1C\x04\xa0=\x93h
+\x04\xa07\\CWAS\x86\\._PR_CPU0
+\x81\xa0\x13\\MPEN\x86\\._PR_CPU1
+\x81p
+\x00\\CWASp
+\x00\\C4NA\xa1\x02\xa3\xa1O\x07\xa0+\x93h
+\x03\xa0%\x92\\CWASp
+\x00\\/\x04_SB_PCI0LPC_C4C3p
+\x01\\CWAS\xa1@\x05\xa0J\x04\x93h
+\x04\xa0C\x04\\CWAS\xa03\x92\\/\x06_SB_PCI0LPC_EC__AC___PSRp
+\x01\\/\x04_SB_PCI0LPC_C4C3p
+\x00\\CWAS\xa1\x02\xa3[\'XDHK\xa1\x02\xa3\x10G\x14\\/\x05_SB_PCI0LPC_EC__HKEY\x14M\x04TDSC\x01p
+\x01`\xa2\x1b`p\\/\x05_SB_PCI0LPC_EC__HANT`ph\\/\x05_SB_PCI0LPC_EC__HANT\xa0\x0c\x93h
+!\\ATCC
+\x00\x14\x0cTDSS\x01\\ATCCh\x14N\x08TDSG\x01{h
+\xff`p`\\/\x05_SB_PCI0LPC_EC__HDAAzh
+\x08`{`
+\xffapa\\/\x05_SB_PCI0LPC_EC__HDABzh
+\x10`{`
+\xffapa\\/\x05_SB_PCI0LPC_EC__HDACzh
+\x18`{`
+\xffapa\\/\x05_SB_PCI0LPC_EC__HANA\x14!TDGC\x00p\\/\x05_SB_PCI0LPC_EC__HDDD`\xa4`\x14!TDGS\x00p\\/\x05_SB_PCI0LPC_EC__HAAA`\xa4`[\x81\x18ECOR\x11\x00@*HSD0\x08HSD1\x08HSD2\x08[\x81\x0eECOR\x11\x00@+HSDL\x10[\x81\x19ECOR\x11\x00@+HSDBH\x04HSDF\x10HSDC\x10[\x01I2CM\x07\x14?CHKS\x00p\x0b\xe8\x03`\xa2\x13HMPR["
+\x01v`\xa0\x07\x92`\xa4\x0b\x80\x80\xa0\x19HMDN\xa0\x0fHMST\xa4}\x0b\x00\x80HMST\x00\xa1\x03\xa4\x00\xa1\x05\xa4\x0b\x81\x80\x14 I2RT\x00p
+\x02HMADp
+!HMCMp
+\x0bHMPR\xa4CHKS\x14&I2NT\x01p
+\x02HMADp
+"HMCMphHSD0p
+\x06HMPR\xa4CHKS\x14K\x0eTATR\x00\xa0C\x0e\\H8DR[#I2CM\xff\xffI2RTpHSD0`\xa0%\x93`
+ \\/\x04_SB_PCI0LPC_TCSZHSD1HSD2I2NT`\xa1M\t\xa0%\x93`
+!\\/\x04_SB_PCI0LPC_TCSTHSD1HSD2I2NT`\xa1D\x07\xa0I\x04\x93`
+"\x08TSDC\x11\x0c
+\t \x00pHSDBTSDC\\/\x04_SB_PCI0LPC_TCBSHSD1TSDCHSDFHSDCI2NT`\xa1\'\xa0%\x93`
+#\\/\x04_SB_PCI0LPC_TSCLHSD1HSDLI2NT`[\'I2CM\x14\rTATE\x00p
+\x01HETE\x08_ADR
+\x00\x08_S3D
+\x02\x08RID_
+\x00\x08LRRT\x12G\x13\x0e\x12\x15\x04\x0c\xff\xff\x01\x00
+\x00\\._SB_LNKA
+\x00\x12\x15\x04\x0c\xff\xff\x02\x00
+\x00\\._SB_LNKA
+\x00\x12\x15\x04\x0c\xff\xff\x1b\x00
+\x01\\._SB_LNKB
+\x00\x12\x15\x04\x0c\xff\xff\x1c\x00
+\x00\\._SB_LNKE
+\x00\x12\x15\x04\x0c\xff\xff\x1c\x00
+\x01\\._SB_LNKF
+\x00\x12\x15\x04\x0c\xff\xff\x1c\x00
+\x02\\._SB_LNKG
+\x00\x12\x15\x04\x0c\xff\xff\x1c\x00
+\x03\\._SB_LNKH
+\x00\x12\x15\x04\x0c\xff\xff\x1d\x00
+\x00\\._SB_LNKA
+\x00\x12\x15\x04\x0c\xff\xff\x1d\x00
+\x01\\._SB_LNKB
+\x00\x12\x15\x04\x0c\xff\xff\x1d\x00
+\x02\\._SB_LNKC
+\x00\x12\x15\x04\x0c\xff\xff\x1d\x00
+\x03\\._SB_LNKD
+\x00\x12\x15\x04\x0c\xff\xff\x1f\x00
+\x00\\._SB_LNKH
+\x00\x12\x15\x04\x0c\xff\xff\x1f\x00
+\x02\\._SB_LNKA
+\x00\x12\x15\x04\x0c\xff\xff\x1f\x00
+\x01\\._SB_LNKA
+\x00\x08ARRT\x12G\x0c\x0e\x12\r\x04\x0c\xff\xff\x01\x00
+\x00
+\x00
+\x10\x12\r\x04\x0c\xff\xff\x02\x00
+\x00
+\x00
+\x10\x12\r\x04\x0c\xff\xff\x1b\x00
+\x01
+\x00
+\x11\x12\r\x04\x0c\xff\xff\x1c\x00
+\x00
+\x00
+\x14\x12\r\x04\x0c\xff\xff\x1c\x00
+\x01
+\x00
+\x15\x12\r\x04\x0c\xff\xff\x1c\x00
+\x02
+\x00
+\x16\x12\r\x04\x0c\xff\xff\x1c\x00
+\x03
+\x00
+\x17\x12\r\x04\x0c\xff\xff\x1d\x00
+\x00
+\x00
+\x10\x12\r\x04\x0c\xff\xff\x1d\x00
+\x01
+\x00
+\x11\x12\r\x04\x0c\xff\xff\x1d\x00
+\x02
+\x00
+\x12\x12\r\x04\x0c\xff\xff\x1d\x00
+\x03
+\x00
+\x13\x12\r\x04\x0c\xff\xff\x1f\x00
+\x00
+\x00
+\x17\x12\r\x04\x0c\xff\xff\x1f\x00
+\x02
+\x00
+\x10\x12\r\x04\x0c\xff\xff\x1f\x00
+\x01
+\x00
+\x10\x14\x19_PRT\x00\xa0\x0b\\GPIC\xa4ARRT\xa1\x06\xa4LRRT\x08_HID\x0cA\xd0
+\x08\x08_CID\x0cA\xd0
+\x03\x08_BBN
+\x00[\x80MHCS\x02
+\x00\x0b\x00\x01[\x815MHCS\x03\x00@HPAM0\x08PAM1\x08PAM2\x08PAM3\x08PAM4\x08PAM5\x08PAM6\x08\x00(\x00\x03TOUD\x05\x08_CRS\x11E\x1c\x0b\xc0\x01\x88\r\x00\x02\x0c\x00\x00\x00\x00\x00\xff\x00\x00\x00\x00\x01G\x01\xf8\x0c\xf8\x0c\x01\x08\x88\r\x00\x01\x0c\x03\x00\x00\x00\x00\xf7\x0c\x00\x00\xf8\x0c\x88\r\x00\x01\x0c\x03\x00\x00\x00\r\xff\xff\x00\x00\x00\xf3\x87\x17\x00\x00\x0c\x03\x00\x00\x00\x00\x00\x00
+\x00\xff\xff\x0b\x00\x00\x00\x00\x00\x00\x00\x02\x00\x87\x17\x00\x00\x0c\x03\x00\x00\x00\x00\x00\x00\x0c\x00\xff?\x0c\x00\x00\x00\x00\x00\x00@\x00\x00\x87\x17\x00\x00\x0c\x03\x00\x00\x00\x00\x00@\x0c\x00\xff\x7f\x0c\x00\x00\x00\x00\x00\x00@\x00\x00\x87\x17\x00\x00\x0c\x03\x00\x00\x00\x00\x00\x80\x0c\x00\xff\xbf\x0c\x00\x00\x00\x00\x00\x00@\x00\x00\x87\x17\x00\x00\x0c\x03\x00\x00\x00\x00\x00\xc0\x0c\x00\xff\xff\x0c\x00\x00\x00\x00\x00\x00@\x00\x00\x87\x17\x00\x00\x0c\x03\x00\x00\x00\x00\x00\x00\r\x00\xff?\r\x00\x00\x00\x00\x00\x00@\x00\x00\x87\x17\x00\x00\x0c\x03\x00\x00\x00\x00\x00@\r\x00\xff\x7f\r\x00\x00\x00\x00\x00\x00@\x00\x00\x87\x17\x00\x00\x0c\x03\x00\x00\x00\x00\x00\x80\r\x00\xff\xbf\r\x00\x00\x00\x00\x00\x00@\x00\x00\x87\x17\x00\x00\x0c\x03\x00\x00\x00\x00\x00\xc0\r\x00\xff\xff\r\x00\x00\x00\x00\x00\x00@\x00\x00\x87\x17\x00\x00\x0c\x03\x00\x00\x00\x00\x00\x00\x0e\x00\xff?\x0e\x00\x00\x00\x00\x00\x00@\x00\x00\x87\x17\x00\x00\x0c\x03\x00\x00\x00\x00\x00@\x0e\x00\xff\x7f\x0e\x00\x00\x00\x00\x00\x00@\x00\x00\x87\x17\x00\x00\x0c\x03\x00\x00\x00\x00\x00\x80\x0e\x00\xff\xbf\x0e\x00\x00\x00\x00\x00\x00@\x00\x00\x87\x17\x00\x00\x0c\x03\x00\x00\x00\x00\x00\xc0\x0e\x00\xff\xff\x0e\x00\x00\x00\x00\x00\x00@\x00\x00\x87\x17\x00\x00\x0c\x03\x00\x00\x00\x00\x00\x00\x10\x00\xff\xff\xbf\xfe\x00\x00\x00\x00\x00\x00\xb0\xfe\x87\x17\x00\x00\x0c\x03\x00\x00\x00\x00\x00\x00\xd4\xfe\xff\x0f\xd4\xfe\x00\x00\x00\x00\x00\x10\x00\x00y\x00\x8a_CRS
+hC0LN\x8a_CRS
+\x82C4LN\x8a_CRS
+\x9cC8LN\x8a_CRS
+\xb6CCLN\x8a_CRS
+\xd0D0LN\x8a_CRS
+\xeaD4LN\x8a_CRS\x0b\x04\x01D8LN\x8a_CRS\x0b\x1e\x01DCLN\x8a_CRS\x0b8\x01E0LN\x8a_CRS\x0bR\x01E4LN\x8a_CRS\x0bl\x01E8LN\x8a_CRS\x0b\x86\x01ECLN\x8a_CRS\x0b\x94\x01XXMN\x8a_CRS\x0b\x98\x01XXMX\x8a_CRS\x0b\xa0\x01XXLN\x8a_CRS\x0b\xae\x01F4MN\x8a_CRS\x0b\xb2\x01F4MX\x8a_CRS\x0b\xba\x01F4LN\x14A\x12_INI\x08\xa0\x11\x92\\OSIF\\._SB__INIyTOUD
+\x1b`p`\\MEMXp`XXMNrtXXMXXXMN\x00
+\x01XXLN\xa0\x15\x92\x93{\\TPMP
+\x01\x00
+\x01p
+\x00F4LN\xa0\x10{PAM1
+\x03\x00p
+\x00C0LN\xa0\x10{PAM1
+0\x00p
+\x00C4LN\xa0\x10{PAM2
+\x03\x00p
+\x00C8LN\xa0\x10{PAM2
+0\x00p
+\x00CCLN\xa0\x10{PAM3
+\x03\x00p
+\x00D0LN\xa0\x10{PAM3
+0\x00p
+\x00D4LN\xa0\x10{PAM4
+\x03\x00p
+\x00D8LN\xa0\x10{PAM4
+0\x00p
+\x00DCLN\xa0\x10{PAM5
+\x03\x00p
+\x00E0LN\xa0\x10{PAM5
+0\x00p
+\x00E4LN\xa0\x10{PAM6
+\x03\x00p
+\x00E8LN\xa0\x10{PAM6
+0\x00p
+\x00ECLN\x08SUPP
+\x00\x08CTRL
+\x00\x14E,_OSC\x04\x8ak
+\x00CDW1\x8ak
+\x04CDW2\x8ak
+\x08CDW3\x8ah
+\x00IID0\x8ah
+\x04IID1\x8ah
+\x08IID2\x8ah
+\x0cIID3\x08UID0\x11\x13
+\x10[M\xdb3\xf7\x1f\x1c@\x96WtA\xc0=\xd7f\x8aUID0
+\x00EID0\x8aUID0
+\x04EID1\x8aUID0
+\x08EID2\x8aUID0
+\x0cEID3\xa0A#\x90\x90\x93IID0EID0\x93IID1EID1\x90\x93IID2EID2\x93IID3EID3pCDW2SUPPpCDW3CTRL{CTRL
+\x1dCTRL\xa0H\x1b\x80{CDW1
+\x01\x00\x00\xa0F\x0f{CTRL
+\x01\x00\xa03\x92\\VIGDp
+\x00\\/\x04_SB_PCI0AGP_HPGPp
+\x00\\/\x04_SB_PCI0AGP_GMGPp
+\x00\\/\x04_SB_PCI0EXP0HPCEp
+\x01\\/\x04_SB_PCI0EXP0HPCSp
+\x01\\/\x04_SB_PCI0EXP0ABP_p
+\x01\\/\x04_SB_PCI0EXP0PDS_p
+\x00\\/\x04_SB_PCI0EXP2HPCEp
+\x01\\/\x04_SB_PCI0EXP2HPCSp
+\x01\\/\x04_SB_PCI0EXP2ABP_p
+\x01\\/\x04_SB_PCI0EXP2PDS_p
+\x01\\NHPS\xa0D\x0b{CTRL
+\x04\x00\xa03\x92\\VIGDp
+\x00\\/\x04_SB_PCI0AGP_PMGPp
+\x00\\/\x04_SB_PCI0AGP_GMGPp
+\x00\\/\x04_SB_PCI0EXP0PMCEp
+\x01\\/\x04_SB_PCI0EXP0PMCSp
+\x00\\/\x04_SB_PCI0EXP2PMCEp
+\x01\\/\x04_SB_PCI0EXP2PMCSp
+\x00\\/\x04_SB_PCI0LPC_EXPEp
+\x01\\NPME\xa0\x11\x92\x93i
+\x01}CDW1
+
+CDW1\xa0\x16\x92\x93CDW3CTRL}CDW1
+\x10CDW1pCTRLCDW3\xa1\x0c}CDW1
+\x06CDW1\xa4k[\x01MDGS\x07\x08VDEE
+\x01\x08VDDA\x11\x03
+\x02\x8dVDDA
+\x00VUPC\x8dVDDA
+\x01VQDL\x8dVDDA
+\x02VQDC\x8dVDDA
+\x03VQDT\x8dVDDA
+\x04VQDD\x8dVDDA
+\x05VSDL\x8dVDDA
+\x06VSDC\x8dVDDA
+\x07VSDT\x8dVDDA
+\x08VSDD\x8dVDDA
+
+MSWT\x8dVDDA
+\x0bVWST[\x82OJVID_\x08_ADR\x0c\x00\x00\x02\x00\x08RID_
+\x00[\x80VPCG\x02
+\x00\x0b\x00\x01[\x81\x0eVPCG\x03\x00@jVPWR \x08_S3D
+\x03\x145_INI\x00\\VUPS
+\x02p\\VCDLVQDLp\\VCDCVQDCp\\VCDTVQDTp\\VCDDVQDD\x14\x07_PS0\x00\xa3\x14\x07_PS1\x00\xa3\x14\x07_PS2\x00\xa3\x14\x07_PS3\x00\xa3\x140VSWT\x00\xa0\x0f\\WVISp\\VEVT
+\x07`\xa1
+p\\VEVT
+\x05`{
+\x0f`a\xa0\taASWTa
+\x01\x14E\x08VLOC\x01\xa0M\x07\x93h\\/\x03_SB_LID__LID\\VSLDh\xa0C\x06\x93VPWR
+\x00\xa0?hp\\VEVT
+\x01`\xa0\x13\\WXPF\x86\\._SB_PCI0
+\x00\xa1\x1a\xa0\x18\\WNTF\x86\\/\x03_SB_PCI0VID_
+\x00["\x0b\xee\x02\xa1
+p\\VEVT
+\x02`{
+\x0f`a\xa0\taASWTa
+\x00\x14G\x07_DOS\x01\xa0:\x93h
+\x02p
+\x14`\xa20`v`[#MDGS\xff\xff\xa0\x19\x93
+\x00MSWTp
+\x01MSWTp
+\x00`phVDEE[\'MDGS["
+\xc8\xa14[#MDGS\xff\xff\xa0\x0f\x93VDEE
+\x02p
+\x00MSWT\xa0\x0c\x94h
+\x02p
+\x01VDEE\xa1\x07phVDEE[\'MDGS\x14\x13_DOD\x00\xa4\x12\x0b\x03\x0b\x00\x01\x0b\x00\x03\x0b\x00\x04\x14L\x0bASWT\x02\xa0\x14\x93
+\x01VDEE{
+\x01ia\\VSDSha\xa1O\tp
+\x14`\xa2A\x08`v`[#MDGS\xff\xff\xa0I\x06\x93
+\x00MSWTp
+\x00`\xa0\r{
+\x01i\x00p
+\x01VUPC\xa1\x08p
+\x00VUPC\xa0\r{
+\x01h\x00p
+\x01VQDL\xa1\x08p
+\x00VQDL\xa0\r{
+\x02h\x00p
+\x01VQDC\xa1\x08p
+\x00VQDC\xa0\r{
+\x08h\x00p
+\x01VQDD\xa1\x08p
+\x00VQDD[\'MDGS["
+\xc8\xa0\r{
+\x02i\x00\x86VID_
+\x81\xa1\x08\x86VID_
+\x80\x14I\x06VDSW\x01\xa0A\x06\x93VPWR
+\x00\xa0D\x04hp\\VEVT
+\x03`\xa0\x15\\WVIS{
+\x0f`a\xa0\taASWTa
+\x00\xa1!\xa0\x07\\WXPF\xa3\xa1\x17\xa0\x15\\WNTF{
+\x0f`a\xa0\taASWTa
+\x00\xa1\x12p\\VEVT
+\x04`ASWT
+\x01
+\x00\x14\x1eVSPD\x00p\\VEVT
+\x06`{
+\x0f`a\xa0\taASWTa
+\x01[\x82H\x06LCD0\x08_ADR\x0b\x00\x04\x14\x1c_DCS\x00\\VUPS
+\x00\xa0\t\\VCDL\xa4
+\x1f\xa1\x04\xa4
+\x1d\x14\x0b_DGS\x00\xa4VQDL\x140_DSS\x01{h
+\x01VSDL\xa0!{h\x0c\x00\x00\x00\x80\x00\xa0\x0f{h\x0c\x00\x00\x00@\x00DSWT
+\x02\xa1\x07DSWT
+\x01[\x82@\x08CRT0\x08_ADR\x0b\x00\x01\x144_DCS\x00\\VUPS
+\x01\xa0\x15\\VCSS\xa0\t\\VCDC\xa4
+\x1f\xa1\x04\xa4
+\x1d\xa1\x10\xa0\t\\VCDC\xa4
+\x0f\xa1\x04\xa4
+\r\x14\x0b_DGS\x00\xa4VQDC\x140_DSS\x01{h
+\x01VSDC\xa0!{h\x0c\x00\x00\x00\x80\x00\xa0\x0f{h\x0c\x00\x00\x00@\x00DSWT
+\x02\xa1\x07DSWT
+\x01[\x82H\x06DVI0\x08_ADR\x0b\x00\x03\x14\x1c_DCS\x00\\VUPS
+\x00\xa0\t\\VCDD\xa4
+\x1f\xa1\x04\xa4
+\x1d\x14\x0b_DGS\x00\xa4VQDD\x140_DSS\x01{h
+\x01VSDD\xa0!{h\x0c\x00\x00\x00\x80\x00\xa0\x0f{h\x0c\x00\x00\x00@\x00DSWT
+\x02\xa1\x07DSWT
+\x01\x14?DSWT\x01\xa0\tVSDLp
+\x01`\xa1\x05p
+\x00`\xa0
+VSDC}
+\x02``\xa0
+VSDD}
+\x08``\xa0\x0f`\xa0\x0cVUPC\\VSDS`h\xa1\x02\xa3[\x82BUAGP_\x08_ADR\x0c\x00\x00\x01\x00\x08_S3D
+\x03\x08RID_
+\x00\x08LART\x12*\x02\x12\x13\x04\x0b\xff\xff
+\x00\\._SB_LNKA
+\x00\x12\x13\x04\x0b\xff\xff
+\x01\\._SB_LNKB
+\x00\x08AART\x12\x1a\x02\x12\x0b\x04\x0b\xff\xff
+\x00
+\x00
+\x10\x12\x0b\x04\x0b\xff\xff
+\x01
+\x00
+\x11\x14\x19_PRT\x00\xa0\x0b\\GPIC\xa4AART\xa1\x06\xa4LART[\x01MDGS\x07\x08VDEE
+\x01\x08VDDA\x11\x03
+\x02\x8dVDDA
+\x00VUPC\x8dVDDA
+\x01VQDL\x8dVDDA
+\x02VQDC\x8dVDDA
+\x03VQDT\x8dVDDA
+\x04VQDD\x8dVDDA
+\x05VSDL\x8dVDDA
+\x06VSDC\x8dVDDA
+\x07VSDT\x8dVDDA
+\x08VSDD\x8dVDDA
+
+MSWT\x8dVDDA
+\x0bVWST[\x82BAVID_\x08_ADR
+\x00[\x80VPCG\x02
+\x00\x0b\x00\x01[\x81\x0eVPCG\x03\x00@*VPWR \x08_S3D
+\x03\x145_INI\x00\\VUPS
+\x02p\\VCDLVQDLp\\VCDCVQDCp\\VCDTVQDTp\\VCDDVQDD\x14\x07_PS0\x00\xa3\x14\x07_PS1\x00\xa3\x14\x07_PS2\x00\xa3\x14\x07_PS3\x00\xa3\x140VSWT\x00\xa0\x0f\\WVISp\\VEVT
+\x07`\xa1
+p\\VEVT
+\x05`{
+\x0f`a\xa0\taASWTa
+\x01\x14@\x05VLOC\x01\xa0H\x04\x93h\\/\x03_SB_LID__LID\\VSLDh\xa0.\x93VPWR
+\x00\xa0\x0bhp\\VEVT
+\x01`\xa1
+p\\VEVT
+\x02`{
+\x0f`a\xa0\taASWTa
+\x00\x14G\x07_DOS\x01\xa0:\x93h
+\x02p
+\x14`\xa20`v`[#MDGS\xff\xff\xa0\x19\x93
+\x00MSWTp
+\x01MSWTp
+\x00`phVDEE[\'MDGS["
+\xc8\xa14[#MDGS\xff\xff\xa0\x0f\x93VDEE
+\x02p
+\x00MSWT\xa0\x0c\x94h
+\x02p
+\x01VDEE\xa1\x07phVDEE[\'MDGS\x14\x13_DOD\x00\xa4\x12\x0b\x03\x0b\x00\x01\x0b\x10\x02\x0b\x10\x01\x14L\x0bASWT\x02\xa0\x14\x93
+\x01VDEE{
+\x01ia\\VSDSha\xa1O\tp
+\x14`\xa2A\x08`v`[#MDGS\xff\xff\xa0I\x06\x93
+\x00MSWTp
+\x00`\xa0\r{
+\x01i\x00p
+\x01VUPC\xa1\x08p
+\x00VUPC\xa0\r{
+\x01h\x00p
+\x01VQDL\xa1\x08p
+\x00VQDL\xa0\r{
+\x02h\x00p
+\x01VQDC\xa1\x08p
+\x00VQDC\xa0\r{
+\x08h\x00p
+\x01VQDD\xa1\x08p
+\x00VQDD[\'MDGS["
+\xc8\xa0\r{
+\x02i\x00\x86VID_
+\x81\xa1\x08\x86VID_
+\x80[\x82C\tLCD0\x08_ADR\x0b\x10\x01\x14\x1c_DCS\x00\\VUPS
+\x00\xa0\t\\VCDL\xa4
+\x1f\xa1\x04\xa4
+\x1d\x14*_DDC\x01\\VDDC\xa0\x0b\x93h
+\x01\xa4\\DDC1\xa1\x12\xa0\x0b\x93h
+\x02\xa4\\DDC2\xa1\x04\xa4
+\x00\x14\x0b_DGS\x00\xa4VQDL\x140_DSS\x01{h
+\x01VSDL\xa0!{h\x0c\x00\x00\x00\x80\x00\xa0\x0f{h\x0c\x00\x00\x00@\x00DSWT
+\x02\xa1\x07DSWT
+\x01[\x82@\x08CRT0\x08_ADR\x0b\x00\x01\x144_DCS\x00\\VUPS
+\x01\xa0\x15\\VCSS\xa0\t\\VCDC\xa4
+\x1f\xa1\x04\xa4
+\x1d\xa1\x10\xa0\t\\VCDC\xa4
+\x0f\xa1\x04\xa4
+\r\x14\x0b_DGS\x00\xa4VQDC\x140_DSS\x01{h
+\x01VSDC\xa0!{h\x0c\x00\x00\x00\x80\x00\xa0\x0f{h\x0c\x00\x00\x00@\x00DSWT
+\x02\xa1\x07DSWT
+\x01[\x82H\x06DVI0\x08_ADR\x0b\x10\x02\x14\x1c_DCS\x00\\VUPS
+\x00\xa0\t\\VCDD\xa4
+\x1f\xa1\x04\xa4
+\x1d\x14\x0b_DGS\x00\xa4VQDD\x140_DSS\x01{h
+\x01VSDD\xa0!{h\x0c\x00\x00\x00\x80\x00\xa0\x0f{h\x0c\x00\x00\x00@\x00DSWT
+\x02\xa1\x07DSWT
+\x01\x14?DSWT\x01\xa0\tVSDLp
+\x01`\xa1\x05p
+\x00`\xa0
+VSDC}
+\x02``\xa0
+VSDD}
+\x08``\xa0\x0f`\xa0\x0cVUPC\\VSDS`h\xa1\x02\xa3[\x80PEGC\x02
+\x00\x0b\x00\x01[\x81\x18PEGC\x03\x00@vGMGP\x01HPGP\x01PMGP\x01[\x82I\x12EXP0\x08_ADR\x0c\x00\x00\x1c\x00\x08RID_
+\x00[\x80P0CS\x02
+\x00\x0b\x00\x01[\x81M\x04P0CS\x03\x00@-ABP_\x01\x00\x02PDC_\x01\x00\x02PDS_\x01\x00\x01\x00(RID0\x10PSP0\x01PPP0\x01\x00F<\x00\x06HPCE\x01PMCE\x01\x00\x18\x00\x06HPCS\x01PMCS\x01\x08_PRW\x12\x06\x02
+\t
+\x04\x08LPRT\x12C\x05\x04\x12\x13\x04\x0b\xff\xff
+\x00\\._SB_LNKA
+\x00\x12\x13\x04\x0b\xff\xff
+\x01\\._SB_LNKB
+\x00\x12\x13\x04\x0b\xff\xff
+\x02\\._SB_LNKC
+\x00\x12\x13\x04\x0b\xff\xff
+\x03\\._SB_LNKD
+\x00\x08APRT\x122\x04\x12\x0b\x04\x0b\xff\xff
+\x00
+\x00
+\x10\x12\x0b\x04\x0b\xff\xff
+\x01
+\x00
+\x11\x12\x0b\x04\x0b\xff\xff
+\x02
+\x00
+\x12\x12\x0b\x04\x0b\xff\xff
+\x03
+\x00
+\x13\x14\x19_PRT\x00\xa0\x0b\\GPIC\xa4APRT\xa1\x06\xa4LPRT[\x82D\x0fEXP1\x08_ADR\x0c\x01\x00\x1c\x00\x08RID_
+\x00[\x80P1CS\x02
+\x00\x0b\x00\x01[\x81\x18P1CS\x03\x00@0RID1\x10PSP1\x01PPP1\x01\x08_PRW\x12\x06\x02
+\t
+\x04\x08LPRT\x12C\x05\x04\x12\x13\x04\x0b\xff\xff
+\x00\\._SB_LNKB
+\x00\x12\x13\x04\x0b\xff\xff
+\x01\\._SB_LNKC
+\x00\x12\x13\x04\x0b\xff\xff
+\x02\\._SB_LNKD
+\x00\x12\x13\x04\x0b\xff\xff
+\x03\\._SB_LNKA
+\x00\x08APRT\x122\x04\x12\x0b\x04\x0b\xff\xff
+\x00
+\x00
+\x11\x12\x0b\x04\x0b\xff\xff
+\x01
+\x00
+\x12\x12\x0b\x04\x0b\xff\xff
+\x02
+\x00
+\x13\x12\x0b\x04\x0b\xff\xff
+\x03
+\x00
+\x10\x14\x19_PRT\x00\xa0\x0b\\GPIC\xa4APRT\xa1\x06\xa4LPRT[\x82H\x14EXP2\x08_ADR\x0c\x02\x00\x1c\x00\x08RID_
+\x00\x08XCPF
+\x00[\x80P2CS\x02
+\x00\x0b\x00\x01[\x81M\x04P2CS\x03\x00@-ABP_\x01\x00\x02PDC_\x01\x00\x02PDS_\x01\x00\x01\x00(RID2\x10PSP2\x01PPP2\x01\x00F<\x00\x06HPCE\x01PMCE\x01\x00\x18\x00\x06HPCS\x01PMCS\x01\x08_PRW\x12\x06\x02
+\t
+\x04\x08LPRT\x12C\x05\x04\x12\x13\x04\x0b\xff\xff
+\x00\\._SB_LNKC
+\x00\x12\x13\x04\x0b\xff\xff
+\x01\\._SB_LNKD
+\x00\x12\x13\x04\x0b\xff\xff
+\x02\\._SB_LNKA
+\x00\x12\x13\x04\x0b\xff\xff
+\x03\\._SB_LNKB
+\x00\x08APRT\x122\x04\x12\x0b\x04\x0b\xff\xff
+\x00
+\x00
+\x12\x12\x0b\x04\x0b\xff\xff
+\x01
+\x00
+\x13\x12\x0b\x04\x0b\xff\xff
+\x02
+\x00
+\x10\x12\x0b\x04\x0b\xff\xff
+\x03
+\x00
+\x11\x14\x19_PRT\x00\xa0\x0b\\GPIC\xa4APRT\xa1\x06\xa4LPRT[\x82\x16EXUP\x08_ADR
+\x00\x14\t_RMV\x00\xa4
+\x01[\x82B\x10EXP3\x08_ADR\x0c\x03\x00\x1c\x00\x08RID_
+\x00[\x80P3CS\x02
+\x00\x0b\x00\x01[\x81\x18P3CS\x03\x00@0RID3\x10PSP3\x01PPP3\x01\x08_PRW\x12\x06\x02
+\t
+\x04\x08LPRT\x12C\x05\x04\x12\x13\x04\x0b\xff\xff
+\x00\\._SB_LNKD
+\x00\x12\x13\x04\x0b\xff\xff
+\x01\\._SB_LNKA
+\x00\x12\x13\x04\x0b\xff\xff
+\x02\\._SB_LNKB
+\x00\x12\x13\x04\x0b\xff\xff
+\x03\\._SB_LNKC
+\x00\x08APRT\x122\x04\x12\x0b\x04\x0b\xff\xff
+\x00
+\x00
+\x13\x12\x0b\x04\x0b\xff\xff
+\x01
+\x00
+\x10\x12\x0b\x04\x0b\xff\xff
+\x02
+\x00
+\x11\x12\x0b\x04\x0b\xff\xff
+\x03
+\x00
+\x12\x14\x19_PRT\x00\xa0\x0b\\GPIC\xa4APRT\xa1\x06\xa4LPRT[\x82\x0cEXPD\x08_ADR
+\x00[\x82O\x16PCI1\x08_ADR\x0c\x00\x00\x1e\x00\x08_S3D
+\x02\x08RID_
+\x00\x08LPRT\x12G\t\x07\x12\x13\x04\x0b\xff\xff
+\x00\\._SB_LNKA
+\x00\x12\x13\x04\x0b\xff\xff
+\x01\\._SB_LNKB
+\x00\x12\x13\x04\x0b\xff\xff
+\x02\\._SB_LNKC
+\x00\x12\x15\x04\x0c\xff\xff\x01\x00
+\x00\\._SB_LNKA
+\x00\x12\x15\x04\x0c\xff\xff\x02\x00
+\x00\\._SB_LNKF
+\x00\x12\x15\x04\x0c\xff\xff\x02\x00
+\x01\\._SB_LNKG
+\x00\x12\x15\x04\x0c\xff\xff\x08\x00
+\x00\\._SB_LNKE
+\x00\x08APRT\x12O\x05\x07\x12\x0b\x04\x0b\xff\xff
+\x00
+\x00
+\x10\x12\x0b\x04\x0b\xff\xff
+\x01
+\x00
+\x11\x12\x0b\x04\x0b\xff\xff
+\x02
+\x00
+\x12\x12\r\x04\x0c\xff\xff\x01\x00
+\x00
+\x00
+\x10\x12\r\x04\x0c\xff\xff\x02\x00
+\x00
+\x00
+\x15\x12\r\x04\x0c\xff\xff\x02\x00
+\x01
+\x00
+\x16\x12\r\x04\x0c\xff\xff\x08\x00
+\x00
+\x00
+\x14\x14\x19_PRT\x00\xa0\x0b\\GPIC\xa4APRT\xa1\x06\xa4LPRT\x08_PRW\x12\x06\x02
+\x0b
+\x04[\x82\'CDBS\x08_ADR
+\x00\x14\x13_S3D\x00\xa0\t\\WMEF\xa4
+\x02\xa4
+\x03\x08_SUN
+\x01[\x82L\xb8IDE0\x08_ADR\x0c\x01\x00\x1f\x00\x08_S3D
+\x03\x08RID_
+\x00[\x80IDCS\x02
+\x00\x0b\x00\x01[\x81@\x12IDCS\x03\x00@ PFT0\x01PIE0\x01PPE0\x01PDT0\x01PFT1\x01PIE1\x01PPE1\x01PDT1\x01PRC0\x02\x00\x02PIS0\x02PSIE\x01PIDE\x01SFT0\x01SIE0\x01SPE0\x01SDT0\x01SFT1\x01SIE1\x01SPE1\x01SDT1\x01SRC0\x02\x00\x02SIS0\x02SSIE\x01SIDE\x01PRC1\x02PIS1\x02SRC1\x02SIS1\x02\x00\x18PSD0\x01PSD1\x01SSD0\x01SSD1\x01\x00\x0cPCT0\x02\x00\x02PCT1\x02\x00\x02SCT0\x02\x00\x02SCT1\x02\x00\x02\x00@\x04PCB0\x01PCB1\x01SCB0\x01SCB1\x01PCR0\x01PCR1\x01SCR0\x01SCR1\x01\x00\x02WRPP\x01\x00\x01FPB0\x01FPB1\x01FSB0\x01FSB1\x01PSIG\x02SSIG\x02[\x81\x1fIDCS\x03\x00@ PTI0\x04PTI1\x04\x00\x08STI0\x04STI1\x04\x14\'GPCT\x04\xa0\t\x92}hi\x00\xa4
+\x00\xa0\t\x90\x92hi\xa4\x0b\x84\x03\xa4wt
+\trjk\x00\x00
+\x1e\x00\x14*GDCT\x04\xa0\x06\x92h\xa4
+\x00\xa0\x05i\xa4
+\x14\xa0\x0cj\xa4wt
+\x04k\x00
+\x0f\x00\xa4wt
+\x04k\x00
+\x1e\x00\x142MTIM\x02p
+\x00`\xa0\x07h}`
+\x01`\xa0\x0b\x92\x95h
+\x02}`
+\x02`\xa0\x08\x92i}`
+\x04`\xa0\x08\x92h}`
+\x08`\xa4`\x14\x1aMISP\x01\xa0\x06\x92h\xa4
+\x00\xa0\t\x92\x94h
+\x02\xa4
+\x01\xa4
+\x02\x14\x1cMRCT\x01\xa0\t\x92\x94h
+\x02\xa4
+\x00\xa0\x08\x93h
+\x03\xa4
+\x01\xa4
+\x03[\x82O\x95PRIM\x08_ADR
+\x00\x08BGTM\x11\x03
+\x14\x8aBGTM
+\x00GTP0\x8aBGTM
+\x04GTD0\x8aBGTM
+\x08GTP1\x8aBGTM
+\x0cGTD1\x8aBGTM
+\x10GTMF\x08BPI0
+\x00\x08BDM0
+\x00\x08BPI1
+\x00\x08BDM1
+\x00\x08DRE0
+\x00\x08DRE1
+\x00\x08DIP0
+\x00\x08DIP1
+\x00\x14M\x11_GTM\x00pGPCTPFT0PDT0PIS0PRC0GTP0pGDCTPSD0FPB0PCB0PCT0GTD0\xa0\x0f\x92GTD0pGTP0GTD0\xa0H\x04PSIEpGPCTPFT1PDT1PIS1PRC1GTP1pGDCTPSD1FPB1PCB1PCT1GTD1\xa0\x0f\x92GTD1pGTP1GTD1\xa1\x0fp
+\x00GTP1p
+\x00GTD1p
+\x00GTMF\xa0\x10PSD0}GTMF
+\x01GTMF\xa0\x1f\x92GTP0}GTMF
+\x01GTMFp
+xGTP0p
+\x14GTD0\xa0\x10PIE0}GTMF
+\x02GTMF\xa0\x10PSD1}GTMF
+\x04GTMF\xa0\x10PIE1}GTMF
+\x08GTMF}GTMF
+\x10GTMF\xa4BGTM\x14@G_STM\x03\x8ah
+\x00STP0\x8ah
+\x04STD0\x8ah
+\x08STP1\x8ah
+\x0cSTD1\x8ah
+\x10STMFp
+\x00DRE0p
+\x00DIP0\xa0G$\x93\x87i\x0b\x00\x02\x8bi
+\x00M000\x8bi
+bM049\x8bi
+fM051\x8bi
+jM053\x8bi
+|M062\x8bi
+~M063\x8bi
+\x80M064\x8bi
+\x82M065\x8bi
+\x88M068\x8bi
+\x9cM078\x8bi
+\xacM086\x8bi
+\xb0M088\x8bi
+\xeeM119\x8bi\x0b(\x01M148\xa0\x1f\x93{M148\x0b\x00\xc0\x00\x0b\x00@\xa0\x10{M148
+\x04\x00p
+\x01DRE0\xa0\x1b{M086\x0b\x00\x80\x00\xa0\x10{M119
+\x01\x00p
+\x01DRE0\xa0E\t\\W98Fp\\UUDMM053M088STD0\xa0\x10STD0}STMF
+\x01STMF\xa1\x0c{STMF
+\xfeSTMFp\\UMDMM053M063M062M065STP0\xa0 \x92STP0p\\UPIOM053M064M051M068STP0\xa0\x15{M049\x0b\x00\x08\x00}STMF
+\x02STMF\xa1\x0c{STMF
+\xfdSTMFp\\DPIOSTP0{STMF
+\x02\x00`p\\DUDMSTD0{STMF
+\x01\x00a\xa0&\x92\x95\\/\x05_SB_PCI0LPC_EC__BGID
+\x00
+\x0cp
+\x00`p
+\xffapMTIM`{M000\x0b\x00\x80\x00PTI0pMISP`PIS0pMRCT`PRC0\xa0\x0c\x93a
+\xffp
+\x00PSD0\xa1C\x06p
+\x01PSD0\xa0\x0c\x92\x94a
+\x02paPCT0\xa1\x18\xa0\r{a
+\x01\x00p
+\x01PCT0\xa1\x08p
+\x02PCT0\xa0\r\x92\x95a
+\x03p
+\x01PCB0\xa1\x08p
+\x00PCB0\xa0\x0c\x93a
+\x05p
+\x01FPB0\xa1\x08p
+\x00FPB0p
+\x01PCR0p\\FDMA`aBDM0p\\FPIO`BPI0\xa0J\x1e\x93\x87j\x0b\x00\x02\x8bj
+\x00S000\x8bj
+bS049\x8bj
+fS051\x8bj
+jS053\x8bj
+|S062\x8bj
+~S063\x8bj
+\x80S064\x8bj
+\x82S065\x8bj
+\x88S068\x8bj
+\xb0S088\xa0E\t\\W98Fp\\UUDMS053S088STD1\xa0\x10STD1}STMF
+\x04STMF\xa1\x0c{STMF
+\xfbSTMFp\\UMDMS053S063S062S065STP1\xa0 \x92STP1p\\UPIOS053S064S051S068STP1\xa0\x15{S049\x0b\x00\x08\x00}STMF
+\x08STMF\xa1\x0c{STMF
+\xf7STMFp\\DPIOSTP1{STMF
+\x08\x00`p\\DUDMSTD1{STMF
+\x04\x00a\xa0=STP1pMTIM`{S000\x0b\x00\x80\x00PTI1\xa0${STMF
+\x10\x00pMISP`PIS1pMRCT`PRC1p
+\x01PSIE\xa1\x0fp
+\x00PTI1p
+\x00PSIE\xa0\x0c\x93a
+\xffp
+\x00PSD1\xa1C\x06p
+\x01PSD1\xa0\x0c\x92\x94a
+\x02paPCT1\xa1\x18\xa0\r{a
+\x01\x00p
+\x01PCT1\xa1\x08p
+\x02PCT1\xa0\r\x92\x95a
+\x03p
+\x01PCB1\xa1\x08p
+\x00PCB1\xa0\x0c\x93a
+\x05p
+\x01FPB1\xa1\x08p
+\x00FPB1p
+\x01PCR1p\\FDMA`aBDM1p\\FPIO`BPI1[\x82I4MSTR\x08_ADR
+\x00\x08HDTF\x11\x1f
+\x1c\x02\x00\x00\x00\x00\xa0\xef\x00\x00\x00\x00\x00\xa0\xf5\x03\x00\x00\x00\x00\xa0\xef\x03\x00\x00\x00\x00\xa0\xef\x8cHDTF
+\x0fHDMA\x8cHDTF
+\x16HPIO\x8cHDTF
+\rHFLC\x08ERTF\x11&
+#\x02\x00\x00\x00\x00\xa0\xef\x00\x00\x00\x00\x00\xa0\xf5\x03\x00\x00\x00\x00\xa0\xef\x03\x00\x00\x00\x00\xa0\xef_\x00\x00\x00\x00\xa0\xef\x8cERTF
+\x0fEDMA\x8cERTF
+\x16EPIO\x8cERTF
+\rEFLC\x08HPTF\x11&
+#\x02\x00\x00\x00\x00\xa0\xef\x00\x00\x00\x00\x00\xa0\xf5\x03\x00\x00\x00\x00\xa0\xef\x03\x00\x00\x00\x00\xa0\xef\x10\x03\x00\x00\x00\xa0\xef\x8cHPTF
+\x0fPDMA\x8cHPTF
+\x16PPIO\x8cHPTF
+\rPFLC\x08HXTF\x11-
+*\x02\x00\x00\x00\x00\xa0\xef\x00\x00\x00\x00\x00\xa0\xf5\x03\x00\x00\x00\x00\xa0\xef\x03\x00\x00\x00\x00\xa0\xef_\x00\x00\x00\x00\xa0\xef\x10\x03\x00\x00\x00\xa0\xef\x8cHXTF
+\x0fXDMA\x8cHXTF
+\x16XPIO\x8cHXTF
+\rXFLC\x08IDTF\x11\x11
+\x0e\x03\x00\x00\x00\x00\xa0\xef\x03\x00\x00\x00\x00\xa0\xef\x8cIDTF
+\x01IDMA\x8cIDTF
+\x08IPIO\x08DDTF\x11\x1f
+\x1c\x03\x00\x00\x00\x00\xa0\xef\x03\x00\x00\x00\x00\xa0\xef\x00\x00\x00\x00\x00\xa0\xe3\x00\x00\x00\x00\x00\xa0\xe3\x8cDDTF
+\x01DDMA\x8cDDTF
+\x08DPIO\x8cDDTF
+\x0fDTAT\x8cDDTF
+\x16DTFT\x14@\x14_GTF\x00p\\/\x05_SB_PCI0LPC_EC__BGID
+\x00`\xa0"\\OSSSp
+\xe1HFLCp
+\xe1EFLCp
+\xe1PFLCp
+\xe1XFLC\xa0M\x08\x93`
+\x06\xa0H\x04^^DRE0\xa0"^^DIP0p^^BDM0XDMAp^^BPI0XPIO\xa4HXTF\xa1\x1cp^^BDM0EDMAp^^BPI0EPIO\xa4ERTF\xa0"^^DIP0p^^BDM0PDMAp^^BPI0PPIO\xa4HPTFp^^BDM0HDMAp^^BPI0HPIO\xa4HDTFp\x00a\xa0\x08\x93`
+\x03p\x01a\xa0\x08\x93`
+
+p\x01a\xa0\x08\x93`
+\x0bp\x01a\xa01ap\\CDFLDTFTp\\CDAHDTATp^^BDM0DDMAp^^BPI0DPIO\xa4DDTF\xa1\x1cp^^BDM0IDMAp^^BPI0IPIO\xa4IDTF\x14\x1e_EJ0\x01\\/\x05_SB_PCI0LPC_EC__BEJ0h\x14)_STA\x00\xa0\x1d\\/\x05_SB_PCI0LPC_EC__BSTA
+\x01\xa4
+\x0f\xa1\x04\xa4
+\x00[\x82K"SATA\x08_ADR\x0c\x02\x00\x1f\x00\x08_S3D
+\x03\x08RID_
+\x00[\x80IDCS\x02
+\x00\x0b\x00\x01[\x81@\x12IDCS\x03\x00@ PFT0\x01PIE0\x01PPE0\x01PDT0\x01PFT1\x01PIE1\x01PPE1\x01PDT1\x01PRC0\x02\x00\x02PIS0\x02PSIE\x01PIDE\x01SFT0\x01SIE0\x01SPE0\x01SDT0\x01SFT1\x01SIE1\x01SPE1\x01SDT1\x01SRC0\x02\x00\x02SIS0\x02SSIE\x01SIDE\x01PRC1\x02PIS1\x02SRC1\x02SIS1\x02\x00\x18PSD0\x01PSD1\x01SSD0\x01SSD1\x01\x00\x0cPCT0\x02\x00\x02PCT1\x02\x00\x02SCT0\x02\x00\x02SCT1\x02\x00\x02\x00@\x04PCB0\x01PCB1\x01SCB0\x01SCB1\x01PCR0\x01PCR1\x01SCR0\x01SCR1\x01\x00\x02WRPP\x01\x00\x01FPB0\x01FPB1\x01FSB0\x01FSB1\x01PSIG\x02SSIG\x02[\x81\x1fIDCS\x03\x00@ PTI0\x04PTI1\x04\x00\x08STI0\x04STI1\x04\x14\'GPCT\x04\xa0\t\x92}hi\x00\xa4
+\x00\xa0\t\x90\x92hi\xa4\x0b\x84\x03\xa4wt
+\trjk\x00\x00
+\x1e\x00\x14*GDCT\x04\xa0\x06\x92h\xa4
+\x00\xa0\x05i\xa4
+\x14\xa0\x0cj\xa4wt
+\x04k\x00
+\x0f\x00\xa4wt
+\x04k\x00
+\x1e\x00\x142MTIM\x02p
+\x00`\xa0\x07h}`
+\x01`\xa0\x0b\x92\x95h
+\x02}`
+\x02`\xa0\x08\x92i}`
+\x04`\xa0\x08\x92h}`
+\x08`\xa4`\x14\x1aMISP\x01\xa0\x06\x92h\xa4
+\x00\xa0\t\x92\x94h
+\x02\xa4
+\x01\xa4
+\x02\x14\x1cMRCT\x01\xa0\t\x92\x94h
+\x02\xa4
+\x00\xa0\x08\x93h
+\x03\xa4
+\x01\xa4
+\x03[\x82\x1dSMBU\x08_ADR\x0c\x03\x00\x1f\x00\x08_S3D
+\x03\x08RID_
+\x00[\x82J\x0eUSB0\x08_ADR\x0c\x00\x00\x1d\x00\x08_S3D
+\x02\x08RID_
+\x00[\x80U0CS\x02
+\xc4
+\x04[\x81\rU0CS\x03U0EN\x02\x00\x1e\x08_PR0\x12\x19\x01\\/\x05_SB_PCI0LPC_EC__PUBS\x08_PR1\x12\x19\x01\\/\x05_SB_PCI0LPC_EC__PUBS\x08_PR2\x12\x19\x01\\/\x05_SB_PCI0LPC_EC__PUBS\x08_PRW\x12\x1d\x03
+\x03
+\x03\\/\x05_SB_PCI0LPC_EC__PUBS\x141_PSW\x01\xa0\thp
+\x03U0EN\xa1\x08p
+\x00U0EN\\/\x05_SB_PCI0LPC_EC__PNSTh[\x82J\x07USB1\x08_ADR\x0c\x01\x00\x1d\x00\x08_S3D
+\x02\x08RID_
+\x00[\x80U1CS\x02
+\xc4
+\x04[\x81\rU1CS\x03U1EN\x02\x00\x1e\x08_PRW\x12\x06\x02
+\x04
+\x03\x14\x19_PSW\x01\xa0\thp
+\x03U1EN\xa1\x08p
+\x00U1EN[\x82\x1aURTH\x08_ADR
+\x00[\x82\x0cUPEX\x08_ADR
+\x02[\x82N\x0eUSB2\x08_ADR\x0c\x02\x00\x1d\x00\x08_S3D
+\x02\x08RID_
+\x00[\x80U2CS\x02
+\xc4
+\x04[\x81\rU2CS\x03U2EN\x02\x00\x1e\x08_PR0\x12\x19\x01\\/\x05_SB_PCI0LPC_EC__PUBS\x08_PR1\x12\x19\x01\\/\x05_SB_PCI0LPC_EC__PUBS\x08_PR2\x12\x19\x01\\/\x05_SB_PCI0LPC_EC__PUBS\x08_PRW\x12\x1d\x03
+\x0c
+\x03\\/\x05_SB_PCI0LPC_EC__PUBS\x14\x19_PSW\x01\xa0\thp
+\x03U2EN\xa1\x08p
+\x00U2EN[\x82\x1aURTH\x08_ADR
+\x00[\x82\x0cUPDK\x08_ADR
+\x02[\x82\x16USB3\x08_ADR\x0c\x03\x00\x1d\x00\x08RID_
+\x00[\x82N\x0fUSB7\x08_ADR\x0c\x07\x00\x1d\x00\x08_S3D
+\x03\x08RID_
+\x00[\x80U7CS\x02
+`
+\x04[\x81\x14U7CS\x03\x00\x10PWKI\x01PWUC\x06\x00\t\x08_PR0\x12\x19\x01\\/\x05_SB_PCI0LPC_EC__PUBS\x08_PR1\x12\x19\x01\\/\x05_SB_PCI0LPC_EC__PUBS\x08_PR2\x12\x19\x01\\/\x05_SB_PCI0LPC_EC__PUBS\x14\x14_INI\x00p
+\x01PWKIp
+\x0fPWUC\x08_PRW\x12\x1d\x03
+\r
+\x03\\/\x05_SB_PCI0LPC_EC__PUBS[\x82(URTH\x08_ADR
+\x00[\x82\x0cUPDK\x08_ADR
+\x06[\x82\x0cUPEX\x08_ADR
+\x04[\x821HDEF\x08_ADR\x0c\x00\x00\x1b\x00\x08_S3D
+\x03\x08RID_
+\x00\x08_PRW\x12\x06\x02
+\x05
+\x04\x14\x07_PSW\x01\xa3\x10C\xbe\\/\x04_SB_PCI0LPC_EC__\x08BDEV
+\xff\x08BSTS
+\x00\x08BHKE
+\x00\x08BXCN
+\x00\x142_Q2C\x00\xa0+\x93BSTS
+\x00pBGID
+\x00BDEV\xa0\rBXCNNXREBDEV\xa1\tNBREBDEV\x14)_Q2D\x00pBGID
+\x00BDEV\xa0\rBXCNNXRCBDEV\xa1\tNBINBDEV\x14D\x07_Q38\x00pBGID
+\x00`\xa01\x93`
+\x0fBDIS\xa0\x17BXCNpBDEV`p
+\x0fBDEVNXEJ`\xa1\x0fNBEJBDEVp`BDEV\xa12\xa0\x16HPBU\xa0\x10BXCNp`BDEVNXIN`\xa1\x19p`BDEV\xa0
+BXCNNXRC`\xa1\x06NBIN`\x14B\rNBRE\x01\xa0&\x93h
+\r\xa0 \\LFDC\x86\\/\x05_SB_PCI0LPC_FDC_FDD0
+\x03\xa0F\x04\x95h
+\x0c\xa0#\x93\\BIDE
+\x03\x86\\/\x05_SB_PCI0SATASCNDMSTR
+\x03\xa1\x1b\x86\\/\x05_SB_PCI0IDE0PRIMMSTR
+\x03\xa0I\x04\x93h
+\x10\xa0+\x91HPACHB0A\xa0 \\WNTF\x86\\/\x05_SB_PCI0LPC_EC__BAT1
+\x03\xa1\x16LED_
+\x04
+\xc0BEEP
+\x0fp
+\x02BSTS\xa0\x12\x93h
+\x11\x86\\._SB_LCIO
+\x03\x14K\x0eNBEJ\x01\xa0N\x0c\x93BSTS
+\x00\xa0&\x93h
+\r\xa0 \\LFDC\x86\\/\x05_SB_PCI0LPC_FDC_FDD0
+\x01\xa0F\x04\x95h
+\x0c\xa0#\x93\\BIDE
+\x03\x86\\/\x05_SB_PCI0SATASCNDMSTR
+\x01\xa1\x1b\x86\\/\x05_SB_PCI0IDE0PRIMMSTR
+\x01\xa0C\x04\x93h
+\x10\xa0 \\WNTF\x86\\/\x05_SB_PCI0LPC_EC__BAT1
+\x01\xa1\x1b\x86\\/\x05_SB_PCI0LPC_EC__BAT1
+\x81\xa0\x12\x93h
+\x11\x86\\._SB_LCIO
+\x01LED_
+\x04
+\x00BEEP
+\x00p
+\x00BSTS\x14B\x15NBIN\x01\xa08\x93h
+\r\xa02\\LFDCBEN_
+\x00BSFDLED_
+\x04
+\x80\x86\\/\x05_SB_PCI0LPC_FDC_FDD0
+\x01\xa0B\x06\x95h
+\x0c\xa0\x0b\x93h
+\x06BEN_
+\x02\xa1\x07BEN_
+\x01LED_
+\x04
+\x80\xa0#\x93\\BIDE
+\x03\x86\\/\x05_SB_PCI0SATASCNDMSTR
+\x01\xa1\x1b\x86\\/\x05_SB_PCI0IDE0PRIMMSTR
+\x01\xa0I\x06\x93h
+\x10LED_
+\x04
+\x80\xa0>\\WNTFp
+\x01\\/\x06_SB_PCI0LPC_EC__BAT1XB1S\x86\\/\x05_SB_PCI0LPC_EC__BAT1
+\x01\xa1\x1b\x86\\/\x05_SB_PCI0LPC_EC__BAT1
+\x81\xa07\x93h
+\x11\xa01\x92\\/\x04_SB_PCI0LPC_CSONLED_
+\x04
+\x80\xa0\x13\\WNTF\x86\\._SB_LCIO
+\x01BEEP
+\x00p
+\x00BSTS\x14J\x07BEJ0\x01\xa0A\x06hBDISLED_
+\x04
+\x00\\BHDP
+\x01
+\x00p
+\x01BSTS\xa0*BHKEp
+\x00BHKE\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x030\xa0\x16\x93BDEV
+\x11p
+\x0fBDEVp
+\x00BSTS\xa1\x10LED_
+\x04
+\x80p
+\x00BSTS\x14\x1dBEJ3\x01\xa0\rhBDISp
+\x01BSTS\xa1\x08p
+\x00BSTS\x14I\x07BPTS\x01p
+\x01HDBM\xa0\x17\x92\x93BSTS
+\x00p
+\x0fBDEVp
+\x00BSTSp
+\x00BHKEp
+\x01`\xa0\x1d\x92\x93BDEV
+\x0f\xa0\x13\x90\x92\\LFDC\x93BDEV
+\rp
+\x00`\xa1\x05p
+\x00`\xa0
+\x92\x95h
+\x04p
+\x00`\xa0\x08`BUWK
+\x01\xa1\x0fLED_
+\x04
+\x00BUWK
+\x00\x14D\x14BWAK\x01BUWK
+\x00pBGID
+\x00`\xa0\x10\x90\x92\\LFDC\x93`
+\rBDIS\\/\x05_SB_PCI0LPC_FDC__INI\xa0K\x05\\LFDC\xa0C\x05\x92\x93`
+\r\xa0K\x04\x93\\/\x05_SB_PCI0LPC_FDC_FD0S\\/\x05_SB_PCI0LPC_EC__HPNF\x86\\/\x05_SB_PCI0LPC_FDC_FDD0
+\x01\xa0J
+\x93BSTS
+\x00\xa0.\x92\x93`BDEV\xa0\x10BXCNp`BDEVNXRC`\xa1\x14NBEJBDEVp`BDEVNBIN`\xa1A\x07\xa0N\x06\x91\\LFDC\x92\x93BDEV
+\r\xa0M\x05\x92\x93`
+\x0fLED_
+\x04
+\x80\xa0M\x04HPBU}yh
+\x08\x00\x0b\x05 BHKE\\/\x06_SB_PCI0LPC_EC__HKEYMHKQBHKE\xa0\x06\x92\x94h
+\x02\xa1\x13\xa0
+BXCNNXRE`\xa1\x06NBRE`\x14N\x0fBDIS\x00\xa0F\x0f\x92\\/\x04_SB_PCI0LPC_CSON\xa0F\x06\x93\\BIDE
+\x03p
+\x00\\/\x04_SB_PCI0SATASIE0p
+\x00\\/\x04_SB_PCI0SATASTI0p
+\x00\\/\x04_SB_PCI0LPC_URST[!
+\x0fp
+\x01\\/\x04_SB_PCI0SATASSIG\xa1N\x05p
+\x00\\/\x04_SB_PCI0IDE0PIE0p
+\x00\\/\x04_SB_PCI0IDE0PTI0p
+\x00\\/\x04_SB_PCI0LPC_URST[!
+\x0fp
+\x01\\/\x04_SB_PCI0IDE0PSIGp
+\x01\\/\x04_SB_PCI0LPC_CSONBSFD\x14A\x0eBEN_\x01\xa0I\r\\/\x04_SB_PCI0LPC_CSONp
+\x00\\/\x04_SB_PCI0LPC_URSTp
+\x00\\/\x04_SB_PCI0LPC_CSON["
+\x0f\xa0C\th\xa05\x93\\BIDE
+\x03p
+\x00\\/\x04_SB_PCI0SATASSIGp
+\x01\\/\x04_SB_PCI0SATASIDE\xa1-p
+\x00\\/\x04_SB_PCI0IDE0PSIGp
+\x01\\/\x04_SB_PCI0IDE0PIDE[!
+-p
+\x01\\/\x04_SB_PCI0LPC_URST\xa0
+\x93h
+\x02["\x0b\xd0\x07\xa1\x06["\x0b\x90\x01\x14N\x05BSTA\x01\xa0\x17\\/\x04_SB_PCI0LPC_CSON\xa4
+\x00BINI\xa0\r\x93h
+\x00\xa4\x93BDEV
+\r\xa0\r\x93h
+\x01\xa4\x95BDEV
+\x0c\xa0\r\x93h
+\x02\xa4\x93BDEV
+\x0e\xa0\r\x93h
+\x03\xa4\x93BDEV
+\x11\xa4
+\x00\x14D\x06BUWK\x01\xa0?\\H8DR\xa0\x1chp
+\x01\\/\x05_SB_PCI0LPC_EC__HWBU\xa1\x1bp
+\x00\\/\x05_SB_PCI0LPC_EC__HWBU\xa1\x1c\xa0\rh\\MBEC
+2
+\xff
+\x80\xa1\x0c\\MBEC
+2
+\x7f
+\x00\x14\x1aBINI\x00\xa0\x13\x93BDEV
+\xffpBGID
+\x00BDEV\x14F\x0bBGID\x01\xa0\x06hp
+\xff`\xa1E
+\xa0\x0c\\H8DRpHBID`\xa1\x10zRBEC
+G
+\x02`{`
+\x0f`{`
+\x03`\xa0\t\x93`
+\x00p
+\x03`\xa1\x11\xa0\t\x93`
+\x02p
+\x06`\xa1\x05p
+\x0f`\xa0)\x93`
+\x0f\xa0\x10\\H8DR\xa0\tHB1Ap
+\x10`\xa1\x12\xa0\x10{\\RBEC
+9
+\x80\x00p
+\x10`\xa09\x93`
+\x0f\xa03\x92\\/\x04_SB_PCI0LPC_CSON\xa0\x1d\x92{\\/\x04_SB_PCI0LPC_GL00
+@\x00p
+\x11`\xa4`\x14(BSFD\x00\xa0\x13BSTA
+\x00\\MISA\x0b\xf3\x03
+\xf3
+\x00\xa1\r\\MISA\x0b\xf3\x03
+\xf3
+\x04\x14A\x0bNXRE\x01\xa0\x14\x93h
+\x0fLED_
+\x04
+\x00p
+\x00BSTS\xa0!\x93h
+\r\xa0\x1b\\LFDCLED_
+\x04
+\xc0\x86\\._SB_SWAP
+\x83\xa0\x1a\x95h
+\x0cLED_
+\x04
+\xc0\x86\\._SB_SWAP
+\x83\xa0\x1a\x93h
+\x0eLED_
+\x04
+\xc0\x86\\._SB_SWAP
+\x83\xa0<\x93h
+\x10\xa0\x1f\x91HPACHB0ALED_
+\x04
+\xc0\x86\\._SB_SWAP
+\x83\xa1\x16LED_
+\x04
+\xc0BEEP
+\x0fp
+\x02BSTS\x14E\x0cNXRC\x01\xa0+\x93h
+\r\xa0%\\LFDCLED_
+\x04
+\x80BEN_
+\x00BSFD\x86\\._SB_SWAP
+\x80\xa0.\x95h
+\x0cLED_
+\x04
+\x80\xa0\x0b\x93h
+\x06BEN_
+\x02\xa1\x07BEN_
+\x01\x86\\._SB_SWAP
+\x80\xa0 \x93h
+\x0eLED_
+\x04
+\x80BEN_
+\x00\x86\\._SB_SWAP
+\x80\xa04\x93h
+\x10\x86\\/\x05_SB_PCI0LPC_EC__BAT1
+\x81LED_
+\x04
+\x80\x86\\._SB_SWAP
+\x80BEEP
+\x00p
+\x00BSTS\x14I\x04NXEJ\x01\xa0\x1f\x93h
+\x10\x86\\/\x05_SB_PCI0LPC_EC__BAT1
+\x81\x86\\._SB_SWAP
+\x82LED_
+\x04
+\x00BEEP
+\x00p
+\x00BSTS\x14\x13NXIN\x01\x86\\._SB_SWAP
+\x81\x10C\x10\\/\x04_SB_PCI0LPC_FDC_\x08XFDS
+\x00\x08DCFD
+\x00\x14C\x05_INI\x00p
+\x00XFDS\xa07\\H8DR}\\/\x05_SB_PCI0LPC_EC__HAMA
+\x0c\\/\x05_SB_PCI0LPC_EC__HAMA\xa1\x0c\\MBEC
+\x1a
+\xff
+\x0c\x08FDEB\x11\x17
+\x14\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x8cFDEB
+\x00FD0S\x14C\x06_FDE\x00\xa0&\x91\\/\x05_SB_PCI0LPC_EC__BSTA
+\x00DCFDp
+\x01FD0S\xa1/\xa0$\x91\\/\x05_SB_PCI0LPC_EC__HPNFXFDSp
+\x00FD0S\xa1\x08p
+\x01FD0S\xa4FDEB\x10E\x06\\/\x05_SB_PCI0LPC_FDC_FDD0\x14K\x04_EJ0\x01\xa02\\/\x05_SB_PCI0LPC_EC__BSTA
+\x00\\/\x05_SB_PCI0LPC_EC__BEJ0h\xa1\x10\xa0\x05DCFD\xa1\x08p
+\x01XFDS\x10A\x12\\/\x04_SB_PCI0LPC_EC__\x14C\t_Q52\x00\xa02\\/\x05_SB_PCI0LPC_FDC_XFDSp
+\x00\\/\x05_SB_PCI0LPC_FDC_XFDS\xa1H\x05\xa02\x91\\/\x05_SB_PCI0LPC_EC__BSTA
+\x00\\/\x05_SB_PCI0LPC_FDC_DCFD\xa1"\xa0 \\LFDC\x86\\/\x05_SB_PCI0LPC_FDC_FDD0
+\x01\x14G\x07_Q53\x00p
+\x00\\/\x05_SB_PCI0LPC_FDC_XFDS\xa02\x91\\/\x05_SB_PCI0LPC_EC__BSTA
+\x00\\/\x05_SB_PCI0LPC_FDC_DCFD\xa1"\xa0 \\LFDC\x86\\/\x05_SB_PCI0LPC_FDC_FDD0
+\x01\x10F\x04\\/\x05_SB_PCI0LPC_EC__BAT1\x14,_EJ0\x01p
+\x00B1STp
+\x00XB1S\\/\x05_SB_PCI0LPC_EC__BEJ0h\x10@3\\_SB_[\x82G2SWAP\x08_HID\x0c$M\x00i\x14\x15_STA\x00\xa0\t\\WMEF\xa4
+\x0f\xa1\x04\xa4
+\x00\x14"XCNN\x01ph\\/\x05_SB_PCI0LPC_EC__BXCN\xa4
+\t\x14\tXSWP\x00\xa4
+\x01\x14\x1eXEJ0\x01\\/\x05_SB_PCI0LPC_EC__BEJ0h\x14\x1eXEJ3\x01\\/\x05_SB_PCI0LPC_EC__BEJ3h\x14@\x1fXDID\x00\x08XPCK\x12\x17\x06
+\x00
+\x00\x0c\xff\xff\xff\xff\x0c\xff\xff\xff\xff\x0c\xff\xff\xff\xff
+\x00p\\/\x05_SB_PCI0LPC_EC__BDEV`p`\x88XPCK
+\x00\x00\xa0D\r\x95`
+\x0c\xa0J\x06\x93\\BIDE
+\x03p\\/\x04_SB_PCI0SATA_ADR\x88XPCK
+\x02\x00p\\/\x05_SB_PCI0SATASCND_ADR\x88XPCK
+\x03\x00p\\/\x06_SB_PCI0SATASCNDMSTR_ADR\x88XPCK
+\x04\x00\xa1B\x06p\\/\x04_SB_PCI0IDE0_ADR\x88XPCK
+\x02\x00p\\/\x05_SB_PCI0IDE0PRIM_ADR\x88XPCK
+\x03\x00p\\/\x06_SB_PCI0IDE0PRIMMSTR_ADR\x88XPCK
+\x04\x00\xa0O\x05\x93`
+\r\xa0K\x04\\LFDCp\\/\x05_SB_PCI0LPC_FDC__HID\x88XPCK
+\x02\x00p\\/\x06_SB_PCI0LPC_FDC_FDD0_ADR\x88XPCK
+\x04\x00\xa1\x0cp
+\x0f\x88XPCK
+\x00\x00\xa0N\x04\x93`
+\x10p\\/\x06_SB_PCI0LPC_EC__BAT1_HID\x88XPCK
+\x02\x00p\\/\x06_SB_PCI0LPC_EC__BAT1_UID\x88XPCK
+\x04\x00p\x7f\\/\x04_SB_PCI0LPC_CSON
+\x01\x00\x88XPCK
+\x05\x00\xa4XPCK\x14H\x05XSTM\x01\x08XDMY\x11\x03
+\x14\xa0\'\x93\\BIDE
+\x03\\/\x05_SB_PCI0SATASCND_STMXDMYh
+\x00\xa1\x1f\\/\x05_SB_PCI0IDE0PRIM_STMXDMYh
+\x00\x14K\x04XGTF\x00\xa0%\x93\\BIDE
+\x03\xa4\\/\x06_SB_PCI0SATASCNDMSTR_GTF\xa1\x1d\xa4\\/\x06_SB_PCI0IDE0PRIMMSTR_GTF\x10L\xe9\\_SB_[\x82C\xe9GDCK\x08_HID\x0c$M\x00y\x08_CID\x0cA\xd0\x0c\x15\x08DOID\x0c\xff\xff\xff\xff\x08DIDB\x0c\xff\xff\xff\xff\x08FLAG
+\x00\x08WUCT
+\x00\x08DHKE
+\x00[\x02DEVT\x14?DSTA\x00UDCKUDKT\xa0\x1a\x91\x93GDID\x0c$M\x00L\x93GDID\x0c$M\x00Dp
+\x0f`\xa1\x13\xa0\x0b\x92\\W98Fp
+\x00`\xa1\x05p
+\x0c`\xa4`\x14G\x07DPTS\x01\xa0O\x06\x90\x92\x95h
+\x01\x92\x94h
+\x04p
+\x00DHKE\xa0\x18DFLG
+\x02
+\x02p
+\x00DOIDDFLG
+\x01
+\x02\xa0/\x91\x93GDID\x0c$M\x00L\x93GDID\x0c$M\x00D\\/\x05_SB_PCI0LPC_EC__DDWK
+\x01pGDIDDIDBDFLG
+\x00\x0b\x00\x01\x08DDTM
+\x00\x14J\x18DWAK\x01p\x0c\xff\xff\xff\xffDOID\xa0H\x17\x90\x92\x95h
+\x01\x92\x94h
+\x04p
+\x00DDTM\xa0\x1d\x91\x93DIDB\x0c$M\x00L\x93DIDB\x0c$M\x00Dp
+\x01DDTM\xa0B\rDDTMp
+\x00DDTM\xa0\x12\x93GDID\x0c$M\x00Lp
+\x01DDTM\xa0\x12\x93GDID\x0c$M\x00Dp
+\x01DDTM\xa0;DDTM\xa0"\x93h
+\x04\xa0\x1c{\\/\x04_SB_PCI0LPC_WAKR
+\x08\x00DGPEyh
+\x08DHKE\xa0
+\x92DFLG
+\x02
+\x08\xa1B\x06p
+\x01\\/\x04_SB_PCI0LPC_BUSD\\/\x05_SB_PCI0LPC_EC__DATT
+\x00
+\x01\\/\x05_SB_PCI0LPC_EC__DATT
+\x01
+\x00\x86\\._SB_GDCK
+\x00\\DHDP
+\x00\xa1;p
+\x00DDTM\xa0\x12\x93GDID\x0c$M\x00Lp
+\x01DDTM\xa0\x12\x93GDID\x0c$M\x00Dp
+\x01DDTM\xa0\tDDTMWDCK\xa1\x02\xa3DFLG
+\x01\x0b\x00\x01DFLG
+\x01
+\x02DFLG
+\x01
+\x10DFLG
+\x01
+ p
+\x01\\/\x04_SB_PCI0LPC_DSCI\x14\x0eDGPE\x00DFLG
+\x00
+\x08\x14N\x12DDCK\x01\xa0J\x08h\\/\x05_SB_PCI0LPC_EC__LED_
+\x08
+\x00\\/\x05_SB_PCI0LPC_EC__LED_
+\t
+\x80\\/\x04_SB_PCI0LPC_LCON
+\x01BCON
+\x01\\/\x05_SB_PCI0LPC_EC__DATT
+\x00
+\x00\\/\x05_SB_PCI0LPC_EC__DATT
+\x01
+\x01\xa1H\t\\/\x05_SB_PCI0LPC_EC__LED_
+\x08
+\x80\\/\x05_SB_PCI0LPC_EC__LED_
+\t
+\xc0DFLG
+\x00
+\x02\\DHDP
+\x00BCON
+\x00\\/\x04_SB_PCI0LPC_LCON
+\x00\\/\x05_SB_PCI0LPC_EC__DATT
+\x00
+\x01\\/\x05_SB_PCI0LPC_EC__DATT
+\x01
+\x00\xa4
+\x01\x14C\x05DEJ0\x01\xa0\rhp
+\x00DOIDUDKIDFLG
+\x01
+\x02\\/\x05_SB_PCI0LPC_EC__LED_
+\x08
+\x00\\/\x05_SB_PCI0LPC_EC__LED_
+\t
+\x00\x14\x1fDEJ3\x01\xa0\x18hDFLG
+\x00
+\x10\xa0\r\x93\\SPS_
+\x03PDE3\x14\x11DEJ4\x01\xa0
+hDFLG
+\x00
+ \x14\x07PDE3\x00\xa3\x08HIDE
+\x00\x14@\x08WDCK\x00\xa0/\x91DFLG
+\x02
+\x10DFLG
+\x02
+ DDCK
+\x01\xa0\x16\\W98FDFLG
+\x00\x0b\x00\x02p
+\x05HIDE\xa1H\x04\xa06\x93\\/\x05_SB_PCI0LPC_EC__BGID
+\x00
+\x11\\/\x05_SB_PCI0LPC_EC__NBRE
+\x11\xa1\x0e\x86\\._SB_GDCK
+\x00\x14O\x07UDCK\x00\xa0G\x07DFLG
+\x02
+\x08\xa0L\x06\x92DFLG
+\x02\x0b\x00\x01}DHKE\x0b\x04 DHKE\xa0(\x93\\UOPT
+\x00\\/\x06_SB_PCI0LPC_EC__HKEYMHKQDHKE\xa0\x13\\W98F\x86\\._SB_GDCK
+\x01\xa1\x0e\x86\\._SB_GDCK
+\x03DFLG
+\x01
+\x08\x14\x1dUDKI\x00\xa0\r\\WNTFp
+\x01WUCT\xa1\x08p
+\x05WUCT\x14C\x05UDKT\x00\xa0K\x04{DHKE\x0b\x04 \x00\xa0?\x93GDID
+\x00\xa06\x92vWUCTp
+\x00DHKE\xa0\'\x93\\UOPT
+\x00\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x03@\x145GDID\x00\xa0)\x93DOID\x0c\xff\xff\xff\xffp\x0c\xff\xff\xff\xff\\/\x03_SB_GDCKG_IDpRDIDDOID\xa4DOID\x14O\tRDID\x00p
+\x00`\xa0A\t\\/\x04_SB_PCI0LPC_EPWG\xa0@\x06\x93\\/\x03_SB_GDCKGGID
+\x00\xa0B\x04\\H8DR\xa01\\/\x05_SB_PCI0LPC_EC__EEPRp\\/\x05_SB_PCI0LPC_EC__HDEP`\xa1\x08p\x0c$M\x00L`\xa1\x08p\\DCKI`\xa0\x1a\x93\\/\x03_SB_GDCKGGID
+\x01p\x0c$M\x00D`\xa4`\x14G\x08RDSR\x00p
+\x00`\xa0I\x07\x92\x93GDID
+\x00\xa0F\x05\x93\\/\x03_SB_GDCKGGID
+\x00\xa08\\H8DR\xa01\\/\x05_SB_PCI0LPC_EC__EEPRp\\/\x05_SB_PCI0LPC_EC__HDEN`\xa1\x08p\\DCKS`\xa0\x17\x93\\/\x03_SB_GDCKGGID
+\x01p
+\x00`\xa4`\x14E\x17BCON\x01p\\/\x05_SB_PCI0LPC_EC__DATT
+\x00
+\x02`\\/\x05_SB_PCI0LPC_EC__DATT
+\x00
+\x01}\\/\x04_SB_PCI0LPC_SERQ
+@\\/\x04_SB_PCI0LPC_SERQ{\\/\x04_SB_PCI0LPC_SERQ
+\x7f\\/\x04_SB_PCI0LPC_SERQp\\/\x04_SB_PCI0LPC_CLKRa\xa0.hp
+\x00\\/\x04_SB_PCI0LPC_CLKRp
+\x01\\/\x04_SB_PCI0LPC_BUSC\xa1\x17p
+\x01\\/\x04_SB_PCI0LPC_BUSDpa\\/\x04_SB_PCI0LPC_CLKR}\\/\x04_SB_PCI0LPC_SERQ
+\xc0\\/\x04_SB_PCI0LPC_SERQ{\\/\x04_SB_PCI0LPC_SERQ
+\xbf\\/\x04_SB_PCI0LPC_SERQ\xa0 \x93`
+\x00\\/\x05_SB_PCI0LPC_EC__DATT
+\x00
+\x00\x149DFLG\x02\xa0\x0f\x93h
+\x00}FLAGiFLAG\xa0\x11\x93h
+\x01{FLAG\x80i\x00FLAG\xa0\x0b{FLAGi\x00\xa4
+\x01\xa1\x04\xa4
+\x00\x10L\x1b\\/\x04_SB_PCI0LPC_EC__\x14A\x11_Q37\x00\xa0I\x10\\/\x04_SB_PCI0LPC_EPWGp\x0b\xd0\x07`["
+dp\x0c\xff\xff\xff\xff\\/\x03_SB_GDCKG_ID\xa20\x90\x93\\/\x03_SB_GDCKGGID
+\x07`["
+\x01p\x0c\xff\xff\xff\xff\\/\x03_SB_GDCKG_IDv`p\x0c\xff\xff\xff\xff\\/\x03_SB_GDCKDOID\xa0O\x08\x91\x93\\/\x03_SB_GDCKGDID\x0c$M\x00L\x93\\/\x03_SB_GDCKGDID\x0c$M\x00D\xa06\x93\\/\x05_SB_PCI0LPC_EC__BGID
+\x00
+\x11\\/\x05_SB_PCI0LPC_EC__NBRE
+\x11\xa1*\xa0(HPACp
+\x00\\/\x04_SB_PCI0LPC_DRST\x86\\._SB_GDCK
+\x00\x14D\tEEPR\x00p
+\x00`\xa0F\x08\\H8DRp
+\x00HDEOp
+
+HDEC\xa2\x0e\x92{HDEC
+\xc0\x00["
+\x01\xa0A\x06\x92{HDEC
+@\x00p
+\x00apHDENbp
+\x04c\xa2\x11cra{b
+\xff\x00azb
+\x08bvcpHDEPbp
+\x04c\xa2\x11cra{b
+\xff\x00azb
+\x08bvcraHDEMaraHDESa\xa0\x0b\x92{a
+\xff\x00p
+\x01`\xa4`\x14D\x04_STA\x00pGGID`\xa0\x0b\x92\\W98Fp
+\x00a\xa1\x05p
+\x0ca\xa0\x1b\x91\x93`
+\x00\x93`
+\x01p\\/\x03_SB_GDCKDSTAa\xa0\x06\x93`
+\x02\xa3\xa4a\x14H\x0c_INI\x00\\/\x05_SB_PCI0LPC_EC__DATT
+\x02
+\x01\xa0>\x93GGID
+\x07\\/\x05_SB_PCI0LPC_EC__DATT
+\x01
+\x00\\/\x05_SB_PCI0LPC_EC__DATT
+\x00
+\x01\xa17\\/\x05_SB_PCI0LPC_EC__DATT
+\x01
+\x01\\/\x05_SB_PCI0LPC_EC__DATT
+\x00
+\x00\\/\x05_SB_PCI0LPC_EC__DDWK
+\x00p
+\x01\\/\x04_SB_PCI0LPC_DSCI\x14K\x04_DCK\x01p
+\x00`\xa0"\x91\x93GGID
+\x00\x93GGID
+\x01p\\/\x03_SB_GDCKDDCKh`\xa0\x1a\\VIGD\\/\x04_SB_PCI0VID_VDSWh\xa4`\x08UDOP
+\x00\x148_EJ0\x01\xa0\x18\x93GGID
+\x00\\/\x03_SB_GDCKDEJ0h\xa0\x18\x93GGID
+\x01\\/\x03_SB_GDCKDEJ0h\x148XEJ3\x01\xa0\x18\x93GGID
+\x00\\/\x03_SB_GDCKDEJ3h\xa0\x18\x93GGID
+\x01\\/\x03_SB_GDCKDEJ3h\x148_EJ4\x01\xa0\x18\x93GGID
+\x00\\/\x03_SB_GDCKDEJ4h\xa0\x18\x93GGID
+\x01\\/\x03_SB_GDCKDEJ4h\x146PEJ3\x00\xa0\x17\x93GGID
+\x00\\/\x03_SB_GDCKPDE3\xa0\x17\x93GGID
+\x01\\/\x03_SB_GDCKPDE3\x14A\x04_BDN\x00p
+\x00`\xa0\x19\x93GGID
+\x00p\\/\x03_SB_GDCKRDID`\xa0\x19\x93GGID
+\x01p\\/\x03_SB_GDCKRDID`\xa4`\x14A\x04_UID\x00p
+\x00`\xa0\x19\x93GGID
+\x00p\\/\x03_SB_GDCKRDSR`\xa0\x19\x93GGID
+\x01p\\/\x03_SB_GDCKRDSR`\xa4`\x14.GPTS\x01\\/\x03_SB_GDCKDPTSh\\/\x05_SB_PCI0LPC_EC__RPTSh\x14H\x04GWAK\x01\\/\x03_SB_GDCKDWAKh\\/\x05_SB_PCI0LPC_EC__RWAKh\\/\x05_SB_PCI0LPC_EC__DDWK
+\x00\x146GGPE\x00\xa0\x17\x93GGID
+\x00\\/\x03_SB_GDCKDGPE\xa0\x17\x93GGID
+\x01\\/\x03_SB_GDCKDGPE\x08G_ID\x0c\xff\xff\xff\xff\x14N\x06GGID\x00pG_ID`\xa0N\x05\x93`\x0c\xff\xff\xff\xffp\\/\x04_SB_PCI0LPC_DKI0`p\\/\x04_SB_PCI0LPC_DKI1ap\\/\x04_SB_PCI0LPC_DKI2b}`ya
+\x01\x00`}`yb
+\x02\x00`p`G_ID\xa4`\x10F*\\/\x04_SB_PCI0LPC_EC__\x14M\x07_Q50\x00p\\/\x03_SB_GDCKGGID`\xa0D\x06\x91\x93`
+\x00\x93`
+\x01\\/\x05_SB_PCI0LPC_EC__LED_
+\x08
+\x80\\/\x05_SB_PCI0LPC_EC__LED_
+\t
+\xc0\xa0\x13\\W98F\x86\\._SB_GDCK
+\x01\xa1\x0e\x86\\._SB_GDCK
+\x03\x14F\x19DATT\x02p
+\x00`\xa0B\x08\x93h
+\x00\xa0(\x93i
+\x01\xa0\x11\\H8DR}HAM6
+\x80HAM6\xa1\x0c\\MBEC
+\x16
+\xff
+\x80p
+\x01`\xa0$\x93i
+\x00\xa0\x11\\H8DR{HAM6
+\x7fHAM6\xa1\x0c\\MBEC
+\x16
+\x7f
+\x00\xa0-\x93i
+\x02\xa0\x14\\H8DR\xa0\r{HAM6
+\x80\x00p
+\x01`\xa1\x12\xa0\x10{\\RBEC
+\x16
+\x80\x00p
+\x01`\xa0B\x08\x93h
+\x01\xa0(\x93i
+\x01\xa0\x11\\H8DR}HAMA
+\x01HAMA\xa1\x0c\\MBEC
+\x1a
+\xff
+\x01p
+\x01`\xa0$\x93i
+\x00\xa0\x11\\H8DR{HAMA
+\xfeHAMA\xa1\x0c\\MBEC
+\x1a
+\xfe
+\x00\xa0-\x93i
+\x02\xa0\x14\\H8DR\xa0\r{HAMA
+\x01\x00p
+\x01`\xa1\x12\xa0\x10{\\RBEC
+\x1a
+\x01\x00p
+\x01`\xa0B\x08\x93h
+\x02\xa0(\x93i
+\x01\xa0\x11\\H8DR}HAMB
+\x01HAMB\xa1\x0c\\MBEC
+\x1b
+\xff
+\x01p
+\x01`\xa0$\x93i
+\x00\xa0\x11\\H8DR{HAMB
+\xfeHAMB\xa1\x0c\\MBEC
+\x1a
+\xfe
+\x00\xa0-\x93i
+\x02\xa0\x14\\H8DR\xa0\r{HAMB
+\x01\x00p
+\x01`\xa1\x12\xa0\x10{\\RBEC
+\x1b
+\x01\x00p
+\x01`\xa4`\x14K\x07DDWK\x01p
+\x00`\xa0#\x93h
+\x01\xa0\x0c\\H8DRp\x01HWDK\xa1\x0c\\MBEC
+2
+\xff
+\x08p
+\x01`\xa0\x1f\x93h
+\x00\xa0\x0c\\H8DRp\x00HWDK\xa1\x0c\\MBEC
+2
+\xf7
+\x00\xa0)\x93h
+\x02\xa0\x10\\H8DR\xa0\tHWDKp
+\x01`\xa1\x12\xa0\x10{\\RBEC
+2
+\x08\x00p
+\x01`\xa4`\x10#\\/\x04_SB_PCI0LPC_EC__\x14\x07RPTS\x01\xa3\x14\x06RWAK\x01\x10B\x10\\/\x04_SB_PCI0LPC_EC__\x14N\x04_Q1C\x00\xa0?\\/\x06_SB_PCI0LPC_EC__HKEYMHKK\x0c\x00\x00 \x00\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x16\x10\\UCMS
+\x00\x14N\x04_Q1D\x00\xa0?\\/\x06_SB_PCI0LPC_EC__HKEYMHKK\x0c\x00\x00\x10\x00\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x15\x10\\UCMS
+\x01\x14N\x04_Q1E\x00\xa0?\\/\x06_SB_PCI0LPC_EC__HKEYMHKK\x0c\x00\x00@\x00\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x17\x10\\UCMS
+\x02\x10L\x13\\/\x04_SB_PCI0LPC_EC__\x08BRTF
+\x01\x14N\x08_Q14\x00\xa0=\\/\x06_SB_PCI0LPC_EC__HKEYMHKK\x0b\x00\x80\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x10\x10\xa0?\\NBCF\xa0\x1c\\VIGD\x86\\/\x04_SB_PCI0VID_LCD0
+\x86\xa1\x1b\x86\\/\x05_SB_PCI0AGP_VID_LCD0
+\x86\xa1\x08\\UCMS
+\x04\x14@\t_Q15\x00\xa0?\\/\x06_SB_PCI0LPC_EC__HKEYMHKK\x0c\x00\x00\x01\x00\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x11\x10\xa0?\\NBCF\xa0\x1c\\VIGD\x86\\/\x04_SB_PCI0VID_LCD0
+\x87\xa1\x1b\x86\\/\x05_SB_PCI0AGP_VID_LCD0
+\x87\xa1\x08\\UCMS
+\x05\x10D\x06\\/\x04_SB_PCI0LPC_EC__\x14N\x04_Q19\x00\xa0?\\/\x06_SB_PCI0LPC_EC__HKEYMHKK\x0c\x00\x00\x80\x00\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x18\x10\\UCMS
+\x03\x10D\x06\\/\x04_SB_PCI0LPC_EC__\x14N\x04_Q63\x00\xa0?\\/\x06_SB_PCI0LPC_EC__HKEYMHKK\x0c\x00\x00\x08\x00\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x14\x10\\UCMS
+\x0b\x10C\t\\/\x04_SB_PCI0LPC_EC__\x14
+_Q70\x00FNST\x14
+_Q72\x00FNST\x14
+_Q73\x00FNST\x14L\x05FNST\x00\xa0\x12\\H8DRpHFNS`pHFNEa\xa1\x17{\\RBEC
+\x0e
+\x03`{\\RBEC
+\x00
+\x08a\xa0)a\xa0\x0c\x93`
+\x00\\UCMS
+\x11\xa0\x0c\x93`
+\x01\\UCMS
+\x0f\xa0\x0c\x93`
+\x02\\UCMS
+\x10\x10I<\\/\x05_SB_PCI0LPC_EC__HKEY\x08WGFL
+\x00\x14\x1eWLSW\x00\xa4\\/\x05_SB_PCI0LPC_EC__GSTS\x14B\x04GWAN\x00p
+\x00`\xa0\x0e{WGFL
+\x01\x00}`
+\x01`\xa0\x0b{WGFL
+\x08\x00\xa4`\xa0
+WPWS}`
+\x02`\xa0\x0e{WGFL
+\x04\x00}`
+\x04`\xa4`\x14K\x04SWAN\x01\xa0\x0c{h
+\x02\x00WPWC
+\x01\xa1\x07WPWC
+\x00\xa0\x18{h
+\x04\x00}WGFL
+\x04WGFL\\WGSV
+\x02\xa1\x15{WGFL\x80
+\x04\x00WGFL\\WGSV
+\x03\x14B\x04GBDC\x00p
+\x00`\xa0\x0e{WGFL
+\x10\x00}`
+\x01`\xa0\x0b{WGFL
+\x80\x00\xa4`\xa0
+BPWS}`
+\x02`\xa0\x0e{WGFL
+@\x00}`
+\x04`\xa4`\x14K\x04SBDC\x01\xa0\x0c{h
+\x02\x00BPWC
+\x01\xa1\x07BPWC
+\x00\xa0\x18{h
+\x04\x00}WGFL
+@WGFL\\BLTH
+\x02\xa1\x15{WGFL\x80
+@\x00WGFL\\BLTH
+\x03\x14;WPWS\x00\xa0\x1f\\H8DRp\\/\x05_SB_PCI0LPC_EC__DCWW`\xa1\x12pz{\\RBEC
+:
+@\x00
+\x06\x00`\xa4`\x14\x19WTGL\x00\xa0\x12{WGFL
+\x01\x00WPWC\x92WPWS\x14B\tWPWC\x01\xa0N\x04\x90h\x90{WGFL
+\x01\x00\x92{WGFL
+\x08\x00\xa0\x1f\\H8DRp\x01\\/\x05_SB_PCI0LPC_EC__DCWW\xa1\x0c\\MBEC
+:
+\xff
+@}WGFL
+\x02WGFL\xa1;\xa0\x1f\\H8DRp\x00\\/\x05_SB_PCI0LPC_EC__DCWW\xa1\x0c\\MBEC
+:
+\xbf
+\x00{WGFL\x80
+\x02\x00WGFL\x14;BPWS\x00\xa0\x1f\\H8DRp\\/\x05_SB_PCI0LPC_EC__DCBD`\xa1\x12pz{\\RBEC
+:
+\x10\x00
+\x04\x00`\xa4`\x14\x19BTGL\x00\xa0\x12{WGFL
+\x10\x00BPWC\x92BPWS\x14B\tBPWC\x01\xa0N\x04\x90h\x90{WGFL
+\x10\x00\x92{WGFL
+\x80\x00\xa0\x1f\\H8DRp\x01\\/\x05_SB_PCI0LPC_EC__DCBD\xa1\x0c\\MBEC
+:
+\xff
+\x10}WGFL
+ WGFL\xa1;\xa0\x1f\\H8DRp\x00\\/\x05_SB_PCI0LPC_EC__DCBD\xa1\x0c\\MBEC
+:
+\xef
+\x00{WGFL\x80
+ \x00WGFL\x14;WGIN\x00p
+\x00WGFLp\\WGSV
+\x01WGFL\xa0\x10WPWS}WGFL
+\x02WGFL\xa0\x10BPWS}WGFL
+ WGFL\x146WGPS\x01\xa0\r\x92\x95h
+\x04\\BLTH
+\x05\xa0\x10\x92{WGFL
+\x04\x00WPWC
+\x00\xa0\x10\x92{WGFL
+@\x00BPWC
+\x00\x14&WGWK\x01\xa0\x0f{WGFL
+ \x00BPWC
+\x01\xa0\x0f{WGFL
+\x02\x00WPWC
+\x01\x109\\/\x04_SB_PCI0LPC_EC__\x14$_Q41\x00\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b\x00p\x10N\x0b\\_SB_[\x82E\x0bLCIO\x08_HID\x0c0\xae\x00\x01\x08_CID\x0cA\xd0
+\x06\x14)_STA\x00\xa0\x1d\\/\x05_SB_PCI0LPC_EC__BSTA
+\x03\xa4
+\x0f\xa1\x04\xa4
+\x00\x14@\x07_EJ0\x01\\/\x05_SB_PCI0LPC_EC__BEJ0h\xa0@\x05\x91\x93\\/\x03_SB_GDCKGDID\x0c$M\x00L\x93\\/\x03_SB_GDCKGDID\x0c$M\x00Dp
+\x00\\/\x04_SB_PCI0LPC_DRST\x86\\._SB_GDCK
+\x00\x10#\\/\x04_SB_PCI0EXP3EXPD\x08_EJD\r_SB.GDCK\x00\x10\'\\/\x05_SB_PCI0USB2URTHUPDK\x08_EJD\r_SB.GDCK\x00\x10\'\\/\x05_SB_PCI0USB7URTHUPDK\x08_EJD\r_SB.GDCK\x00\x101\\/\x05_SB_PCI0USB1URTHUPEX\x08_EJD\r_SB.PCI0.EXP2.EXUP\x00\x101\\/\x05_SB_PCI0USB7URTHUPEX\x08_EJD\r_SB.PCI0.EXP2.EXUP\x00\x102\\/\x04_SB_PCI0EXP2EXUP\x08_EJD\r_SB.PCI0.USB7.URTH.UPEX\x00\x08\\_S0_\x12
+\x04
+\x00
+\x00
+\x00
+\x00\x08\\_S3_\x12
+\x04
+\x05
+\x05
+\x00
+\x00\x08\\_S4_\x12
+\x04
+\x06
+\x06
+\x00
+\x00\x08\\_S5_\x12
+\x04
+\x07
+\x07
+\x00
+\x00\x14O\x1d\\_PTS\x01p
+\x01`\xa0\x0c\x93h\\SPS_p
+\x00`\xa0\x0f\x91\x93h
+\x00\x92\x95h
+\x06p
+\x00`\xa0E\x1b`ph\\SPS_\\/\x06_SB_PCI0LPC_EC__HKEYMHKE
+\x00\xa0\x1f\\/\x05_SB_PCI0LPC_EC__KBLT\\UCMS
+\r\xa0G\x05\x93h
+\x01p\\/\x05_SB_PCI0LPC_EC__HFNI\\FNIDp
+\x00\\/\x05_SB_PCI0LPC_EC__HFNIp
+\x00\\/\x05_SB_PCI0LPC_EC__HFSP\xa02\x93h
+\x03\\VVPD
+\x03\\TRAPp\\/\x06_SB_PCI0LPC_EC__AC___PSR\\ACST\xa0)\x93h
+\x04\\/\x03_SB_SLPB_PSW
+\x00\xa0\r\\SPEN\\STEP
+\x07\\TRAP\xa0
+\x93h
+\x05\\TRAP\\/\x05_SB_PCI0LPC_EC__BPTSh\xa0 \x92\x95h
+\x04p
+\x00\\/\x05_SB_PCI0LPC_EC__HWLB\xa1\x1bp
+\x01\\/\x05_SB_PCI0LPC_EC__HWLB\xa0<\x92\x93h
+\x05p
+\x01\\/\x05_SB_PCI0LPC_EC__HCMU\\/\x03_SB_GDCKGPTSh\xa0\x0b\\W98F\\CBRI\\/\x06_SB_PCI0LPC_EC__HKEYWGPSh\x08WAKI\x12\x06\x02
+\x00
+\x00\x14AJ\\_WAK\x01\xa0\x10\x91\x93h
+\x00\x92\x95h
+\x05\xa4WAKIp
+\x00\\SPS_p
+\x00\\/\x05_SB_PCI0LPC_EC__HCMUp
+\x80\\/\x05_SB_PCI0LPC_EC__HFSP\\/\x05_SB_PCI0LPC_EC__EVNT
+\x01\\/\x06_SB_PCI0LPC_EC__HKEYMHKE
+\x01\\/\x05_SB_PCI0LPC_EC__FNST\\UCMS
+\rp
+\x00\\LIDB\xa0"\x93h
+\x01p\\/\x05_SB_PCI0LPC_EC__HFNI\\FNID\xa0A\x13\x93h
+\x03THRM
+\x00\xa0E\x04\\WXPFp
+\x00\\/\x04_SB_PCI0LPC_C4C3\xa0\'\\OSC4\x86\\._PR_CPU0
+\x81\xa0\x13\\MPEN\x86\\._PR_CPU1
+\x81\xa1D\x07\xa0A\x07\\WNTF\xa02\\/\x06_SB_PCI0LPC_EC__AC___PSRp
+\x00\\/\x04_SB_PCI0LPC_C4C3\xa16\xa0\x1c\\CWASp
+\x00\\/\x04_SB_PCI0LPC_C4C3\xa1\x17p
+\x01\\/\x04_SB_PCI0LPC_C4C3\xa0:\x92\x93\\ACST\\/\x06_SB_PCI0LPC_EC__AC___PSR\\/\x05_SB_PCI0LPC_EC__ATMC\xa0.\x90{\\CFGD\x0c\x00\x00\x00\x01\x00\x90\\WXPF\x92\x94\\WSPV
+\x01\xa0\x10{\\CFGD
+\xf0\x00PPMS
+\x00\xa0@\x13\x93h
+\x04\xa0\x0bDTSETHRM
+\x02\xa0\x13\\W98F\x86\\._SB_SLPB
+\x02\xa0\x1f\\WMEF\\/\x05_SB_PCI0LPC_EC__BEEP
+\x05\xa0!\x92\\W98Fp
+\x00\\/\x05_SB_PCI0LPC_EC__HSPA\xa0.\\WXPF\xa0\'\\OSC4\x86\\._PR_CPU0
+\x81\xa0\x13\\MPEN\x86\\._PR_CPU1
+\x81\xa1D\x04\xa0A\x04\\WNTF\xa09\x91\x92\\/\x06_SB_PCI0LPC_EC__AC___PSR\\CWASp
+\x00\\/\x04_SB_PCI0LPC_C4C3\xa0\r\\SPEN\\STEP
+\x08\\/\x05_SB_PCI0LPC_EC__ATMC\xa0.\x90{\\CFGD\x0c\x00\x00\x00\x01\x00\x90\\WXPF\x92\x94\\WSPV
+\x01\xa0\x10{\\CFGD
+\xf0\x00PPMS
+\x00\xa0O\x07\x7f\\/\x04_SB_PCI0EXP2PDS_\\/\x04_SB_PCI0EXP2XCPF\x00\xa0*\\/\x04_SB_PCI0EXP2PDS_p
+\x01\\/\x04_SB_PCI0EXP2XCPF\xa1\x17p
+\x00\\/\x04_SB_PCI0EXP2XCPF\x86\\/\x03_SB_PCI0EXP2
+\x00\\/\x03_SB_GDCKGWAKh\\/\x05_SB_PCI0LPC_EC__BWAKh\\/\x06_SB_PCI0LPC_EC__HKEYWGWKh\x86\\._TZ_THM0
+\x80\x86\\._TZ_THM1
+\x80\\VSLD\\/\x03_SB_LID__LID\xa01\x90\\W98F\x92\\WMEF\x86\\/\x03_SB_PCI0USB0
+\x00\x86\\/\x03_SB_PCI0USB1
+\x00\xa09\x95h
+\x04\xa03{\\RRBF
+\x02\x00yh
+\x08`p}\x0b\x13 `\x00`\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ`p\x00\\RRBF\xa4WAKI\x10@\x1e\\_SI_\x14H\x1d_SST\x01\xa0;\x93h
+\x00\\/\x05_SB_PCI0LPC_EC__LED_
+\x00
+\x00\\/\x05_SB_PCI0LPC_EC__LED_
+\x07
+\x00\xa0B\x06\x93h
+\x01\xa0%\x91\\SPS_\\WNTF\\/\x05_SB_PCI0LPC_EC__BEEP
+\x05\\/\x05_SB_PCI0LPC_EC__LED_
+\x00
+\x80\\/\x05_SB_PCI0LPC_EC__LED_
+\x07
+\x00\xa0;\x93h
+\x02\\/\x05_SB_PCI0LPC_EC__LED_
+\x00
+\x80\\/\x05_SB_PCI0LPC_EC__LED_
+\x07
+\xc0\xa0K\x0b\x93h
+\x03\xa0"\x94\\SPS_
+\x03\\/\x05_SB_PCI0LPC_EC__BEEP
+\x07\xa1O\x04\xa01\x93\\SPS_
+\x03\\/\x05_SB_PCI0LPC_EC__BEEP
+\x03\\/\x03_SB_GDCKPEJ3\xa1\x1a\\/\x05_SB_PCI0LPC_EC__BEEP
+\x04\xa0\t\x93\\SPS_
+\x03\xa1\x1c\\/\x05_SB_PCI0LPC_EC__LED_
+\x00
+\x80\\/\x05_SB_PCI0LPC_EC__LED_
+\x07
+\xc0\xa09\x93h
+\x04\\/\x05_SB_PCI0LPC_EC__BEEP
+\x03\\/\x05_SB_PCI0LPC_EC__LED_
+\x07
+\xc0\x10C<\\_GPE[\x01MGPE\x07\x14N
+_L18\x00p\\/\x05_SB_PCI0LPC_EC__HWAK`p`\\RRBF["
+
+\xa0\x06{`
+\x02\x00\xa0){`
+\x04\x00\xa0\x13\\W98F\x86\\._SB_SLPB
+\x02\xa1\x0e\x86\\._SB_LID_
+\x02\xa0"{`
+\x08\x00\\/\x03_SB_GDCKGGPE\x86\\._SB_SLPB
+\x02\xa0\x13{`
+\x10\x00\x86\\._SB_SLPB
+\x02\xa0\x06{`
+@\x00\xa0\x13{`
+\x80\x00\x86\\._SB_SLPB
+\x02\x14K\x0f_L09\x00\xa0<\\/\x04_SB_PCI0EXP0PSP0p
+\x01\\/\x04_SB_PCI0EXP0PSP0\x86\\/\x03_SB_PCI0EXP0
+\x02\xa0<\\/\x04_SB_PCI0EXP1PSP1p
+\x01\\/\x04_SB_PCI0EXP1PSP1\x86\\/\x03_SB_PCI0EXP1
+\x02\xa0<\\/\x04_SB_PCI0EXP2PSP2p
+\x01\\/\x04_SB_PCI0EXP2PSP2\x86\\/\x03_SB_PCI0EXP2
+\x02\xa0<\\/\x04_SB_PCI0EXP3PSP3p
+\x01\\/\x04_SB_PCI0EXP3PSP3\x86\\/\x03_SB_PCI0EXP3
+\x02\x14D\x17_L01\x00\xa0@\x0f\\/\x04_SB_PCI0EXP2HPCSp
+\x01\\/\x04_SB_PCI0EXP2HPCS\xa0*\\/\x04_SB_PCI0EXP2ABP_p
+\x01\\/\x04_SB_PCI0EXP2ABP_\xa0I\t\\/\x04_SB_PCI0EXP2PDC_p
+\x01\\/\x04_SB_PCI0EXP2PDC_p
+\x00\\/\x04_SB_PCI0EXP2XCPF\x86\\/\x03_SB_PCI0EXP2
+\x00\xa0E\x04\\/\x04_SB_PCI0EXP2PDS_p
+\x01\\/\x04_SB_PCI0EXP2XCPF["
+d\x86\\/\x04_SB_PCI0EXP2EXUP
+\x01[#MGPE\xff\xff\xa0M\x06\\/\x04_SB_PCI0EXP0HPCSp
+\x01\\/\x04_SB_PCI0EXP0HPCS\xa0A\x04\\/\x04_SB_PCI0EXP0PDC_["
+\xc8p
+\x01\\/\x04_SB_PCI0EXP0PDC_\x86\\/\x03_SB_PCI0EXP0
+\x00[\'MGPE\x14D\t_L02\x00p
+\x00\\/\x04_SB_PCI0LPC_SWGE\xa0A\x04\\/\x06_SB_PCI0LPC_EC__HKEYDHKC\xa0#DT02\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b"`\x86\\._TZ_THM1
+\x80\xa0\'\\OSPX\x86\\._PR_CPU0
+\x80\xa0\x13\\MPEN\x86\\._PR_CPU1
+\x80\x10@(\\/\x05_SB_PCI0LPC_EC__HKEY\x14H\x0cMHQT\x01\xa0M\x0b\x90\\WNTF\\TATC\xa0\x0e\x93h
+\x00p\\TATC`\xa4`\xa1@
+\xa0K\x04\x93h
+\x01p\\TDFA`r`y\\TDTA
+\x04\x00`r`y\\TDFD
+\x08\x00`r`y\\TDTD
+\x0c\x00`r`y\\TNFT
+\x10\x00`r`y\\TNTT
+\x14\x00`\xa4`\xa1A\x05\xa02\x93h
+\x02p\\TCFA`r`y\\TCTA
+\x04\x00`r`y\\TCFD
+\x08\x00`r`y\\TCTD
+\x0c\x00`\xa4`\xa1\x1b\xa0\x05\x93h
+\x03\xa1\x13\xa0\x0e\x93h
+\x04p\\TATW`\xa4`\xa1\x02\xa3\xa4
+\x00\x14O\x07MHAT\x01\xa0D\x07\x90\\WNTF\\TATCp{h
+\xff\x00`\xa0
+\x92ATMV`\xa4
+\x00p{zh
+\x08\x00
+\xff\x00`\xa0
+\x92ATMV`\xa4
+\x00p{h
+\x0f\x00\\TCFAp{zh
+\x04\x00
+\x0f\x00\\TCTAp{zh
+\x08\x00
+\x0f\x00\\TCFDp{zh
+\x0c\x00
+\x0f\x00\\TCTDATMC\xa4
+\x01\xa4
+\x00\x14@\rMHGT\x01\xa0E\x0c\x90\\WNTF\\TATCpy\\TSFT
+\x10\x00`r`y\\TSTT
+\x14\x00`p{h
+\xff\x00a\xa0\x0b\x92ATMVa\xa4\x0b\xff\xffp{h
+\x0f\x00a\xa0\r\x93a
+\x00r`\\TIF0`\xa1&\xa0\r\x93a
+\x01r`\\TIF1`\xa1\x16\xa0\r\x93a
+\x02r`\\TIF2`\xa1\x06r`
+\xff`p{zh
+\x04\x00
+\x0f\x00a\xa0\x11\x93a
+\x00r`y\\TIT0
+\x08\x00`\xa12\xa0\x11\x93a
+\x01r`y\\TIT1
+\x08\x00`\xa1\x1e\xa0\x11\x93a
+\x02r`y\\TIT2
+\x08\x00`\xa1
+r`y
+\xff
+\x08\x00`\xa4`\xa4
+\x00\x14L\x04ATMV\x01p{h
+\x0f\x00ap\\TNFT`\xa0\x08\x92\x95a`\xa4
+\x00p{zh
+\x04\x00
+\x0f\x00bp\\TNTT`\xa0\x08\x92\x95b`\xa4
+\x00\xa0\x0f\\TATL\xa0\x08\x7fab\x00\xa4
+\x00\xa4
+\x01\x10F\x10\\/\x04_SB_PCI0LPC_EC__\x14@\x0fATMC\x00\xa0H\x0e\x90\\WNTF\\TATC\xa0E\x06HPACp\\TCFA`p\\TCTAap}ya
+\x04\x00`\x00ATMX\xa0\x1f\x93\\TCTA
+\x00p\\TCR0\\TCRTp\\TPS0\\TPSV\xa1#\xa0\x1f\x93\\TCTA
+\x01p\\TCR1\\TCRTp\\TPS1\\TPSV\xa1\x01\xa1A\x06p\\TCFD`p\\TCTDap}ya
+\x04\x00`\x00ATMX\xa0\x1f\x93\\TCTD
+\x00p\\TCR0\\TCRTp\\TPS0\\TPSV\xa1#\xa0\x1f\x93\\TCTD
+\x01p\\TCR1\\TCRTp\\TPS1\\TPSV\xa1\x01\x86\\._TZ_THM0
+\x81THRM
+\x01\x10C\x1f\\_TZ_[\x85L\x0cTHM0\x14\r_CRT\x00\xa4C2K_
+\x7f\x14G\x0b_TMP\x00\xa0B\x05\\H8DRp\\/\x05_SB_PCI0LPC_EC__TMP0`p\\/\x05_SB_PCI0LPC_EC__HT12ap\\/\x05_SB_PCI0LPC_EC__HT13b\xa1$p\\RBEC
+x`p{\\RBEC
+
+@\x00ap{\\RBEC
+
+\x80\x00b\xa0\tb\xa4C2K_
+\x80\xa0\'\x92\\/\x06_SB_PCI0LPC_EC__HKEYDHKC\xa0\ta\xa4C2K_
+\x80\xa4C2K_`[\x85@\x0fTHM1\x143_PSL\x00\xa0\x1e\\MPEN\xa4\x12\x16\x02\\._PR_CPU0\\._PR_CPU1\xa4\x12\x0c\x01\\._PR_CPU0\x14\x0c_CRT\x00\xa4\\TCRT\x14\x0c_PSV\x00\xa4\\TPSV\x14\x0c_TC1\x00\xa4\\TTC1\x14\x0c_TC2\x00\xa4\\TTC2\x14\x0c_TSP\x00\xa4\\TTSP\x14D\x07_TMP\x00\xa0J\x05\\DTSETHRM
+\x02pDTS1`\xa0\x11\x92\x95DTS0DTS1pDTS0`\xa0.\x92\\/\x06_SB_PCI0LPC_EC__HKEYDHKC\xa0\x10DT02r\\TCRT
+\x01`\xa4`\xa4C2K_`\xa1\x11\xa4\\/\x03_TZ_THM0_TMP\x14+C2K_\x01rwh
+
+\x00\x0b\xac
+`\xa0\x0c\x92\x94`\x0b\xac
+p\x0b\xb8\x0b`\xa0\x0b\x94`\x0b\xac\x0fp\x0b\xb8\x0b`\xa4`\x10O\x13\\/\x04_SB_PCI0LPC_EC__\x14I\x12_Q40\x00\x86\\._TZ_THM0
+\x80\xa08\\H8DRp\\/\x05_SB_PCI0LPC_EC__HT11`p\\/\x05_SB_PCI0LPC_EC__HT12a\xa1\x1bp{\\RBEC
+
+ \x00`p{\\RBEC
+
+@\x00a\xa0=\\/\x06_SB_PCI0LPC_EC__HKEYDHKC\xa0 a\\/\x06_SB_PCI0LPC_EC__HKEYMHKQ\x0b"`\xa0\x06VIGD\xa3\xa1\x06\\VTHR\xa0C\x07\\SPEN\xa0\'\\OSPX\x86\\._PR_CPU0
+\x80\xa0\x13\\MPEN\x86\\._PR_CPU1
+\x80\xa1C\x04\xa07\x91\\/\x05_SB_PCI0LPC_EC__HT00\\/\x05_SB_PCI0LPC_EC__HT10\\STEP
+\t\xa1\x08\\STEP
+
+\x08GPIC
+\x00\x14\r_PIC\x01ph\\GPIC[\x80MNVS\x00\x0c\x00@\xef\x7f\x0b\x00\x10[\x81B+MNVS\x03\x00\x80\x80\x07GAPA GAPL DCKI DCKS VCDL\x01VCDC\x01VCDT\x01VCDD\x01VIGD\x01VCSS\x01VCDB\x01VCIN\x01VPDF\x01\x00\x07VLID\x04VVPO\x04\x00\x08CDFL\x08CDAH\x08PMOD\x02PDIR\x01PDMA\x01\x00\x04LFDC\x01\x00\x07C2NA\x01C3NA\x01C4NA\x01\x00\x05SPEN\x01\x00\x01\x00\x01\x00\x01MPEN\x01\x00\x03OSPX\x01OSC4\x01OSSS\x01NHPS\x01NPME\x01\x00\x03UOPT\x08BTID LWST\x08LPST\x08TCRT\x10TPSV\x10TTC1\x10TTC2\x10TTSP\x10SRAH\x08SRHE\x08SRE0\x08SRE1\x08SRE2\x08SRE3\x08SRE4\x08SRE5\x08SRU0\x08SRU1\x08SRU2\x08SRU3\x08SRU7\x08SRPB\x08SRLP\x08SRSA\x08SRSM\x08CWAC\x01CWAS\x01\x00\x06CWAP\x10CWAT\x10DBGC\x01\x00\x07FS1L\x10FS1M\x10FS1H\x10FS2L\x10FS2M\x10FS2H\x10FS3L\x10FS3M\x10FS3H\x10TATC\x01\x00\x06TATL\x01TATW\x08TNFT\x04TNTT\x04TDFA\x04TDTA\x04TDFD\x04TDTD\x04TCFA\x04TCTA\x04TCFD\x04TCTD\x04TSFT\x04TSTT\x04TIT0\x08TCR0\x10TPS0\x10TIT1\x08TCR1\x10TPS1\x10TIT2\x08TCR2\x10TPS2\x10TIF0\x08TIF1\x08TIF2\x08\x00 TCZ1\x08TCZ2\x08TCZ3\x08BTHI\x01\x00\x07HDIR\x01HDEH\x01\x00\x06TPMP\x01TPMS\x01\x00\x06BIDE\x08\x00\x01DTSE\x01\x00\x06DTS0\x08DTS1\x08DT00\x01DT01\x01DT02\x01DT03\x01\x00\x04PH01\x08PH02\x08PH03\x08PH04\x08PH05\x08PH06\x08PH07\x08PH08\x08PH09\x08PH0A\x08PH0B\x08LIDB\x01\x00\x07TCG0\x01\x00\x07[\x81\x13MNVS\x01\x00\x80\x00\x07DDC1@@\x00@@[\x81\x10MNVS\x01\x00\x80\x00\x07DDC2@\x80[\x80SMI0\x01
+\xb2
+\x01[\x81\x0bSMI0\x01APMC\x08[\x81(MNVS\x00\x00\x80\xe0\x07CMD_\x08ERR_ PAR0 PAR1 PAR2 PAR3 [\x01MSMI\x07\x14F\x05SMI_\x05[#MSMI\xff\xffphCMD_piPAR0pjPAR1pkPAR2plPAR3p
+\xf5APMC\xa2\x13\x93ERR_
+\x01["
+dp
+\xf5APMCpPAR0`[\'MSMI\xa4`\x14\x14RPCI\x01\xa4SMI_
+\x00
+\x00h
+\x00
+\x00\x14\x12WPCI\x02SMI_
+\x00
+\x01hi
+\x00\x14\x11MPCI\x03SMI_
+\x00
+\x02hij\x14\x14RBEC\x01\xa4SMI_
+\x00
+\x03h
+\x00
+\x00\x14\x12WBEC\x02SMI_
+\x00
+\x04hi
+\x00\x14\x11MBEC\x03SMI_
+\x00
+\x05hij\x14\x14RISA\x01\xa4SMI_
+\x00
+\x06h
+\x00
+\x00\x14\x12WISA\x02SMI_
+\x00
+\x07hi
+\x00\x14\x11MISA\x03SMI_
+\x00
+\x08hij\x14\x14VEXP\x00SMI_
+\x01
+\x00
+\x00
+\x00
+\x00\x14\x13VUPS\x01SMI_
+\x01
+\x01h
+\x00
+\x00\x14\x12VSDS\x02SMI_
+\x01
+\x02hi
+\x00\x14\x14VDDC\x00SMI_
+\x01
+\x03
+\x00
+\x00
+\x00\x14\x13VVPD\x01SMI_
+\x01
+\x04h
+\x00
+\x00\x14\x13VNRS\x01SMI_
+\x01
+\x05h
+\x00
+\x00\x14\x15GLPW\x00\xa4SMI_
+\x01
+\x06
+\x00
+\x00
+\x00\x14\x13VSLD\x01SMI_
+\x01
+\x07h
+\x00
+\x00\x14\x14VEVT\x01\xa4SMI_
+\x01
+\x08h
+\x00
+\x00\x14\x15VTHR\x00\xa4SMI_
+\x01
+\t
+\x00
+\x00
+\x00\x14\x13VBRC\x01SMI_
+\x01
+
+h
+\x00
+\x00\x14\x15VBRG\x00\xa4SMI_
+\x01
+\x0e
+\x00
+\x00
+\x00\x14\x14UCMS\x01\xa4SMI_
+\x02h
+\x00
+\x00
+\x00\x14\x13BHDP\x02\xa4SMI_
+\x03
+\x00hi
+\x00\x14\x14DHDP\x01\xa4SMI_
+\x03
+\x01h
+\x00
+\x00\x14\x13STEP\x01SMI_
+\x04h
+\x00
+\x00
+\x00\x14\x14TRAP\x00SMI_
+\x05
+\x00
+\x00
+\x00
+\x00\x14\x14CBRI\x00SMI_
+\x05
+\x01
+\x00
+\x00
+\x00\x14"DSPD\x01\xa0\x18\x92\x94h
+\x01rh
+\x02hSMI_
+\x05h
+\x00
+\x00
+\x00\xa1\x02\xa3\x14\x14BLTH\x01\xa4SMI_
+\x06h
+\x00
+\x00
+\x00\x14\x14FISP\x00SMI_
+\x07
+\x00
+\x00
+\x00
+\x00\x14\x13ATCC\x01SMI_
+\x08h
+\x00
+\x00
+\x00\x14\x14WGSV\x01\xa4SMI_
+\th
+\x00
+\x00
+\x00\x14\x14THRM\x01\xa4SMI_
+
+h
+\x00
+\x00
+\x00\x14\x14PPMS\x01\xa4SMI_
+\x0bh
+\x00
+\x00
+\x00\x14\x13TPHY\x01SMI_
+\x0ch
+\x00
+\x00
+\x00\x14\x13TMOR\x01SMI_
+\rh
+\x00
+\x00
+\x00\x143DPIO\x02\xa0\x06\x92h\xa4
+\x00\xa0\x08\x94h
+\xf0\xa4
+\x00\xa0\x10\x94h
+\xb4\xa0\x05i\xa4
+\x02\xa1\x04\xa4
+\x01\xa0\x08\x94h
+x\xa4
+\x03\xa4
+\x04\x14=DUDM\x02\xa0\x06\x92i\xa4
+\xff\xa0\x08\x94h
+Z\xa4
+\x00\xa0\x08\x94h
+<\xa4
+\x01\xa0\x08\x94h
+-\xa4
+\x02\xa0\x08\x94h
+\x1e\xa4
+\x03\xa0\x08\x94h
+\x14\xa4
+\x04\xa4
+\x05\x14(DMDM\x02\xa0\x05i\xa4
+\x00\xa0\x06\x92h\xa4
+\x00\xa0\x08\x94h
+\x96\xa4
+\x01\xa0\x08\x94h
+x\xa4
+\x02\xa4
+\x03\x14A\x05UUDM\x02\xa0
+\x92{h
+\x04\x00\xa4
+\x00\xa0\t{i
+ \x00\xa4
+\x14\xa0\t{i
+\x10\x00\xa4
+\x1e\xa0\t{i
+\x08\x00\xa4
+-\xa0\t{i
+\x04\x00\xa4
+<\xa0\t{i
+\x02\x00\xa4
+Z\xa0\t{i
+\x01\x00\xa4
+x\xa4
+\x00\x14H\x04UMDM\x04\xa0
+\x92{h
+\x02\x00\xa4
+\x00\xa0\x08{i
+\x04\x00\xa4k\xa0\x14{i
+\x02\x00\xa0\t\x92\x94k
+x\xa4
+\xb4\xa1\x03\xa4k\xa0\x14{j
+\x04\x00\xa0\t\x92\x94k
+\xb4\xa4
+\xf0\xa1\x03\xa4k\xa4
+\x00\x14K\x04UPIO\x04\xa0\x16\x92{h
+\x02\x00\xa0\x08\x93j
+\x02\xa4
+\xf0\xa1\x05\xa4\x0b\x84\x03\xa0\x08{i
+\x02\x00\xa4k\xa0\x14{i
+\x01\x00\xa0\t\x92\x94k
+x\xa4
+\xb4\xa1\x03\xa4k\xa0\x08\x93j
+\x02\xa4
+\xf0\xa1\x05\xa4\x0b\x84\x03\x14-FDMA\x02\xa0\x0c\x92\x93i
+\xff\xa4}i
+@\x00\xa0\x10\x92\x95h
+\x03\xa4}th
+\x02\x00
+ \x00\xa0\x05h\xa4
+\x12\xa4
+\x00\x14\x1fFPIO\x01\xa0\x0c\x92\x95h
+\x03\xa4}h
+\x08\x00\xa0\x08\x93h
+\x01\xa4
+\x01\xa4
+\x00\x14J\x05SCMP\x02p\x87h`\xa0\x08\x92\x93`\x87i\xa4\x01u`\x08STR1\x11\x02`\x08STR2\x11\x02`phSTR1piSTR2p\x00a\xa2"\x95a`p\x83\x88STR1a\x00bp\x83\x88STR2a\x00c\xa0\x07\x92\x93bc\xa4\x01ua\xa4\x00\x08SPS_
+\x00\x08OSIF
+\x00\x08W98F
+\x00\x08WNTF
+\x00\x08WMEF
+\x00\x08WXPF
+\x00\x08WVIS
+\x00\x08WSPV
+\x00\x08LNUX
+\x00\x08H8DR
+\x00\x08MEMX
+\x00\x08ACST
+\x00\x08FNID
+\x00\x08RRBF
+\x00\x08NBCF
+\x00''')
+f('sys/firmware/acpi/tables/SSDT1', 0o664, b'''SSDT\xaa\x01\x00\x00\x01\x89LENOVOTP-7I \x11\x00\x00MSFT\x0e\x00\x00\x01\x10\x0e\\\x00\x14
+KOU2\x00[!
+d\x10I\x0b\\/\x04_SB_PCI0VID_LCD0\x14&_BCL\x00p
+\x01\\NBCF\xa4\x12\x16
+
+d
+\x1e
+\x1e
+(
+2
+<
+F
+P
+Z
+d\x08BCLP\x12\x12\x08
+\x1e
+(
+2
+<
+F
+P
+Z
+d\x08BCLL\x12\x12\x08
+\x00
+\x01
+\x02
+\x03
+\x04
+\x05
+\x06
+\x07\x14*_BCM\x01p\x89BCLP\x01h\x00
+\x00
+\x00`\xa0\x15\x92\x93`\xffp\x83\x88BCLL`\x00a\\VBRCa\x14!_BQC\x00p\\VBRG`\xa0\x0f\x92\x94`
+\x07\xa4\x83\x88BCLP`\x00\xa1\x03\xa4\x00\x10L\x0b\\/\x05_SB_PCI0AGP_VID_LCD0\x14%_BCL\x00p
+\x01NBCF\xa4\x12\x16
+
+d
+\x1e
+\x1e
+(
+2
+<
+F
+P
+Z
+d\x08BCLP\x12\x12\x08
+\x1e
+(
+2
+<
+F
+P
+Z
+d\x08BCLL\x12\x12\x08
+\x00
+\x01
+\x02
+\x03
+\x04
+\x05
+\x06
+\x07\x14*_BCM\x01p\x89BCLP\x01h\x00
+\x00
+\x00`\xa0\x15\x92\x93`\xffp\x83\x88BCLL`\x00a\\VBRCa\x14!_BQC\x00p\\VBRG`\xa0\x0f\x92\x94`
+\x07\xa4\x83\x88BCLP`\x00\xa1\x03\xa4\x00''')
+f('sys/firmware/acpi/tables/SLIC', 0o664, b'SLICv\x01\x00\x00\x01\x1dLENOVOTP-7I \x11\x00\x00 LTP\x00\x00\x00\x00\x00\x00\x00\x00\x9c\x00\x00\x00\x06\x02\x00\x00\x00$\x00\x00RSA1\x00\x04\x00\x00\x01\x00\x01\x00i\x16J\x9f\xb1K:\xfb\x80 \xaa\xaf\xc4\xf9>\xc1\x80I\xeeje&r\x1e\xcd\xbf_/\x96\xd6\xc0\n\x92\xf5\x06\xb5\x00\xb2;)\x02\xe2L\x8d\xc2\xf2\xbcAw\x9cp\xf0\xf3\x1b\t\xd2cZ\xdc\xa8\x83\xf8^\xc9\x15\x95\xf9\xfa\xfd\xdc\x05\xb7Mg\x7f-\xb3\x843 \xe1\xd1y*\xa7jw\xd1\xb6 *vB\xc5\xd5\xe9\xb6C@UD\xc3\xc97\x99_A\x97p\xf3\xd1\xf6\x07\xec{\x1a)\xa1\xc1\xf1\x91\xfdH\x86n>\xce\xcb\x01\x00\x00\x00\xb6\x00\x00\x00\x00\x00\x02\x00LENOVOTP-7I WINDOWS \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8bz\xb4\xe1\x0e{\x7fc\xd3M%N\xd7\tBd\x9c\x89\xf6F\xb8L\xd5M\x86sy\xf0\x15\xf2\x98\xad\x806\t\xbd\x8c%wn\xb8C\xf4\xb1\xf0W\x08x\x8d\xc6\x18T\xe1`G\xf07\xfdH\xd2\xfdM\x07\xdd\x91O\x9e*\xd6\xdd4\xeb\x9ac\x9a\xb8O%\xd4o\xf0\x95\xbb\xce\xbd:X\x04\xc5l\xb8\xa8\xd89\xf5\x02Oh\x84\x9c)K\xd0\x9b\x16\xb5\xf5A\xb0\x9d\xb8A\x07\x9dJ\x11\xaf\x19\xbd\xb7\xc7\x05\xb6\xa7\x93H\xf6\xcb')
+f('sys/firmware/acpi/tables/SSDT3', 0o664, b'''SSDT\xa6\x00\x00\x00\x01hLENOVOTP-7I \x11\x00\x00INTL\x13\x05\x05 \x10A\x08\\._PR_CPU1\x08_TPC
+\x00\x14\x16_PTC\x00\xa4\\/\x03_PR_CPU0_PTC\x14\x16_TSS\x00\xa4\\/\x03_PR_CPU0_TSS\x14?_TSD\x00\xa0\'\x90{CFGD\x0c\x00\x00\x00\x01\x00\x92{PDC1
+\x04\x00\xa4\x12\x0f\x01\x12\x0c\x05
+\x05
+\x00
+\x00
+\xfd
+\x02\xa4\x12\x0f\x01\x12\x0c\x05
+\x05
+\x00
+\x01
+\xfc
+\x01''')
+f('sys/firmware/acpi/tables/SSDT5', 0o664, b'''SSDT\xd8\x01\x00\x00\x01\tLENOVOTP-7I \x11\x00\x00INTL\x13\x05\x05 \x10C\x1b\\/\x03_SB_PCI0SATA[\x82@\x1aPRT0\x08DRE0
+\x00\x08DIP0
+\x00\x08HDTF\x11\x11
+\x0e\x02\x00\x00\x00\x00\xa0\xef\x00\x00\x00\x00\x00\xa0\xf5\x8cHDTF
+\rHFLC\x08ERTF\x11\x18
+\x15\x02\x00\x00\x00\x00\xa0\xef\x00\x00\x00\x00\x00\xa0\xf5_\x00\x00\x00\x00\xa0\xef\x8cERTF
+\rEFLC\x08HPTF\x11\x18
+\x15\x02\x00\x00\x00\x00\xa0\xef\x00\x00\x00\x00\x00\xa0\xf5\x10\x03\x00\x00\x00\xa0\xef\x8cHPTF
+\rPFLC\x08HXTF\x11\x1f
+\x1c\x02\x00\x00\x00\x00\xa0\xef\x00\x00\x00\x00\x00\xa0\xf5_\x00\x00\x00\x00\xa0\xef\x10\x03\x00\x00\x00\xa0\xef\x8cHXTF
+\rXFLC\x08_ADR\x0b\xff\xff\x14L\x08_SDD\x01p
+\x00DRE0p
+\x00DIP0\xa0F\x07\x93\x87h\x0b\x00\x02\x8bh
+\x9cM078\x8bh
+\xacM086\x8bh
+\xeeM119\x8bh\x0b(\x01M148\xa0\x1f\x93{M148\x0b\x00\xc0\x00\x0b\x00@\xa0\x10{M148
+\x04\x00p
+\x01DRE0\xa0\x1b{M086\x0b\x00\x80\x00\xa0\x10{M119
+\x01\x00p
+\x01DRE0\xa0\x10{M078
+\x08\x00p
+\x01DIP0\x14B\x05_GTF\x00\xa0"\\OSSSp
+\xe1XFLCp
+\xe1EFLCp
+\xe1HFLCp
+\xe1PFLC\xa0\x17DRE0\xa0
+DIP0\xa4HXTF\xa1\x06\xa4ERTF\xa0
+DIP0\xa4HPTF\xa4HDTF''')
+f('sys/firmware/acpi/tables/HPET', 0o664, b'HPET8\x00\x00\x00\x01\xaaLENOVOTP-7I \x11\x00\x00LNVO\x01\x00\x00\x00\x01\xa2\x86\x80\x00\x00\x00\x00\x00\x00\xd0\xfe\x00\x00\x00\x00\x00\x80\x00\x00')
+f('sys/firmware/acpi/tables/FACP', 0o664, b'FACP\xf4\x00\x00\x00\x03\xf0LENOVOTP-7I \x11\x00\x00LNVO\x01\x00\x00\x00\x00@\xef\x7f^\x19\xed\x7f\x00\x02\t\x00\xb2\x00\x00\x00\xf0\xf1\x00\xf3\x00\x10\x00\x00\x00\x00\x00\x00\x04\x10\x00\x00\x00\x00\x00\x00 \x10\x00\x00\x08\x10\x00\x00(\x10\x00\x00\x00\x00\x00\x00\x04\x02\x01\x04\x08\x00\x00\xf4\x01\x00U\x00\x00\x00\x00\x00\x01\x03\r\x002\x12\x00\x00\xad\xc2\x00\x00\x01\x08\x00\x00\xf9\x0c\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00@\xef\x7f\x00\x00\x00\x00^\x19\xed\x7f\x00\x00\x00\x00\x01 \x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x10\x00\x00\x04\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x08\x00\x00 \x10\x00\x00\x00\x00\x00\x00\x01 \x00\x00\x08\x10\x00\x00\x00\x00\x00\x00\x01 \x00\x00(\x10\x00\x00\x00\x00\x00\x00\x01 \x00\x00,\x10\x00\x00\x00\x00\x00\x00')
+f('sys/firmware/acpi/tables/APIC', 0o664, b'''APICh\x00\x00\x00\x01lLENOVOTP-7I \x11\x00\x00LNVO\x01\x00\x00\x00\x00\x00\xe0\xfe\x01\x00\x00\x00\x00\x08\x00\x00\x01\x00\x00\x00\x00\x08\x01\x01\x01\x00\x00\x00\x01\x0c\x01\x00\x00\x00\xc0\xfe\x00\x00\x00\x00\x02
+\x00\x00\x02\x00\x00\x00\x00\x00\x02
+\x00\t\t\x00\x00\x00\r\x00\x04\x06\x00\x05\x00\x01\x04\x06\x01\x05\x00\x01''')
+f('sys/firmware/acpi/tables/SSDT2', 0o664, b'''SSDT_\x02\x00\x00\x01\xc2LENOVOTP-7I \x11\x00\x00INTL\x13\x05\x05 \x10J#\\._PR_CPU0\x08_TPC
+\x00\x14M\x06_PTC\x00\xa07{PDC0
+\x04\x00\xa4\x12,\x02\x11\x14
+\x11\x82\x0c\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00y\x00\x11\x14
+\x11\x82\x0c\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00y\x00\xa4\x12,\x02\x11\x14
+\x11\x82\x0c\x00\x01\x04\x01\x00\x10\x10\x00\x00\x00\x00\x00\x00y\x00\x11\x14
+\x11\x82\x0c\x00\x01\x04\x01\x00\x10\x10\x00\x00\x00\x00\x00\x00y\x00\x08TSSI\x12A\x07\x08\x12\r\x05
+d\x0b\xe8\x03
+\x00
+\x00
+\x00\x12\r\x05
+X\x0bk\x03
+\x00
+\x0f
+\x00\x12\r\x05
+K\x0b\xee\x02
+\x00
+\x0e
+\x00\x12\r\x05
+?\x0bq\x02
+\x00
+\r
+\x00\x12\r\x05
+2\x0b\xf4\x01
+\x00
+\x0c
+\x00\x12\r\x05
+&\x0bw\x01
+\x00
+\x0b
+\x00\x12\x0c\x05
+\x19
+\xfa
+\x00
+
+
+\x00\x12\x0c\x05
+\r
+}
+\x00
+\t
+\x00\x08TSSM\x12A\x07\x08\x12\r\x05
+d\x0b\xe8\x03
+\x00
+\x00
+\x00\x12\r\x05
+X\x0bk\x03
+\x00
+\x1e
+\x00\x12\r\x05
+K\x0b\xee\x02
+\x00
+\x1c
+\x00\x12\r\x05
+?\x0bq\x02
+\x00
+\x1a
+\x00\x12\r\x05
+2\x0b\xf4\x01
+\x00
+\x18
+\x00\x12\r\x05
+&\x0bw\x01
+\x00
+\x16
+\x00\x12\x0c\x05
+\x19
+\xfa
+\x00
+\x14
+\x00\x12\x0c\x05
+\r
+}
+\x00
+\x12
+\x00\x08TSSF
+\x00\x14C\x08_TSS\x00\xa0G\x06\x90\x92TSSF[\x12_PSS\x00p_PSS`p\x87`avap\x83\x88\x83\x88`a\x00
+\x01\x00bp
+\x00c\xa25\x95c\x87TSSIpxwbt
+\x08c\x00\x00
+\x08\x00\x00dpd\x88\x83\x88TSSIc\x00
+\x01\x00pd\x88\x83\x88TSSMc\x00
+\x01\x00ucp\xffTSSF\xa0\x0e{PDC0
+\x04\x00\xa4TSSM\xa4TSSI\x14?_TSD\x00\xa0\'\x90{CFGD\x0c\x00\x00\x00\x01\x00\x92{PDC0
+\x04\x00\xa4\x12\x0f\x01\x12\x0c\x05
+\x05
+\x00
+\x00
+\xfd
+\x02\xa4\x12\x0f\x01\x12\x0c\x05
+\x05
+\x00
+\x00
+\xfc
+\x01''')
+f('sys/firmware/acpi/tables/BOOT', 0o664, b'BOOT(\x00\x00\x00\x01\xa8LENOVOTP-7I \x11\x00\x00 LTP\x01\x00\x00\x005\x00\x00\x00')
+f('sys/firmware/acpi/tables/TCPA', 0o664, b'TCPA2\x00\x00\x00\x02YLENOVOTP-7I \x11\x00\x00LNVO\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\xce\x1a\xee\x7f\x00\x00\x00\x00')
+f('sys/firmware/acpi/tables/SSDT4', 0o664, b'''SSDT\xf7\x04\x00\x00\x01\xa6LENOVOTP-7I \x11\x00\x00INTL\x13\x05\x05 \x10E\x08\\\x00\x08SSDT\x12C\x05\x0c\rCPU0IST \x00\x0c6\x1d\xef\x7f\x0c\xc4\x02\x00\x00\rCPU1IST \x00\x0cn\x1c\xef\x7f\x0c\xc8\x00\x00\x00\rCPU0CST \x00\x0c\x7f \xef\x7f\x0cZ\x06\x00\x00\rCPU1CST \x00\x0c\xfa\x1f\xef\x7f\x0c\x85\x00\x00\x00\x08CFGD\x0c\xf1i;\x11\x08\\PDC0\x0c\x00\x00\x00\x80\x08\\PDC1\x0c\x00\x00\x00\x80\x08\\SDTL
+\x00\x10@!\\._PR_CPU0\x08HI0_
+\x00\x08HC0_
+\x00\x14H\x06_PDC\x01\x8ah
+\x00REVS\x8ah
+\x04SIZEp\x87h`pt`
+\x08\x00a[\x13h
+@wa
+\x08\x00TEMP\x08STS0\x11\x07
+\x04\x00\x00\x00\x00sSTS0TEMPb_OSC\x11\x13
+\x10\x16\xa6w@\x0c)\xbeG\x9e\xbd\xd8pXq9SREVSSIZEb\x14L\x18_OSC\x04\x8ak
+\x00STS0\x8ak
+\x04CAP0\x8ah
+\x00IID0\x8ah
+\x04IID1\x8ah
+\x08IID2\x8ah
+\x0cIID3\x08UID0\x11\x13
+\x10\x16\xa6w@\x0c)\xbeG\x9e\xbd\xd8pXq9S\x8aUID0
+\x00EID0\x8aUID0
+\x04EID1\x8aUID0
+\x08EID2\x8aUID0
+\x0cEID3\xa02\x92\x90\x90\x93IID0EID0\x93IID1EID1\x90\x93IID2EID2\x93IID3EID3p
+\x06STS0\xa4k\xa0\x0f\x92\x93i
+\x01p
+
+STS0\xa4k}{PDC0\x0c\xff\xff\xff\x7f\x00CAP0PDC0\xa0L\x05{CFGD
+\x01\x00\xa0A\x05\x90\x90{CFGD\x0c\x00\x00\x00\x01\x00\x93{PDC0
+\t\x00
+\t\x92{SDTL
+\x01\x00}SDTL
+\x01SDTL[\x80IST0\x00\x83\x88SSDT
+\x01\x00\x83\x88SSDT
+\x02\x00[ IST0HI0_\xa0I\x05{CFGD
+\xf0\x00\xa0N\x04\x90\x90{CFGD\x0c\x00\x00\x00\x01\x00{PDC0
+\x18\x00\x92{SDTL
+\x02\x00}SDTL
+\x02SDTL[\x80CST0\x00\x83\x88SSDT
+\x07\x00\x83\x88SSDT
+\x08\x00[ CST0HC0_\xa4k\x10K#\\._PR_CPU1\x08HI1_
+\x00\x08HC1_
+\x00\x14H\x06_PDC\x01\x8ah
+\x00REVS\x8ah
+\x04SIZEp\x87h`pt`
+\x08\x00a[\x13h
+@wa
+\x08\x00TEMP\x08STS1\x11\x07
+\x04\x00\x00\x00\x00sSTS1TEMPb_OSC\x11\x13
+\x10\x16\xa6w@\x0c)\xbeG\x9e\xbd\xd8pXq9SREVSSIZEb\x14L\x18_OSC\x04\x8ak
+\x00STS1\x8ak
+\x04CAP1\x8ah
+\x00IID0\x8ah
+\x04IID1\x8ah
+\x08IID2\x8ah
+\x0cIID3\x08UID1\x11\x13
+\x10\x16\xa6w@\x0c)\xbeG\x9e\xbd\xd8pXq9S\x8aUID1
+\x00EID0\x8aUID1
+\x04EID1\x8aUID1
+\x08EID2\x8aUID1
+\x0cEID3\xa02\x92\x90\x90\x93IID0EID0\x93IID1EID1\x90\x93IID2EID2\x93IID3EID3p
+\x06STS1\xa4k\xa0\x0f\x92\x93i
+\x01p
+
+STS1\xa4k}{PDC1\x0c\xff\xff\xff\x7f\x00CAP1PDC1\xa0L\x05{CFGD
+\x01\x00\xa0A\x05\x90\x90{CFGD\x0c\x00\x00\x00\x01\x00\x93{PDC1
+\t\x00
+\t\x92{SDTL
+\x10\x00}SDTL
+\x10SDTL[\x80IST1\x00\x83\x88SSDT
+\x04\x00\x83\x88SSDT
+\x05\x00[ IST1HI1_\xa0I\x05{CFGD
+\xf0\x00\xa0N\x04\x90\x90{CFGD\x0c\x00\x00\x00\x01\x00{PDC1
+\x18\x00\x92{SDTL
+ \x00}SDTL
+ SDTL[\x80CST1\x00\x83\x88SSDT
+
+\x00\x83\x88SSDT
+\x0b\x00[ CST1HC1_\xa4k\x14*_INI\x00\xa0\x0c\\DTSETHRM
+\x00\xa0\x16\x90\\WXPF\x92\x94\\WSPV
+\x01PPMS
+\x00''')
+f('sys/firmware/acpi/tables/ECDT', 0o664, b'ECDTR\x00\x00\x00\x01ULENOVOTP-7I \x11\x00\x00LNVO\x01\x00\x00\x00\x01\x08\x00\x00f\x00\x00\x00\x00\x00\x00\x00\x01\x08\x00\x00b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\\_SB.PCI0.LPC.EC\x00')
+f('sys/firmware/acpi/tables/FACS', 0o664, b'FACS@\x00\x00\x00/\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
+f('sys/firmware/acpi/tables/MCFG', 0o664, b'MCFG<\x00\x00\x00\x01\x82LENOVOTP-7I \x11\x00\x00LNVO\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x00\x00\x00\x00\x00\x00\x00?\x00\x00\x00\x00')
+d('sys/firmware/acpi/interrupts', 0o775)
+f('sys/firmware/acpi/interrupts/gpe1A', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe12', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe11', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe10', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/ff_pmtimer', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe0C', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe04', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe06', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe14', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe0B', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/sci', 0o664, b' 14240\n')
+f('sys/firmware/acpi/interrupts/gpe08', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe15', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe17', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe0A', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/ff_rt_clk', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe09', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe19', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe03', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe01', 0o664, b' 1\tenable\n')
+f('sys/firmware/acpi/interrupts/ff_slp_btn', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/error', 0o664, b' 0\n')
+f('sys/firmware/acpi/interrupts/gpe1C', 0o664, b' 14039\tenable\n')
+f('sys/firmware/acpi/interrupts/ff_pwr_btn', 0o664, b' 0\tenable\n')
+f('sys/firmware/acpi/interrupts/gpe0D', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe05', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe02', 0o664, b' 200\tenable\n')
+f('sys/firmware/acpi/interrupts/gpe1E', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe18', 0o664, b' 0\tenable\n')
+f('sys/firmware/acpi/interrupts/gpe1D', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe1F', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe0E', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe00', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe1B', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe0F', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe07', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe16', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe13', 0o664, b' 0 invalid\n')
+f('sys/firmware/acpi/interrupts/gpe_all', 0o664, b' 14240\n')
+f('sys/firmware/acpi/interrupts/ff_gbl_lock', 0o664, b' 0\tenable\n')
+d('sys/bus', 0o755)
+d('sys/bus/pci_express', 0o755)
+f('sys/bus/pci_express/drivers_autoprobe', 0o644, b'1\n')
+d('sys/bus/pci_express/devices', 0o755)
+l('sys/bus/pci_express/devices/0000:00:1c.2:pcie02', '../../../devices/pci0000:00/0000:00:1c.2/0000:00:1c.2:pcie02')
+l('sys/bus/pci_express/devices/0000:00:1c.2:pcie00', '../../../devices/pci0000:00/0000:00:1c.2/0000:00:1c.2:pcie00')
+l('sys/bus/pci_express/devices/0000:00:1c.0:pcie03', '../../../devices/pci0000:00/0000:00:1c.0/0000:00:1c.0:pcie03')
+l('sys/bus/pci_express/devices/0000:00:01.0:pcie03', '../../../devices/pci0000:00/0000:00:01.0/0000:00:01.0:pcie03')
+l('sys/bus/pci_express/devices/0000:00:1c.2:pcie03', '../../../devices/pci0000:00/0000:00:1c.2/0000:00:1c.2:pcie03')
+l('sys/bus/pci_express/devices/0000:00:1c.1:pcie02', '../../../devices/pci0000:00/0000:00:1c.1/0000:00:1c.1:pcie02')
+l('sys/bus/pci_express/devices/0000:00:1c.0:pcie00', '../../../devices/pci0000:00/0000:00:1c.0/0000:00:1c.0:pcie00')
+l('sys/bus/pci_express/devices/0000:00:1c.3:pcie02', '../../../devices/pci0000:00/0000:00:1c.3/0000:00:1c.3:pcie02')
+l('sys/bus/pci_express/devices/0000:00:1c.0:pcie02', '../../../devices/pci0000:00/0000:00:1c.0/0000:00:1c.0:pcie02')
+l('sys/bus/pci_express/devices/0000:00:1c.1:pcie03', '../../../devices/pci0000:00/0000:00:1c.1/0000:00:1c.1:pcie03')
+l('sys/bus/pci_express/devices/0000:00:1c.3:pcie03', '../../../devices/pci0000:00/0000:00:1c.3/0000:00:1c.3:pcie03')
+l('sys/bus/pci_express/devices/0000:00:1c.1:pcie00', '../../../devices/pci0000:00/0000:00:1c.1/0000:00:1c.1:pcie00')
+l('sys/bus/pci_express/devices/0000:00:1c.3:pcie00', '../../../devices/pci0000:00/0000:00:1c.3/0000:00:1c.3:pcie00')
+l('sys/bus/pci_express/devices/0000:00:01.0:pcie00', '../../../devices/pci0000:00/0000:00:01.0/0000:00:01.0:pcie00')
+d('sys/bus/acpi', 0o775)
+f('sys/bus/acpi/drivers_autoprobe', 0o664, b'1\n')
+d('sys/bus/acpi/drivers', 0o775)
+d('sys/bus/acpi/drivers/thinkpad_hotkey', 0o775)
+l('sys/bus/acpi/drivers/thinkpad_hotkey/IBM0068:00', '../../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/IBM0068:00')
+d('sys/bus/acpi/drivers/button', 0o775)
+l('sys/bus/acpi/drivers/button/PNP0C0E:00', '../../../../devices/LNXSYSTM:00/device:00/PNP0C0E:00')
+l('sys/bus/acpi/drivers/button/PNP0C0D:00', '../../../../devices/LNXSYSTM:00/device:00/PNP0C0D:00')
+l('sys/bus/acpi/drivers/button/LNXPWRBN:00', '../../../../devices/LNXSYSTM:00/LNXPWRBN:00')
+d('sys/bus/acpi/drivers/processor', 0o775)
+l('sys/bus/acpi/drivers/processor/ACPI0007:01', '../../../../devices/LNXSYSTM:00/ACPI0007:01')
+l('sys/bus/acpi/drivers/processor/ACPI0007:00', '../../../../devices/LNXSYSTM:00/ACPI0007:00')
+d('sys/bus/acpi/drivers/power', 0o775)
+l('sys/bus/acpi/drivers/power/LNXPOWER:00', '../../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/LNXPOWER:00')
+d('sys/bus/acpi/drivers/pci_link', 0o775)
+l('sys/bus/acpi/drivers/pci_link/PNP0C0F:05', '../../../../devices/LNXSYSTM:00/device:00/PNP0C0F:05')
+l('sys/bus/acpi/drivers/pci_link/PNP0C0F:07', '../../../../devices/LNXSYSTM:00/device:00/PNP0C0F:07')
+l('sys/bus/acpi/drivers/pci_link/PNP0C0F:04', '../../../../devices/LNXSYSTM:00/device:00/PNP0C0F:04')
+l('sys/bus/acpi/drivers/pci_link/PNP0C0F:02', '../../../../devices/LNXSYSTM:00/device:00/PNP0C0F:02')
+l('sys/bus/acpi/drivers/pci_link/PNP0C0F:00', '../../../../devices/LNXSYSTM:00/device:00/PNP0C0F:00')
+l('sys/bus/acpi/drivers/pci_link/PNP0C0F:01', '../../../../devices/LNXSYSTM:00/device:00/PNP0C0F:01')
+l('sys/bus/acpi/drivers/pci_link/PNP0C0F:06', '../../../../devices/LNXSYSTM:00/device:00/PNP0C0F:06')
+l('sys/bus/acpi/drivers/pci_link/PNP0C0F:03', '../../../../devices/LNXSYSTM:00/device:00/PNP0C0F:03')
+d('sys/bus/acpi/drivers/battery', 0o775)
+l('sys/bus/acpi/drivers/battery/PNP0C0A:00', '../../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00')
+d('sys/bus/acpi/drivers/ec', 0o775)
+l('sys/bus/acpi/drivers/ec/PNP0C09:00', '../../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00')
+d('sys/bus/acpi/drivers/pci_root', 0o775)
+l('sys/bus/acpi/drivers/pci_root/PNP0A08:00', '../../../../devices/LNXSYSTM:00/device:00/PNP0A08:00')
+d('sys/bus/acpi/drivers/thermal', 0o775)
+l('sys/bus/acpi/drivers/thermal/LNXTHERM:01', '../../../../devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:01')
+l('sys/bus/acpi/drivers/thermal/LNXTHERM:02', '../../../../devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:02')
+d('sys/bus/acpi/drivers/ac', 0o775)
+l('sys/bus/acpi/drivers/ac/ACPI0003:00', '../../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/ACPI0003:00')
+d('sys/bus/acpi/devices', 0o775)
+l('sys/bus/acpi/devices/device:11', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:11')
+l('sys/bus/acpi/devices/device:21', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21')
+l('sys/bus/acpi/devices/PNP0000:00', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0000:00')
+l('sys/bus/acpi/devices/device:0b', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0b')
+l('sys/bus/acpi/devices/device:1f', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1d/device:1e/device:1f')
+l('sys/bus/acpi/devices/LNXTHERM:01', '../../../devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:01')
+l('sys/bus/acpi/devices/PNP0103:00', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0103:00')
+l('sys/bus/acpi/devices/LNXPOWER:00', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/LNXPOWER:00')
+l('sys/bus/acpi/devices/device:1c', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1a/device:1b/device:1c')
+l('sys/bus/acpi/devices/device:06', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06')
+l('sys/bus/acpi/devices/ACPI0003:00', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/ACPI0003:00')
+l('sys/bus/acpi/devices/PNP0C0A:00', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00')
+l('sys/bus/acpi/devices/device:0e', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0d/device:0e')
+l('sys/bus/acpi/devices/ATM1200:00', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/ATM1200:00')
+l('sys/bus/acpi/devices/device:08', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/device:08')
+l('sys/bus/acpi/devices/PNP0C0F:05', '../../../devices/LNXSYSTM:00/device:00/PNP0C0F:05')
+l('sys/bus/acpi/devices/device:18', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:18')
+l('sys/bus/acpi/devices/device:0c', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0c')
+l('sys/bus/acpi/devices/PNP0303:00', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0303:00')
+l('sys/bus/acpi/devices/device:17', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:16/device:17')
+l('sys/bus/acpi/devices/device:02', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02')
+l('sys/bus/acpi/devices/ACPI0007:01', '../../../devices/LNXSYSTM:00/ACPI0007:01')
+l('sys/bus/acpi/devices/device:13', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13')
+l('sys/bus/acpi/devices/PNP0C0E:00', '../../../devices/LNXSYSTM:00/device:00/PNP0C0E:00')
+l('sys/bus/acpi/devices/device:04', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/device:04')
+l('sys/bus/acpi/devices/PNP0A08:00', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00')
+l('sys/bus/acpi/devices/PNP0C04:00', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C04:00')
+l('sys/bus/acpi/devices/LNXTHERM:00', '../../../devices/LNXSYSTM:00/LNXTHERM:00')
+l('sys/bus/acpi/devices/device:15', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13/device:14/device:15')
+l('sys/bus/acpi/devices/IBM0079:00', '../../../devices/LNXSYSTM:00/device:00/IBM0079:00')
+l('sys/bus/acpi/devices/device:1d', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1d')
+l('sys/bus/acpi/devices/PNP0C0D:00', '../../../devices/LNXSYSTM:00/device:00/PNP0C0D:00')
+l('sys/bus/acpi/devices/device:23', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/device:22/device:23')
+l('sys/bus/acpi/devices/device:19', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:19')
+l('sys/bus/acpi/devices/device:12', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:11/device:12')
+l('sys/bus/acpi/devices/device:1a', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1a')
+l('sys/bus/acpi/devices/device:00', '../../../devices/LNXSYSTM:00/device:00')
+l('sys/bus/acpi/devices/PNP0800:00', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0800:00')
+l('sys/bus/acpi/devices/PNP0C02:00', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C02:00')
+l('sys/bus/acpi/devices/device:10', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0f/device:10')
+l('sys/bus/acpi/devices/PNP0100:00', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0100:00')
+l('sys/bus/acpi/devices/device:0d', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0d')
+l('sys/bus/acpi/devices/IBM0068:00', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/IBM0068:00')
+l('sys/bus/acpi/devices/device:25', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:25')
+l('sys/bus/acpi/devices/PNP0C01:00', '../../../devices/LNXSYSTM:00/device:00/PNP0C01:00')
+l('sys/bus/acpi/devices/device:01', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01')
+l('sys/bus/acpi/devices/PNP0C0F:07', '../../../devices/LNXSYSTM:00/device:00/PNP0C0F:07')
+l('sys/bus/acpi/devices/PNP0C0F:04', '../../../devices/LNXSYSTM:00/device:00/PNP0C0F:04')
+l('sys/bus/acpi/devices/device:1b', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1a/device:1b')
+l('sys/bus/acpi/devices/device:24', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/device:22/device:24')
+l('sys/bus/acpi/devices/device:1e', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1d/device:1e')
+l('sys/bus/acpi/devices/ACPI0007:00', '../../../devices/LNXSYSTM:00/ACPI0007:00')
+l('sys/bus/acpi/devices/LNXTHERM:02', '../../../devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:02')
+l('sys/bus/acpi/devices/PNP0C09:00', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00')
+l('sys/bus/acpi/devices/device:20', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:20')
+l('sys/bus/acpi/devices/PNP0C0F:02', '../../../devices/LNXSYSTM:00/device:00/PNP0C0F:02')
+l('sys/bus/acpi/devices/LNXSYSTM:00', '../../../devices/LNXSYSTM:00')
+l('sys/bus/acpi/devices/device:05', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/device:05')
+l('sys/bus/acpi/devices/PNP0C0F:00', '../../../devices/LNXSYSTM:00/device:00/PNP0C0F:00')
+l('sys/bus/acpi/devices/device:0f', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0f')
+l('sys/bus/acpi/devices/device:16', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:16')
+l('sys/bus/acpi/devices/device:09', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/device:09')
+l('sys/bus/acpi/devices/device:07', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07')
+l('sys/bus/acpi/devices/device:03', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/device:03')
+l('sys/bus/acpi/devices/device:22', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/device:22')
+l('sys/bus/acpi/devices/PNP0C0F:01', '../../../devices/LNXSYSTM:00/device:00/PNP0C0F:01')
+l('sys/bus/acpi/devices/PNP0C0F:06', '../../../devices/LNXSYSTM:00/device:00/PNP0C0F:06')
+l('sys/bus/acpi/devices/device:0a', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/device:0a')
+l('sys/bus/acpi/devices/PNP0200:00', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0200:00')
+l('sys/bus/acpi/devices/device:14', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13/device:14')
+l('sys/bus/acpi/devices/IBM0057:00', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/IBM0057:00')
+l('sys/bus/acpi/devices/PNP0B00:00', '../../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0B00:00')
+l('sys/bus/acpi/devices/PNP0C0F:03', '../../../devices/LNXSYSTM:00/device:00/PNP0C0F:03')
+l('sys/bus/acpi/devices/LNXPWRBN:00', '../../../devices/LNXSYSTM:00/LNXPWRBN:00')
+d('sys/bus/serio', 0o755)
+f('sys/bus/serio/drivers_autoprobe', 0o644, b'1\n')
+d('sys/bus/serio/drivers', 0o755)
+d('sys/bus/serio/drivers/psmouse', 0o755)
+l('sys/bus/serio/drivers/psmouse/module', '../../../../module/psmouse')
+l('sys/bus/serio/drivers/psmouse/serio1', '../../../../devices/platform/i8042/serio1')
+f('sys/bus/serio/drivers/psmouse/bind_mode', 0o644, b'auto\n')
+f('sys/bus/serio/drivers/psmouse/description', 0o644, b'PS/2 mouse driver\n')
+d('sys/bus/serio/drivers/atkbd', 0o755)
+l('sys/bus/serio/drivers/atkbd/serio0', '../../../../devices/platform/i8042/serio0')
+l('sys/bus/serio/drivers/atkbd/module', '../../../../module/atkbd')
+f('sys/bus/serio/drivers/atkbd/bind_mode', 0o644, b'auto\n')
+f('sys/bus/serio/drivers/atkbd/description', 0o644, b'AT and PS/2 keyboard driver\n')
+d('sys/bus/serio/devices', 0o755)
+l('sys/bus/serio/devices/serio0', '../../../devices/platform/i8042/serio0')
+l('sys/bus/serio/devices/serio1', '../../../devices/platform/i8042/serio1')
+d('sys/bus/scsi', 0o755)
+f('sys/bus/scsi/drivers_autoprobe', 0o644, b'1\n')
+d('sys/bus/scsi/drivers', 0o755)
+d('sys/bus/scsi/drivers/sd', 0o755)
+l('sys/bus/scsi/drivers/sd/7:0:0:0', '../../../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0')
+l('sys/bus/scsi/drivers/sd/0:0:0:0', '../../../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0')
+d('sys/bus/scsi/drivers/sr', 0o755)
+l('sys/bus/scsi/drivers/sr/4:0:0:0', '../../../../devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0')
+d('sys/bus/scsi/devices', 0o755)
+l('sys/bus/scsi/devices/target4:0:0', '../../../devices/pci0000:00/0000:00:1f.1/host4/target4:0:0')
+l('sys/bus/scsi/devices/host0', '../../../devices/pci0000:00/0000:00:1f.2/host0')
+l('sys/bus/scsi/devices/host5', '../../../devices/pci0000:00/0000:00:1f.1/host5')
+l('sys/bus/scsi/devices/host1', '../../../devices/pci0000:00/0000:00:1f.2/host1')
+l('sys/bus/scsi/devices/target0:0:0', '../../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0')
+l('sys/bus/scsi/devices/host4', '../../../devices/pci0000:00/0000:00:1f.1/host4')
+l('sys/bus/scsi/devices/7:0:0:0', '../../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0')
+l('sys/bus/scsi/devices/target7:0:0', '../../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0')
+l('sys/bus/scsi/devices/0:0:0:0', '../../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0')
+l('sys/bus/scsi/devices/host2', '../../../devices/pci0000:00/0000:00:1f.2/host2')
+l('sys/bus/scsi/devices/host7', '../../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7')
+l('sys/bus/scsi/devices/4:0:0:0', '../../../devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0')
+l('sys/bus/scsi/devices/host3', '../../../devices/pci0000:00/0000:00:1f.2/host3')
+d('sys/bus/usb', 0o755)
+f('sys/bus/usb/drivers_autoprobe', 0o644, b'1\n')
+d('sys/bus/usb/drivers', 0o755)
+d('sys/bus/usb/drivers/usb-storage', 0o755)
+l('sys/bus/usb/drivers/usb-storage/module', '../../../../module/usb_storage')
+l('sys/bus/usb/drivers/usb-storage/5-1:1.0', '../../../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0')
+d('sys/bus/usb/drivers/cdc_acm', 0o755)
+l('sys/bus/usb/drivers/cdc_acm/5-2:1.1', '../../../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1')
+l('sys/bus/usb/drivers/cdc_acm/5-2:1.0', '../../../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0')
+l('sys/bus/usb/drivers/cdc_acm/module', '../../../../module/cdc_acm')
+d('sys/bus/usb/drivers/usbhid', 0o755)
+l('sys/bus/usb/drivers/usbhid/3-1:1.0', '../../../../devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0')
+l('sys/bus/usb/drivers/usbhid/module', '../../../../module/usbhid')
+d('sys/bus/usb/drivers/hub', 0o755)
+l('sys/bus/usb/drivers/hub/3-0:1.0', '../../../../devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0')
+l('sys/bus/usb/drivers/hub/1-0:1.0', '../../../../devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0')
+l('sys/bus/usb/drivers/hub/4-0:1.0', '../../../../devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0')
+l('sys/bus/usb/drivers/hub/module', '../../../../module/usbcore')
+l('sys/bus/usb/drivers/hub/2-0:1.0', '../../../../devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0')
+l('sys/bus/usb/drivers/hub/5-0:1.0', '../../../../devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0')
+d('sys/bus/usb/drivers/usb', 0o755)
+l('sys/bus/usb/drivers/usb/usb5', '../../../../devices/pci0000:00/0000:00:1d.7/usb5')
+l('sys/bus/usb/drivers/usb/usb1', '../../../../devices/pci0000:00/0000:00:1d.0/usb1')
+l('sys/bus/usb/drivers/usb/4-2', '../../../../devices/pci0000:00/0000:00:1d.3/usb4/4-2')
+l('sys/bus/usb/drivers/usb/5-1', '../../../../devices/pci0000:00/0000:00:1d.7/usb5/5-1')
+l('sys/bus/usb/drivers/usb/5-2', '../../../../devices/pci0000:00/0000:00:1d.7/usb5/5-2')
+l('sys/bus/usb/drivers/usb/4-1', '../../../../devices/pci0000:00/0000:00:1d.3/usb4/4-1')
+l('sys/bus/usb/drivers/usb/module', '../../../../module/usbcore')
+l('sys/bus/usb/drivers/usb/usb4', '../../../../devices/pci0000:00/0000:00:1d.3/usb4')
+l('sys/bus/usb/drivers/usb/usb3', '../../../../devices/pci0000:00/0000:00:1d.2/usb3')
+l('sys/bus/usb/drivers/usb/usb2', '../../../../devices/pci0000:00/0000:00:1d.1/usb2')
+l('sys/bus/usb/drivers/usb/3-1', '../../../../devices/pci0000:00/0000:00:1d.2/usb3/3-1')
+d('sys/bus/usb/drivers/usbfs', 0o755)
+l('sys/bus/usb/drivers/usbfs/module', '../../../../module/usbcore')
+d('sys/bus/usb/devices', 0o755)
+l('sys/bus/usb/devices/4-1:1.3', '../../../devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.3')
+l('sys/bus/usb/devices/5-2:1.4', '../../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.4')
+l('sys/bus/usb/devices/usb5', '../../../devices/pci0000:00/0000:00:1d.7/usb5')
+l('sys/bus/usb/devices/4-1:1.0', '../../../devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0')
+l('sys/bus/usb/devices/5-2:1.2', '../../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2')
+l('sys/bus/usb/devices/3-0:1.0', '../../../devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0')
+l('sys/bus/usb/devices/usb1', '../../../devices/pci0000:00/0000:00:1d.0/usb1')
+l('sys/bus/usb/devices/4-2', '../../../devices/pci0000:00/0000:00:1d.3/usb4/4-2')
+l('sys/bus/usb/devices/5-2:1.1', '../../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1')
+l('sys/bus/usb/devices/1-0:1.0', '../../../devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0')
+l('sys/bus/usb/devices/5-1', '../../../devices/pci0000:00/0000:00:1d.7/usb5/5-1')
+l('sys/bus/usb/devices/5-2:1.10', '../../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.10')
+l('sys/bus/usb/devices/4-0:1.0', '../../../devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0')
+l('sys/bus/usb/devices/5-2:1.0', '../../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0')
+l('sys/bus/usb/devices/5-2', '../../../devices/pci0000:00/0000:00:1d.7/usb5/5-2')
+l('sys/bus/usb/devices/5-2:1.9', '../../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.9')
+l('sys/bus/usb/devices/3-1:1.0', '../../../devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0')
+l('sys/bus/usb/devices/5-2:1.13', '../../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.13')
+l('sys/bus/usb/devices/5-2:1.5', '../../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.5')
+l('sys/bus/usb/devices/4-1', '../../../devices/pci0000:00/0000:00:1d.3/usb4/4-1')
+l('sys/bus/usb/devices/4-1:1.2', '../../../devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2')
+l('sys/bus/usb/devices/usb4', '../../../devices/pci0000:00/0000:00:1d.3/usb4')
+l('sys/bus/usb/devices/2-0:1.0', '../../../devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0')
+l('sys/bus/usb/devices/5-2:1.11', '../../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.11')
+l('sys/bus/usb/devices/usb3', '../../../devices/pci0000:00/0000:00:1d.2/usb3')
+l('sys/bus/usb/devices/5-2:1.12', '../../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.12')
+l('sys/bus/usb/devices/5-2:1.3', '../../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3')
+l('sys/bus/usb/devices/5-2:1.6', '../../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.6')
+l('sys/bus/usb/devices/4-1:1.1', '../../../devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1')
+l('sys/bus/usb/devices/5-1:1.0', '../../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0')
+l('sys/bus/usb/devices/5-0:1.0', '../../../devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0')
+l('sys/bus/usb/devices/4-2:1.0', '../../../devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0')
+l('sys/bus/usb/devices/usb2', '../../../devices/pci0000:00/0000:00:1d.1/usb2')
+l('sys/bus/usb/devices/3-1', '../../../devices/pci0000:00/0000:00:1d.2/usb3/3-1')
+d('sys/bus/pci', 0o755)
+f('sys/bus/pci/drivers_autoprobe', 0o644, b'1\n')
+d('sys/bus/pci/drivers', 0o755)
+d('sys/bus/pci/drivers/pcieport-driver', 0o755)
+l('sys/bus/pci/drivers/pcieport-driver/0000:00:1c.2', '../../../../devices/pci0000:00/0000:00:1c.2')
+l('sys/bus/pci/drivers/pcieport-driver/0000:00:1c.1', '../../../../devices/pci0000:00/0000:00:1c.1')
+l('sys/bus/pci/drivers/pcieport-driver/0000:00:1c.3', '../../../../devices/pci0000:00/0000:00:1c.3')
+l('sys/bus/pci/drivers/pcieport-driver/0000:00:1c.0', '../../../../devices/pci0000:00/0000:00:1c.0')
+l('sys/bus/pci/drivers/pcieport-driver/0000:00:01.0', '../../../../devices/pci0000:00/0000:00:01.0')
+d('sys/bus/pci/drivers/uhci_hcd', 0o755)
+l('sys/bus/pci/drivers/uhci_hcd/0000:00:1d.3', '../../../../devices/pci0000:00/0000:00:1d.3')
+l('sys/bus/pci/drivers/uhci_hcd/module', '../../../../module/uhci_hcd')
+l('sys/bus/pci/drivers/uhci_hcd/0000:00:1d.0', '../../../../devices/pci0000:00/0000:00:1d.0')
+l('sys/bus/pci/drivers/uhci_hcd/0000:00:1d.2', '../../../../devices/pci0000:00/0000:00:1d.2')
+l('sys/bus/pci/drivers/uhci_hcd/0000:00:1d.1', '../../../../devices/pci0000:00/0000:00:1d.1')
+d('sys/bus/pci/drivers/HDA Intel', 0o755)
+l('sys/bus/pci/drivers/HDA Intel/0000:00:1b.0', '../../../../devices/pci0000:00/0000:00:1b.0')
+l('sys/bus/pci/drivers/HDA Intel/module', '../../../../module/snd_hda_intel')
+d('sys/bus/pci/drivers/ata_piix', 0o755)
+l('sys/bus/pci/drivers/ata_piix/0000:00:1f.1', '../../../../devices/pci0000:00/0000:00:1f.1')
+d('sys/bus/pci/drivers/yenta_cardbus', 0o755)
+l('sys/bus/pci/drivers/yenta_cardbus/module', '../../../../module/yenta_socket')
+l('sys/bus/pci/drivers/yenta_cardbus/0000:15:00.0', '../../../../devices/pci0000:00/0000:00:1e.0/0000:15:00.0')
+d('sys/bus/pci/drivers/e1000e', 0o755)
+l('sys/bus/pci/drivers/e1000e/0000:02:00.0', '../../../../devices/pci0000:00/0000:00:1c.0/0000:02:00.0')
+l('sys/bus/pci/drivers/e1000e/module', '../../../../module/e1000e')
+d('sys/bus/pci/drivers/iwl3945', 0o755)
+l('sys/bus/pci/drivers/iwl3945/module', '../../../../module/iwl3945')
+l('sys/bus/pci/drivers/iwl3945/0000:03:00.0', '../../../../devices/pci0000:00/0000:00:1c.1/0000:03:00.0')
+d('sys/bus/pci/drivers/ehci_hcd', 0o755)
+l('sys/bus/pci/drivers/ehci_hcd/module', '../../../../module/ehci_hcd')
+d('sys/bus/pci/drivers/agpgart-intel', 0o755)
+l('sys/bus/pci/drivers/agpgart-intel/module', '../../../../module/intel_agp')
+d('sys/bus/pci/drivers/ahci', 0o755)
+l('sys/bus/pci/drivers/ahci/module', '../../../../module/ahci')
+l('sys/bus/pci/drivers/ahci/0000:00:1f.2', '../../../../devices/pci0000:00/0000:00:1f.2')
+d('sys/bus/pci/devices', 0o755)
+l('sys/bus/pci/devices/0000:00:1d.3', '../../../devices/pci0000:00/0000:00:1d.3')
+l('sys/bus/pci/devices/0000:00:1c.2', '../../../devices/pci0000:00/0000:00:1c.2')
+l('sys/bus/pci/devices/0000:00:1b.0', '../../../devices/pci0000:00/0000:00:1b.0')
+l('sys/bus/pci/devices/0000:02:00.0', '../../../devices/pci0000:00/0000:00:1c.0/0000:02:00.0')
+l('sys/bus/pci/devices/0000:00:1c.1', '../../../devices/pci0000:00/0000:00:1c.1')
+l('sys/bus/pci/devices/0000:00:00.0', '../../../devices/pci0000:00/0000:00:00.0')
+l('sys/bus/pci/devices/0000:01:00.0', '../../../devices/pci0000:00/0000:00:01.0/0000:01:00.0')
+l('sys/bus/pci/devices/0000:00:1c.3', '../../../devices/pci0000:00/0000:00:1c.3')
+l('sys/bus/pci/devices/0000:00:1f.0', '../../../devices/pci0000:00/0000:00:1f.0')
+l('sys/bus/pci/devices/0000:00:1c.0', '../../../devices/pci0000:00/0000:00:1c.0')
+l('sys/bus/pci/devices/0000:15:00.0', '../../../devices/pci0000:00/0000:00:1e.0/0000:15:00.0')
+l('sys/bus/pci/devices/0000:00:1f.3', '../../../devices/pci0000:00/0000:00:1f.3')
+l('sys/bus/pci/devices/0000:00:1d.0', '../../../devices/pci0000:00/0000:00:1d.0')
+l('sys/bus/pci/devices/0000:00:1f.2', '../../../devices/pci0000:00/0000:00:1f.2')
+l('sys/bus/pci/devices/0000:00:1d.2', '../../../devices/pci0000:00/0000:00:1d.2')
+l('sys/bus/pci/devices/0000:03:00.0', '../../../devices/pci0000:00/0000:00:1c.1/0000:03:00.0')
+l('sys/bus/pci/devices/0000:00:01.0', '../../../devices/pci0000:00/0000:00:01.0')
+l('sys/bus/pci/devices/0000:00:1f.1', '../../../devices/pci0000:00/0000:00:1f.1')
+l('sys/bus/pci/devices/0000:00:1e.0', '../../../devices/pci0000:00/0000:00:1e.0')
+l('sys/bus/pci/devices/0000:00:1d.1', '../../../devices/pci0000:00/0000:00:1d.1')
+d('sys/bus/pnp', 0o755)
+f('sys/bus/pnp/drivers_autoprobe', 0o644, b'1\n')
+d('sys/bus/pnp/drivers', 0o755)
+d('sys/bus/pnp/drivers/system', 0o755)
+l('sys/bus/pnp/drivers/system/00:02', '../../../../devices/pnp0/00:02')
+l('sys/bus/pnp/drivers/system/00:00', '../../../../devices/pnp0/00:00')
+d('sys/bus/pnp/drivers/i8042 kbd', 0o755)
+l('sys/bus/pnp/drivers/i8042 kbd/00:08', '../../../../devices/pnp0/00:08')
+d('sys/bus/pnp/drivers/rtc_cmos', 0o755)
+l('sys/bus/pnp/drivers/rtc_cmos/00:07', '../../../../devices/pnp0/00:07')
+d('sys/bus/pnp/drivers/i8042 aux', 0o755)
+l('sys/bus/pnp/drivers/i8042 aux/00:09', '../../../../devices/pnp0/00:09')
+d('sys/bus/pnp/devices', 0o755)
+l('sys/bus/pnp/devices/00:04', '../../../devices/pnp0/00:04')
+l('sys/bus/pnp/devices/00:0a', '../../../devices/pnp0/00:0a')
+l('sys/bus/pnp/devices/00:03', '../../../devices/pnp0/00:03')
+l('sys/bus/pnp/devices/00:02', '../../../devices/pnp0/00:02')
+l('sys/bus/pnp/devices/00:00', '../../../devices/pnp0/00:00')
+l('sys/bus/pnp/devices/00:09', '../../../devices/pnp0/00:09')
+l('sys/bus/pnp/devices/00:07', '../../../devices/pnp0/00:07')
+l('sys/bus/pnp/devices/00:06', '../../../devices/pnp0/00:06')
+l('sys/bus/pnp/devices/00:08', '../../../devices/pnp0/00:08')
+l('sys/bus/pnp/devices/00:05', '../../../devices/pnp0/00:05')
+l('sys/bus/pnp/devices/00:01', '../../../devices/pnp0/00:01')
+d('sys/bus/pcmcia', 0o755)
+f('sys/bus/pcmcia/drivers_autoprobe', 0o644, b'1\n')
+d('sys/bus/platform', 0o755)
+f('sys/bus/platform/drivers_autoprobe', 0o644, b'1\n')
+d('sys/bus/platform/drivers', 0o755)
+d('sys/bus/platform/drivers/pcspkr', 0o755)
+l('sys/bus/platform/drivers/pcspkr/pcspkr', '../../../../devices/platform/pcspkr')
+l('sys/bus/platform/drivers/pcspkr/module', '../../../../module/pcspkr')
+d('sys/bus/platform/drivers/serial8250', 0o755)
+l('sys/bus/platform/drivers/serial8250/serial8250', '../../../../devices/platform/serial8250')
+d('sys/bus/platform/drivers/thinkpad_acpi', 0o755)
+l('sys/bus/platform/drivers/thinkpad_acpi/module', '../../../../module/thinkpad_acpi')
+l('sys/bus/platform/drivers/thinkpad_acpi/thinkpad_acpi', '../../../../devices/platform/thinkpad_acpi')
+f('sys/bus/platform/drivers/thinkpad_acpi/version', 0o644, b'ThinkPad ACPI Extras v0.21\n')
+f('sys/bus/platform/drivers/thinkpad_acpi/debug_level', 0o644, b'0x0000\n')
+f('sys/bus/platform/drivers/thinkpad_acpi/interface_version', 0o644, b'0x00020200\n')
+d('sys/bus/platform/drivers/vesafb', 0o755)
+l('sys/bus/platform/drivers/vesafb/vesafb.0', '../../../../devices/platform/vesafb.0')
+d('sys/bus/platform/drivers/thinkpad_hwmon', 0o755)
+l('sys/bus/platform/drivers/thinkpad_hwmon/module', '../../../../module/thinkpad_acpi')
+l('sys/bus/platform/drivers/thinkpad_hwmon/thinkpad_hwmon', '../../../../devices/platform/thinkpad_hwmon')
+f('sys/bus/platform/drivers/thinkpad_hwmon/version', 0o644, b'ThinkPad ACPI Extras v0.21\n')
+f('sys/bus/platform/drivers/thinkpad_hwmon/fan_watchdog', 0o644, b'0\n')
+f('sys/bus/platform/drivers/thinkpad_hwmon/debug_level', 0o644, b'0x0000\n')
+f('sys/bus/platform/drivers/thinkpad_hwmon/interface_version', 0o644, b'0x00020200\n')
+d('sys/bus/platform/drivers/i8042', 0o755)
+l('sys/bus/platform/drivers/i8042/i8042', '../../../../devices/platform/i8042')
+d('sys/bus/platform/devices', 0o755)
+l('sys/bus/platform/devices/pcspkr', '../../../devices/platform/pcspkr')
+l('sys/bus/platform/devices/vesafb.0', '../../../devices/platform/vesafb.0')
+l('sys/bus/platform/devices/dock.0', '../../../devices/platform/dock.0')
+l('sys/bus/platform/devices/serial8250', '../../../devices/platform/serial8250')
+l('sys/bus/platform/devices/thinkpad_acpi', '../../../devices/platform/thinkpad_acpi')
+l('sys/bus/platform/devices/thinkpad_hwmon', '../../../devices/platform/thinkpad_hwmon')
+l('sys/bus/platform/devices/microcode', '../../../devices/platform/microcode')
+l('sys/bus/platform/devices/i8042', '../../../devices/platform/i8042')
+d('sys/fs', 0o775)
+d('sys/fs/fuse', 0o775)
+d('sys/fs/fuse/connections', 0o775)
+d('sys/fs/fuse/connections/16', 0o775)
+f('sys/fs/fuse/connections/16/waiting', 0o664, b'0\n')
+f('sys/fs/fuse/connections/16/abort', 0o664, b'')
+d('sys/dev', 0o755)
+d('sys/dev/char', 0o755)
+l('sys/dev/char/4:39', '../../devices/virtual/tty/tty39')
+l('sys/dev/char/116:33', '../../devices/virtual/sound/timer')
+l('sys/dev/char/10:229', '../../devices/virtual/misc/fuse')
+l('sys/dev/char/4:23', '../../devices/virtual/tty/tty23')
+l('sys/dev/char/4:19', '../../devices/virtual/tty/tty19')
+l('sys/dev/char/252:1', '../../devices/pci0000:00/0000:00:1d.0/usb1/usb_endpoint/usbdev1.1_ep00')
+l('sys/dev/char/4:48', '../../devices/virtual/tty/tty48')
+l('sys/dev/char/7:129', '../../devices/virtual/vc/vcsa1')
+l('sys/dev/char/4:34', '../../devices/virtual/tty/tty34')
+l('sys/dev/char/189:0', '../../devices/pci0000:00/0000:00:1d.0/usb1')
+l('sys/dev/char/4:61', '../../devices/virtual/tty/tty61')
+l('sys/dev/char/4:5', '../../devices/virtual/tty/tty5')
+l('sys/dev/char/10:1', '../../devices/virtual/misc/psaux')
+l('sys/dev/char/4:47', '../../devices/virtual/tty/tty47')
+l('sys/dev/char/254:2', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/bsg/7:0:0:0')
+l('sys/dev/char/252:7', '../../devices/pci0000:00/0000:00:1d.3/usb4/usb_endpoint/usbdev4.1_ep00')
+l('sys/dev/char/7:1', '../../devices/virtual/vc/vcs1')
+l('sys/dev/char/4:37', '../../devices/virtual/tty/tty37')
+l('sys/dev/char/4:3', '../../devices/virtual/tty/tty3')
+l('sys/dev/char/252:3', '../../devices/pci0000:00/0000:00:1d.1/usb2/usb_endpoint/usbdev2.1_ep00')
+l('sys/dev/char/1:3', '../../devices/virtual/mem/null')
+l('sys/dev/char/14:12', '../../devices/pci0000:00/0000:00:1b.0/sound/card0/adsp')
+l('sys/dev/char/7:0', '../../devices/virtual/vc/vcs')
+l('sys/dev/char/252:14', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep02')
+l('sys/dev/char/4:52', '../../devices/virtual/tty/tty52')
+l('sys/dev/char/252:18', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep04')
+l('sys/dev/char/1:5', '../../devices/virtual/mem/zero')
+l('sys/dev/char/13:66', '../../devices/platform/pcspkr/input/input2/event2')
+l('sys/dev/char/10:223', '../../devices/virtual/misc/uinput')
+l('sys/dev/char/7:2', '../../devices/virtual/vc/vcs2')
+l('sys/dev/char/4:40', '../../devices/virtual/tty/tty40')
+l('sys/dev/char/4:31', '../../devices/virtual/tty/tty31')
+l('sys/dev/char/252:21', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep02')
+l('sys/dev/char/4:11', '../../devices/virtual/tty/tty11')
+l('sys/dev/char/4:17', '../../devices/virtual/tty/tty17')
+l('sys/dev/char/252:31', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep84')
+l('sys/dev/char/189:256', '../../devices/pci0000:00/0000:00:1d.2/usb3')
+l('sys/dev/char/252:5', '../../devices/pci0000:00/0000:00:1d.2/usb3/usb_endpoint/usbdev3.1_ep00')
+l('sys/dev/char/7:4', '../../devices/virtual/vc/vcs4')
+l('sys/dev/char/4:38', '../../devices/virtual/tty/tty38')
+l('sys/dev/char/4:66', '../../devices/platform/serial8250/tty/ttyS2')
+l('sys/dev/char/4:0', '../../devices/virtual/tty/tty0')
+l('sys/dev/char/21:0', '../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_generic/sg0')
+l('sys/dev/char/7:134', '../../devices/virtual/vc/vcsa6')
+l('sys/dev/char/116:24', '../../devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D0c')
+l('sys/dev/char/4:29', '../../devices/virtual/tty/tty29')
+l('sys/dev/char/21:2', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_generic/sg2')
+l('sys/dev/char/4:27', '../../devices/virtual/tty/tty27')
+l('sys/dev/char/4:21', '../../devices/virtual/tty/tty21')
+l('sys/dev/char/13:64', '../../devices/platform/i8042/serio0/input/input0/event0')
+l('sys/dev/char/252:30', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/usb_endpoint/usbdev5.9_ep83')
+l('sys/dev/char/4:51', '../../devices/virtual/tty/tty51')
+l('sys/dev/char/254:1', '../../devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/bsg/4:0:0:0')
+l('sys/dev/char/4:18', '../../devices/virtual/tty/tty18')
+l('sys/dev/char/7:3', '../../devices/virtual/vc/vcs3')
+l('sys/dev/char/252:32', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep02')
+l('sys/dev/char/252:27', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/usb_endpoint/usbdev5.9_ep81')
+l('sys/dev/char/252:12', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep81')
+l('sys/dev/char/1:1', '../../devices/virtual/mem/mem')
+l('sys/dev/char/189:386', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-2')
+l('sys/dev/char/10:62', '../../devices/virtual/misc/network_latency')
+l('sys/dev/char/252:4', '../../devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/usb_endpoint/usbdev3.1_ep81')
+l('sys/dev/char/5:1', '../../devices/virtual/tty/console')
+l('sys/dev/char/1:7', '../../devices/virtual/mem/full')
+l('sys/dev/char/7:5', '../../devices/virtual/vc/vcs5')
+l('sys/dev/char/4:4', '../../devices/virtual/tty/tty4')
+l('sys/dev/char/4:15', '../../devices/virtual/tty/tty15')
+l('sys/dev/char/4:9', '../../devices/virtual/tty/tty9')
+l('sys/dev/char/4:20', '../../devices/virtual/tty/tty20')
+l('sys/dev/char/10:228', '../../devices/virtual/misc/hpet')
+l('sys/dev/char/4:59', '../../devices/virtual/tty/tty59')
+l('sys/dev/char/252:2', '../../devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/usb_endpoint/usbdev2.1_ep81')
+l('sys/dev/char/4:7', '../../devices/virtual/tty/tty7')
+l('sys/dev/char/4:35', '../../devices/virtual/tty/tty35')
+l('sys/dev/char/254:0', '../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0')
+l('sys/dev/char/189:128', '../../devices/pci0000:00/0000:00:1d.1/usb2')
+l('sys/dev/char/10:184', '../../devices/virtual/misc/microcode')
+l('sys/dev/char/7:131', '../../devices/virtual/vc/vcsa3')
+l('sys/dev/char/116:1', '../../devices/virtual/sound/seq')
+l('sys/dev/char/252:17', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep84')
+l('sys/dev/char/10:61', '../../devices/virtual/misc/network_throughput')
+l('sys/dev/char/7:130', '../../devices/virtual/vc/vcsa2')
+l('sys/dev/char/252:0', '../../devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/usb_endpoint/usbdev1.1_ep81')
+l('sys/dev/char/4:33', '../../devices/virtual/tty/tty33')
+l('sys/dev/char/4:10', '../../devices/virtual/tty/tty10')
+l('sys/dev/char/13:71', '../../devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/event7')
+l('sys/dev/char/252:10', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep81')
+l('sys/dev/char/253:0', '../../devices/pnp0/00:07/rtc/rtc0')
+l('sys/dev/char/252:19', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-1/usb_endpoint/usbdev4.2_ep00')
+l('sys/dev/char/7:10', '../../devices/virtual/vc/vcs10')
+l('sys/dev/char/4:42', '../../devices/virtual/tty/tty42')
+l('sys/dev/char/10:144', '../../devices/virtual/misc/nvram')
+l('sys/dev/char/4:63', '../../devices/virtual/tty/tty63')
+l('sys/dev/char/252:25', '../../devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/usb_endpoint/usbdev3.4_ep81')
+l('sys/dev/char/189:520', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-2')
+l('sys/dev/char/4:55', '../../devices/virtual/tty/tty55')
+l('sys/dev/char/13:33', '../../devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/mouse1')
+l('sys/dev/char/13:70', '../../devices/virtual/input/input6/event6')
+l('sys/dev/char/252:29', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep01')
+l('sys/dev/char/4:45', '../../devices/virtual/tty/tty45')
+l('sys/dev/char/4:56', '../../devices/virtual/tty/tty56')
+l('sys/dev/char/10:60', '../../devices/virtual/misc/device-mapper')
+l('sys/dev/char/5:2', '../../devices/virtual/tty/ptmx')
+l('sys/dev/char/252:8', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/usb_endpoint/usbdev5.1_ep81')
+l('sys/dev/char/14:3', '../../devices/pci0000:00/0000:00:1b.0/sound/card0/dsp')
+l('sys/dev/char/13:68', '../../devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/event4')
+l('sys/dev/char/13:67', '../../devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/event3')
+l('sys/dev/char/1:4', '../../devices/virtual/mem/port')
+l('sys/dev/char/116:0', '../../devices/pci0000:00/0000:00:1b.0/sound/card0/controlC0')
+l('sys/dev/char/4:46', '../../devices/virtual/tty/tty46')
+l('sys/dev/char/4:41', '../../devices/virtual/tty/tty41')
+l('sys/dev/char/189:512', '../../devices/pci0000:00/0000:00:1d.7/usb5')
+l('sys/dev/char/4:62', '../../devices/virtual/tty/tty62')
+l('sys/dev/char/252:15', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep83')
+l('sys/dev/char/7:133', '../../devices/virtual/vc/vcsa5')
+l('sys/dev/char/4:2', '../../devices/virtual/tty/tty2')
+l('sys/dev/char/1:8', '../../devices/virtual/mem/random')
+l('sys/dev/char/7:138', '../../devices/virtual/vc/vcsa10')
+l('sys/dev/char/4:64', '../../devices/platform/serial8250/tty/ttyS0')
+l('sys/dev/char/4:1', '../../devices/virtual/tty/tty1')
+l('sys/dev/char/4:28', '../../devices/virtual/tty/tty28')
+l('sys/dev/char/13:32', '../../devices/platform/i8042/serio1/input/input1/mouse0')
+l('sys/dev/char/4:44', '../../devices/virtual/tty/tty44')
+l('sys/dev/char/4:36', '../../devices/virtual/tty/tty36')
+l('sys/dev/char/4:43', '../../devices/virtual/tty/tty43')
+l('sys/dev/char/7:128', '../../devices/virtual/vc/vcsa')
+l('sys/dev/char/4:60', '../../devices/virtual/tty/tty60')
+l('sys/dev/char/7:135', '../../devices/virtual/vc/vcsa7')
+l('sys/dev/char/4:6', '../../devices/virtual/tty/tty6')
+l('sys/dev/char/4:49', '../../devices/virtual/tty/tty49')
+l('sys/dev/char/189:518', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-1')
+l('sys/dev/char/29:0', '../../devices/platform/vesafb.0/graphics/fb0')
+l('sys/dev/char/252:23', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-2/usb_endpoint/usbdev4.3_ep00')
+l('sys/dev/char/10:227', '../../devices/virtual/misc/mcelog')
+l('sys/dev/char/4:14', '../../devices/virtual/tty/tty14')
+l('sys/dev/char/4:54', '../../devices/virtual/tty/tty54')
+l('sys/dev/char/7:132', '../../devices/virtual/vc/vcsa4')
+l('sys/dev/char/5:0', '../../devices/virtual/tty/tty')
+l('sys/dev/char/252:26', '../../devices/pci0000:00/0000:00:1d.2/usb3/3-1/usb_endpoint/usbdev3.4_ep00')
+l('sys/dev/char/1:2', '../../devices/virtual/mem/kmem')
+l('sys/dev/char/189:259', '../../devices/pci0000:00/0000:00:1d.2/usb3/3-1')
+l('sys/dev/char/252:11', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep02')
+l('sys/dev/char/4:26', '../../devices/virtual/tty/tty26')
+l('sys/dev/char/252:33', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/usb_endpoint/usbdev5.9_ep00')
+l('sys/dev/char/4:22', '../../devices/virtual/tty/tty22')
+l('sys/dev/char/10:63', '../../devices/virtual/misc/cpu_dma_latency')
+l('sys/dev/char/4:13', '../../devices/virtual/tty/tty13')
+l('sys/dev/char/116:17', '../../devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D1p')
+l('sys/dev/char/116:16', '../../devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D0p')
+l('sys/dev/char/252:16', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep03')
+l('sys/dev/char/4:8', '../../devices/virtual/tty/tty8')
+l('sys/dev/char/252:28', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep82')
+l('sys/dev/char/21:1', '../../devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/scsi_generic/sg1')
+l('sys/dev/char/4:24', '../../devices/virtual/tty/tty24')
+l('sys/dev/char/7:7', '../../devices/virtual/vc/vcs7')
+l('sys/dev/char/252:20', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep81')
+l('sys/dev/char/166:0', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0')
+l('sys/dev/char/4:58', '../../devices/virtual/tty/tty58')
+l('sys/dev/char/4:57', '../../devices/virtual/tty/tty57')
+l('sys/dev/char/189:384', '../../devices/pci0000:00/0000:00:1d.3/usb4')
+l('sys/dev/char/4:50', '../../devices/virtual/tty/tty50')
+l('sys/dev/char/7:6', '../../devices/virtual/vc/vcs6')
+l('sys/dev/char/4:25', '../../devices/virtual/tty/tty25')
+l('sys/dev/char/4:16', '../../devices/virtual/tty/tty16')
+l('sys/dev/char/4:65', '../../devices/platform/serial8250/tty/ttyS1')
+l('sys/dev/char/13:65', '../../devices/platform/i8042/serio1/input/input1/event1')
+l('sys/dev/char/13:69', '../../devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/event5')
+l('sys/dev/char/252:22', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep83')
+l('sys/dev/char/1:11', '../../devices/virtual/mem/kmsg')
+l('sys/dev/char/189:385', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-1')
+l('sys/dev/char/4:12', '../../devices/virtual/tty/tty12')
+l('sys/dev/char/252:13', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep82')
+l('sys/dev/char/1:9', '../../devices/virtual/mem/urandom')
+l('sys/dev/char/4:67', '../../devices/platform/serial8250/tty/ttyS3')
+l('sys/dev/char/13:63', '../../devices/virtual/input/mice')
+l('sys/dev/char/252:24', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/usb_endpoint/usbdev5.7_ep00')
+l('sys/dev/char/252:9', '../../devices/pci0000:00/0000:00:1d.7/usb5/usb_endpoint/usbdev5.1_ep00')
+l('sys/dev/char/4:53', '../../devices/virtual/tty/tty53')
+l('sys/dev/char/4:30', '../../devices/virtual/tty/tty30')
+l('sys/dev/char/14:4', '../../devices/pci0000:00/0000:00:1b.0/sound/card0/audio')
+l('sys/dev/char/14:0', '../../devices/pci0000:00/0000:00:1b.0/sound/card0/mixer')
+l('sys/dev/char/252:6', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/usb_endpoint/usbdev4.1_ep81')
+l('sys/dev/char/4:32', '../../devices/virtual/tty/tty32')
+d('sys/dev/block', 0o755)
+l('sys/dev/block/7:1', '../../devices/virtual/block/loop1')
+l('sys/dev/block/7:0', '../../devices/virtual/block/loop0')
+l('sys/dev/block/8:17', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/sdb1')
+l('sys/dev/block/7:2', '../../devices/virtual/block/loop2')
+l('sys/dev/block/7:4', '../../devices/virtual/block/loop4')
+l('sys/dev/block/8:8', '../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8')
+l('sys/dev/block/7:3', '../../devices/virtual/block/loop3')
+l('sys/dev/block/11:0', '../../devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0')
+l('sys/dev/block/7:5', '../../devices/virtual/block/loop5')
+l('sys/dev/block/8:5', '../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5')
+l('sys/dev/block/8:10', '../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10')
+l('sys/dev/block/8:0', '../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda')
+l('sys/dev/block/8:9', '../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9')
+l('sys/dev/block/8:7', '../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7')
+l('sys/dev/block/8:16', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb')
+l('sys/dev/block/9:0', '../../devices/virtual/block/md0')
+l('sys/dev/block/7:7', '../../devices/virtual/block/loop7')
+l('sys/dev/block/8:6', '../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6')
+l('sys/dev/block/7:6', '../../devices/virtual/block/loop6')
+l('sys/dev/block/8:1', '../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1')
+d('sys/module', 0o775)
+d('sys/module/arc4', 0o775)
+f('sys/module/arc4/initstate', 0o664, b'live\n')
+f('sys/module/arc4/srcversion', 0o664, b'0E7B177AF22D87B5B21A577\n')
+f('sys/module/arc4/refcnt', 0o664, b'2\n')
+d('sys/module/arc4/sections', 0o775)
+f('sys/module/arc4/sections/.exit.text', 0o664, b'0xffffffffa006b0dc\n')
+f('sys/module/arc4/sections/.note.gnu.build-id', 0o664, b'0xffffffffa006b0f0\n')
+f('sys/module/arc4/sections/.strtab', 0o664, b'0xffffffffa006b400\n')
+f('sys/module/arc4/sections/.bss', 0o664, b'0xffffffffa006ba00\n')
+f('sys/module/arc4/sections/.text', 0o664, b'0xffffffffa006b000\n')
+f('sys/module/arc4/sections/.init.text', 0o664, b'0xffffffffa009a000\n')
+f('sys/module/arc4/sections/.data', 0o664, b'0xffffffffa006b520\n')
+f('sys/module/arc4/sections/.symtab', 0o664, b'0xffffffffa006b118\n')
+f('sys/module/arc4/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa006b640\n')
+d('sys/module/arc4/notes', 0o775)
+f('sys/module/arc4/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00[P \tR\xc2\xa7\xdd\xf0H\xaa\x06\x1a,\xb3\xa1\xa4\x9a\x13G')
+d('sys/module/vt', 0o775)
+d('sys/module/vt/parameters', 0o775)
+f('sys/module/vt/parameters/default_grn', 0o664, b'0,0,170,85,0,0,170,170,85,85,255,255,85,85,255,255\n')
+f('sys/module/vt/parameters/default_red', 0o664, b'0,170,0,170,0,170,0,170,85,255,85,255,85,255,85,255\n')
+f('sys/module/vt/parameters/italic', 0o664, b'2\n')
+f('sys/module/vt/parameters/underline', 0o664, b'3\n')
+f('sys/module/vt/parameters/default_blu', 0o664, b'0,0,0,0,170,170,170,170,85,85,85,85,255,255,255,255\n')
+f('sys/module/vt/parameters/default_utf8', 0o664, b'1\n')
+d('sys/module/cdrom', 0o775)
+f('sys/module/cdrom/initstate', 0o664, b'live\n')
+f('sys/module/cdrom/srcversion', 0o664, b'D868CCB0789DA27F51280A8\n')
+f('sys/module/cdrom/refcnt', 0o664, b'1\n')
+d('sys/module/cdrom/holders', 0o775)
+l('sys/module/cdrom/holders/sr_mod', '../../sr_mod')
+d('sys/module/cdrom/sections', 0o775)
+f('sys/module/cdrom/sections/__ksymtab_strings', 0o664, b'0xffffffffa002fe20\n')
+f('sys/module/cdrom/sections/.exit.text', 0o664, b'0xffffffffa002e0f8\n')
+f('sys/module/cdrom/sections/.note.gnu.build-id', 0o664, b'0xffffffffa002e120\n')
+f('sys/module/cdrom/sections/.strtab', 0o664, b'0xffffffffa0030f60\n')
+f('sys/module/cdrom/sections/__ksymtab', 0o664, b'0xffffffffa002fc10\n')
+f('sys/module/cdrom/sections/.rodata', 0o664, b'0xffffffffa002e160\n')
+f('sys/module/cdrom/sections/__param', 0o664, b'0xffffffffa002fd30\n')
+f('sys/module/cdrom/sections/.bss', 0o664, b'0xffffffffa0032380\n')
+f('sys/module/cdrom/sections/.text', 0o664, b'0xffffffffa0029000\n')
+f('sys/module/cdrom/sections/.init.text', 0o664, b'0xffffffffa0034000\n')
+f('sys/module/cdrom/sections/__kcrctab', 0o664, b'0xffffffffa002fcd0\n')
+f('sys/module/cdrom/sections/.data', 0o664, b'0xffffffffa0031b80\n')
+f('sys/module/cdrom/sections/.symtab', 0o664, b'0xffffffffa002fef8\n')
+f('sys/module/cdrom/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa0031fc0\n')
+f('sys/module/cdrom/sections/.rodata.str1.1', 0o664, b'0xffffffffa002f896\n')
+d('sys/module/cdrom/notes', 0o775)
+f('sys/module/cdrom/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00C\x03\x04\xe9\x8a\x17\x19\x8b\xc7Y\xea\x1a\xa35\x85K\x9e\x1e\xf8=')
+d('sys/module/rfkill', 0o775)
+f('sys/module/rfkill/version', 0o664, b'1.0\n')
+f('sys/module/rfkill/initstate', 0o664, b'live\n')
+f('sys/module/rfkill/srcversion', 0o664, b'6B4E68548C57FD365EB4E71\n')
+f('sys/module/rfkill/refcnt', 0o664, b'2\n')
+d('sys/module/rfkill/holders', 0o775)
+l('sys/module/rfkill/holders/thinkpad_acpi', '../../thinkpad_acpi')
+d('sys/module/rfkill/parameters', 0o775)
+f('sys/module/rfkill/parameters/default_state', 0o664, b'1\n')
+d('sys/module/rfkill/sections', 0o775)
+f('sys/module/rfkill/sections/__ksymtab_gpl', 0o664, b'0xffffffffa01d9f70\n')
+f('sys/module/rfkill/sections/.smp_locks', 0o664, b'0xffffffffa01d9e80\n')
+f('sys/module/rfkill/sections/__bug_table', 0o664, b'0xffffffffa01d9e36\n')
+f('sys/module/rfkill/sections/__ksymtab_strings', 0o664, b'0xffffffffa01d9fe0\n')
+f('sys/module/rfkill/sections/.exit.text', 0o664, b'0xffffffffa01d9c88\n')
+f('sys/module/rfkill/sections/.note.gnu.build-id', 0o664, b'0xffffffffa01d9cb0\n')
+f('sys/module/rfkill/sections/.strtab', 0o664, b'0xffffffffa01dae08\n')
+f('sys/module/rfkill/sections/__ksymtab', 0o664, b'0xffffffffa01d9ee0\n')
+f('sys/module/rfkill/sections/.rodata', 0o664, b'0xffffffffa01d9cd8\n')
+f('sys/module/rfkill/sections/__param', 0o664, b'0xffffffffa01d9fb8\n')
+f('sys/module/rfkill/sections/.bss', 0o664, b'0xffffffffa01dbe00\n')
+f('sys/module/rfkill/sections/.text', 0o664, b'0xffffffffa01d9000\n')
+f('sys/module/rfkill/sections/.init.text', 0o664, b'0xffffffffa009a000\n')
+f('sys/module/rfkill/sections/__kcrctab', 0o664, b'0xffffffffa01d9f40\n')
+f('sys/module/rfkill/sections/.data', 0o664, b'0xffffffffa01db780\n')
+f('sys/module/rfkill/sections/.symtab', 0o664, b'0xffffffffa01da088\n')
+f('sys/module/rfkill/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa01dba40\n')
+f('sys/module/rfkill/sections/.rodata.str1.1', 0o664, b'0xffffffffa01d9d36\n')
+f('sys/module/rfkill/sections/__kcrctab_gpl', 0o664, b'0xffffffffa01d9fa0\n')
+d('sys/module/rfkill/notes', 0o775)
+f('sys/module/rfkill/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xd1\x1fs\x98\x9b\x97\xc4\xec\x9dd\xac:\x94m\x1e\xc0Y\xcfd"')
+d('sys/module/uinput', 0o775)
+f('sys/module/uinput/version', 0o664, b'0.3\n')
+f('sys/module/uinput/initstate', 0o664, b'live\n')
+f('sys/module/uinput/srcversion', 0o664, b'2C3E0DB9E2496AD70174B85\n')
+f('sys/module/uinput/refcnt', 0o664, b'0\n')
+d('sys/module/uinput/sections', 0o775)
+f('sys/module/uinput/sections/.smp_locks', 0o664, b'0xffffffffa0206448\n')
+f('sys/module/uinput/sections/.exit.text', 0o664, b'0xffffffffa0206278\n')
+f('sys/module/uinput/sections/.note.gnu.build-id', 0o664, b'0xffffffffa020628c\n')
+f('sys/module/uinput/sections/.strtab', 0o664, b'0xffffffffa0206c88\n')
+f('sys/module/uinput/sections/.rodata', 0o664, b'0xffffffffa02062c0\n')
+f('sys/module/uinput/sections/.bss', 0o664, b'0xffffffffa02074c0\n')
+f('sys/module/uinput/sections/.text', 0o664, b'0xffffffffa0205000\n')
+f('sys/module/uinput/sections/.init.text', 0o664, b'0xffffffffa0070000\n')
+f('sys/module/uinput/sections/.data', 0o664, b'0xffffffffa02070c0\n')
+f('sys/module/uinput/sections/.symtab', 0o664, b'0xffffffffa0206490\n')
+f('sys/module/uinput/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa0207100\n')
+f('sys/module/uinput/sections/.rodata.str1.1', 0o664, b'0xffffffffa0206398\n')
+d('sys/module/uinput/notes', 0o775)
+f('sys/module/uinput/notes/.note.gnu.build-id', 0o664, b"\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00'\n{\xdf\xe9m\x80\xea\xa8k\x8f=\x90\x8c\xe1\xf7{\x06\x15S")
+d('sys/module/fuse', 0o775)
+f('sys/module/fuse/initstate', 0o664, b'live\n')
+f('sys/module/fuse/srcversion', 0o664, b'A6C92EE44A51B1B0DC4377D\n')
+f('sys/module/fuse/refcnt', 0o664, b'3\n')
+d('sys/module/fuse/sections', 0o775)
+f('sys/module/fuse/sections/.smp_locks', 0o664, b'0xffffffffa0249d78\n')
+f('sys/module/fuse/sections/__bug_table', 0o664, b'0xffffffffa024a032\n')
+f('sys/module/fuse/sections/.exit.text', 0o664, b'0xffffffffa02493d0\n')
+f('sys/module/fuse/sections/.note.gnu.build-id', 0o664, b'0xffffffffa0249414\n')
+f('sys/module/fuse/sections/.strtab', 0o664, b'0xffffffffa024c4e8\n')
+f('sys/module/fuse/sections/.rodata', 0o664, b'0xffffffffa0249440\n')
+f('sys/module/fuse/sections/.bss', 0o664, b'0xffffffffa024e300\n')
+f('sys/module/fuse/sections/.text', 0o664, b'0xffffffffa0240000\n')
+f('sys/module/fuse/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/fuse/sections/.data', 0o664, b'0xffffffffa024dba0\n')
+f('sys/module/fuse/sections/.symtab', 0o664, b'0xffffffffa024a208\n')
+f('sys/module/fuse/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa024df40\n')
+f('sys/module/fuse/sections/.rodata.str1.1', 0o664, b'0xffffffffa0249e50\n')
+d('sys/module/fuse/notes', 0o775)
+f('sys/module/fuse/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\x7fh\xfe:\x1f\xc6\xddW\x96\x80\x16\x9fK\x7f\xba,\x8a\xc6\xf6E')
+d('sys/module/hid', 0o775)
+d('sys/module/hid/parameters', 0o775)
+f('sys/module/hid/parameters/pb_fnmode', 0o664, b'1\n')
+d('sys/module/uhci_hcd', 0o775)
+f('sys/module/uhci_hcd/initstate', 0o664, b'live\n')
+f('sys/module/uhci_hcd/srcversion', 0o664, b'E3F4B6BEC99D6670259FCC9\n')
+f('sys/module/uhci_hcd/refcnt', 0o664, b'0\n')
+d('sys/module/uhci_hcd/drivers', 0o775)
+l('sys/module/uhci_hcd/drivers/pci:uhci_hcd', '../../../bus/pci/drivers/uhci_hcd')
+d('sys/module/uhci_hcd/parameters', 0o775)
+f('sys/module/uhci_hcd/parameters/ignore_oc', 0o664, b'N\n')
+d('sys/module/uhci_hcd/sections', 0o775)
+f('sys/module/uhci_hcd/sections/.smp_locks', 0o664, b'0xffffffffa00c6850\n')
+f('sys/module/uhci_hcd/sections/.exit.text', 0o664, b'0xffffffffa00c621c\n')
+f('sys/module/uhci_hcd/sections/.note.gnu.build-id', 0o664, b'0xffffffffa00c6254\n')
+f('sys/module/uhci_hcd/sections/.strtab', 0o664, b'0xffffffffa00c7690\n')
+f('sys/module/uhci_hcd/sections/.rodata', 0o664, b'0xffffffffa00c6280\n')
+f('sys/module/uhci_hcd/sections/__param', 0o664, b'0xffffffffa00c6888\n')
+f('sys/module/uhci_hcd/sections/.bss', 0o664, b'0xffffffffa00c8400\n')
+f('sys/module/uhci_hcd/sections/.text', 0o664, b'0xffffffffa00c2000\n')
+f('sys/module/uhci_hcd/sections/.init.text', 0o664, b'0xffffffffa0027000\n')
+f('sys/module/uhci_hcd/sections/.data', 0o664, b'0xffffffffa00c7ee0\n')
+f('sys/module/uhci_hcd/sections/.symtab', 0o664, b'0xffffffffa00c68b0\n')
+f('sys/module/uhci_hcd/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa00c8040\n')
+f('sys/module/uhci_hcd/sections/.rodata.str1.1', 0o664, b'0xffffffffa00c67d2\n')
+d('sys/module/uhci_hcd/notes', 0o775)
+f('sys/module/uhci_hcd/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00t\xd0\xa5\xd2A\xa2\x874\x12\xb5\xf6\x9c\xff\xb9\xee`\x8d\x9f[\x04')
+d('sys/module/crypto_blkcipher', 0o775)
+f('sys/module/crypto_blkcipher/initstate', 0o664, b'live\n')
+f('sys/module/crypto_blkcipher/srcversion', 0o664, b'723F00BD2391209F4D65272\n')
+f('sys/module/crypto_blkcipher/refcnt', 0o664, b'1\n')
+d('sys/module/crypto_blkcipher/holders', 0o775)
+l('sys/module/crypto_blkcipher/holders/ecb', '../../ecb')
+d('sys/module/crypto_blkcipher/sections', 0o775)
+f('sys/module/crypto_blkcipher/sections/__ksymtab_gpl', 0o664, b'0xffffffffa01f1610\n')
+f('sys/module/crypto_blkcipher/sections/.smp_locks', 0o664, b'0xffffffffa01f18c0\n')
+f('sys/module/crypto_blkcipher/sections/__bug_table', 0o664, b'0xffffffffa01f185f\n')
+f('sys/module/crypto_blkcipher/sections/__ksymtab_strings', 0o664, b'0xffffffffa01f1748\n')
+f('sys/module/crypto_blkcipher/sections/.exit.text', 0o664, b'0xffffffffa01f138c\n')
+f('sys/module/crypto_blkcipher/sections/.note.gnu.build-id', 0o664, b'0xffffffffa01f13b0\n')
+f('sys/module/crypto_blkcipher/sections/.strtab', 0o664, b'0xffffffffa01f2b10\n')
+f('sys/module/crypto_blkcipher/sections/.rodata', 0o664, b'0xffffffffa01f13e0\n')
+f('sys/module/crypto_blkcipher/sections/.bss', 0o664, b'0xffffffffa01f3ec0\n')
+f('sys/module/crypto_blkcipher/sections/.text', 0o664, b'0xffffffffa01ef000\n')
+f('sys/module/crypto_blkcipher/sections/.init.text', 0o664, b'0xffffffffa0027000\n')
+f('sys/module/crypto_blkcipher/sections/.data', 0o664, b'0xffffffffa01f39e0\n')
+f('sys/module/crypto_blkcipher/sections/.symtab', 0o664, b'0xffffffffa01f18f8\n')
+f('sys/module/crypto_blkcipher/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa01f3b00\n')
+f('sys/module/crypto_blkcipher/sections/.rodata.str1.1', 0o664, b'0xffffffffa01f1440\n')
+f('sys/module/crypto_blkcipher/sections/__kcrctab_gpl', 0o664, b'0xffffffffa01f16e0\n')
+d('sys/module/crypto_blkcipher/notes', 0o775)
+f('sys/module/crypto_blkcipher/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00-_P~\xd2\x1eM\xee\xb0!\xc0\xd8\xb7\x00\x1b\xe4#-\xc8\xe0')
+d('sys/module/soundcore', 0o775)
+f('sys/module/soundcore/initstate', 0o664, b'live\n')
+f('sys/module/soundcore/srcversion', 0o664, b'E4F49ED9C4CFD1A5A923330\n')
+f('sys/module/soundcore/refcnt', 0o664, b'1\n')
+d('sys/module/soundcore/holders', 0o775)
+l('sys/module/soundcore/holders/snd', '../../snd')
+d('sys/module/soundcore/sections', 0o775)
+f('sys/module/soundcore/sections/__ksymtab_strings', 0o664, b'0xffffffffa0067bf0\n')
+f('sys/module/soundcore/sections/.exit.text', 0o664, b'0xffffffffa0067850\n')
+f('sys/module/soundcore/sections/.note.gnu.build-id', 0o664, b'0xffffffffa0067874\n')
+f('sys/module/soundcore/sections/.strtab', 0o664, b'0xffffffffa00686d0\n')
+f('sys/module/soundcore/sections/__ksymtab', 0o664, b'0xffffffffa0067b00\n')
+f('sys/module/soundcore/sections/.rodata', 0o664, b'0xffffffffa00678a0\n')
+f('sys/module/soundcore/sections/.bss', 0o664, b'0xffffffffa00692c0\n')
+f('sys/module/soundcore/sections/.text', 0o664, b'0xffffffffa0067000\n')
+f('sys/module/soundcore/sections/.init.text', 0o664, b'0xffffffffa006b000\n')
+f('sys/module/soundcore/sections/__kcrctab', 0o664, b'0xffffffffa0067ba0\n')
+f('sys/module/soundcore/sections/.data', 0o664, b'0xffffffffa0068ec0\n')
+f('sys/module/soundcore/sections/.symtab', 0o664, b'0xffffffffa0067cc8\n')
+f('sys/module/soundcore/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa0068f00\n')
+f('sys/module/soundcore/sections/.rodata.str1.1', 0o664, b'0xffffffffa00679f8\n')
+d('sys/module/soundcore/notes', 0o775)
+f('sys/module/soundcore/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00^\x97fIs2\xf4Ck\xe0$]\xd8)]\xe2\x9c\xea\x1d\x0c')
+d('sys/module/pcspkr', 0o775)
+f('sys/module/pcspkr/initstate', 0o664, b'live\n')
+f('sys/module/pcspkr/srcversion', 0o664, b'5757E9C81E627525BA9D165\n')
+f('sys/module/pcspkr/refcnt', 0o664, b'0\n')
+d('sys/module/pcspkr/drivers', 0o775)
+l('sys/module/pcspkr/drivers/platform:pcspkr', '../../../bus/platform/drivers/pcspkr')
+d('sys/module/pcspkr/sections', 0o775)
+f('sys/module/pcspkr/sections/.exit.text', 0o664, b'0xffffffffa009e15c\n')
+f('sys/module/pcspkr/sections/.note.gnu.build-id', 0o664, b'0xffffffffa009e250\n')
+f('sys/module/pcspkr/sections/.strtab', 0o664, b'0xffffffffa009e6e8\n')
+f('sys/module/pcspkr/sections/.devexit.text', 0o664, b'0xffffffffa009e16e\n')
+f('sys/module/pcspkr/sections/.bss', 0o664, b'0xffffffffa009ed80\n')
+f('sys/module/pcspkr/sections/.text', 0o664, b'0xffffffffa009e000\n')
+f('sys/module/pcspkr/sections/.init.text', 0o664, b'0xffffffffa00a0000\n')
+f('sys/module/pcspkr/sections/.data', 0o664, b'0xffffffffa009e900\n')
+f('sys/module/pcspkr/sections/.devinit.text', 0o664, b'0xffffffffa009e1ad\n')
+f('sys/module/pcspkr/sections/.symtab', 0o664, b'0xffffffffa009e298\n')
+f('sys/module/pcspkr/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa009e9c0\n')
+f('sys/module/pcspkr/sections/.rodata.str1.1', 0o664, b'0xffffffffa009e274\n')
+d('sys/module/pcspkr/notes', 0o775)
+f('sys/module/pcspkr/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xe3\xfd\xb1\xf7b\xd2\x8f\xc1\xd2C\xfc\xfe\xdf8\x80\x82\x85A\xc9!')
+d('sys/module/sr_mod', 0o775)
+f('sys/module/sr_mod/initstate', 0o664, b'live\n')
+f('sys/module/sr_mod/srcversion', 0o664, b'3484F077F1A71803F453437\n')
+f('sys/module/sr_mod/refcnt', 0o664, b'0\n')
+d('sys/module/sr_mod/parameters', 0o775)
+f('sys/module/sr_mod/parameters/xa_test', 0o664, b'0\n')
+d('sys/module/sr_mod/sections', 0o775)
+f('sys/module/sr_mod/sections/.smp_locks', 0o664, b'0xffffffffa0061488\n')
+f('sys/module/sr_mod/sections/.exit.text', 0o664, b'0xffffffffa006126c\n')
+f('sys/module/sr_mod/sections/.note.gnu.build-id', 0o664, b'0xffffffffa0061290\n')
+f('sys/module/sr_mod/sections/.strtab', 0o664, b'0xffffffffa00623f0\n')
+f('sys/module/sr_mod/sections/.rodata', 0o664, b'0xffffffffa00612c0\n')
+f('sys/module/sr_mod/sections/__param', 0o664, b'0xffffffffa0061750\n')
+f('sys/module/sr_mod/sections/.bss', 0o664, b'0xffffffffa00630c0\n')
+f('sys/module/sr_mod/sections/.text', 0o664, b'0xffffffffa005f000\n')
+f('sys/module/sr_mod/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/sr_mod/sections/.data', 0o664, b'0xffffffffa0062aa0\n')
+f('sys/module/sr_mod/sections/.symtab', 0o664, b'0xffffffffa0061778\n')
+f('sys/module/sr_mod/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa0062d00\n')
+f('sys/module/sr_mod/sections/.rodata.str1.1', 0o664, b'0xffffffffa0061308\n')
+d('sys/module/sr_mod/notes', 0o775)
+f('sys/module/sr_mod/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xae\xa7\xdcHo\xe7\xe1\xa0#\x94\x9a\xfeV8\xa6O$@\xc1(')
+d('sys/module/cfg80211', 0o775)
+f('sys/module/cfg80211/initstate', 0o664, b'live\n')
+f('sys/module/cfg80211/srcversion', 0o664, b'C43F275505B181F0D1625BE\n')
+f('sys/module/cfg80211/refcnt', 0o664, b'2\n')
+d('sys/module/cfg80211/holders', 0o775)
+l('sys/module/cfg80211/holders/mac80211', '../../mac80211')
+l('sys/module/cfg80211/holders/iwl3945', '../../iwl3945')
+d('sys/module/cfg80211/parameters', 0o775)
+f('sys/module/cfg80211/parameters/ieee80211_regdom', 0o664, b'US\n')
+d('sys/module/cfg80211/sections', 0o775)
+f('sys/module/cfg80211/sections/.smp_locks', 0o664, b'0xffffffffa00bd2a0\n')
+f('sys/module/cfg80211/sections/__bug_table', 0o664, b'0xffffffffa00bd166\n')
+f('sys/module/cfg80211/sections/__ksymtab_strings', 0o664, b'0xffffffffa00bd448\n')
+f('sys/module/cfg80211/sections/.note.gnu.build-id', 0o664, b'0xffffffffa00bce58\n')
+f('sys/module/cfg80211/sections/.strtab', 0o664, b'0xffffffffa00be8c0\n')
+f('sys/module/cfg80211/sections/__ksymtab', 0o664, b'0xffffffffa00bd370\n')
+f('sys/module/cfg80211/sections/.rodata', 0o664, b'0xffffffffa00bce80\n')
+f('sys/module/cfg80211/sections/.data.read_mostly', 0o664, b'0xffffffffa00bfe60\n')
+f('sys/module/cfg80211/sections/__param', 0o664, b'0xffffffffa00bd518\n')
+f('sys/module/cfg80211/sections/.bss', 0o664, b'0xffffffffa00c02c0\n')
+f('sys/module/cfg80211/sections/.text', 0o664, b'0xffffffffa00b9000\n')
+f('sys/module/cfg80211/sections/__kcrctab', 0o664, b'0xffffffffa00bd400\n')
+f('sys/module/cfg80211/sections/.data', 0o664, b'0xffffffffa00bf760\n')
+f('sys/module/cfg80211/sections/.symtab', 0o664, b'0xffffffffa00bd540\n')
+f('sys/module/cfg80211/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa00bff00\n')
+f('sys/module/cfg80211/sections/.rodata.str1.1', 0o664, b'0xffffffffa00bd078\n')
+d('sys/module/cfg80211/notes', 0o775)
+f('sys/module/cfg80211/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00}-\xdb\xa6\xb1\xf6I\x90\xaf\xbdX\xed\x8d\xac\x86o(\xc8zC')
+d('sys/module/snd_seq', 0o775)
+f('sys/module/snd_seq/initstate', 0o664, b'live\n')
+f('sys/module/snd_seq/srcversion', 0o664, b'94E19F6DBC8F63B241414FE\n')
+f('sys/module/snd_seq/refcnt', 0o664, b'0\n')
+d('sys/module/snd_seq/parameters', 0o775)
+f('sys/module/snd_seq/parameters/seq_default_timer_device', 0o664, b'0\n')
+f('sys/module/snd_seq/parameters/seq_default_timer_class', 0o664, b'1\n')
+f('sys/module/snd_seq/parameters/seq_client_load', 0o664, b'-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1\n')
+f('sys/module/snd_seq/parameters/seq_default_timer_sclass', 0o664, b'0\n')
+f('sys/module/snd_seq/parameters/seq_default_timer_resolution', 0o664, b'0\n')
+f('sys/module/snd_seq/parameters/seq_default_timer_subdevice', 0o664, b'0\n')
+f('sys/module/snd_seq/parameters/seq_default_timer_card', 0o664, b'-1\n')
+d('sys/module/snd_seq/sections', 0o775)
+f('sys/module/snd_seq/sections/.smp_locks', 0o664, b'0xffffffffa02b1d30\n')
+f('sys/module/snd_seq/sections/__ksymtab_strings', 0o664, b'0xffffffffa02b1748\n')
+f('sys/module/snd_seq/sections/.exit.text', 0o664, b'0xffffffffa02b0ff0\n')
+f('sys/module/snd_seq/sections/.note.gnu.build-id', 0o664, b'0xffffffffa02b10bc\n')
+f('sys/module/snd_seq/sections/.strtab', 0o664, b'0xffffffffa02b4590\n')
+f('sys/module/snd_seq/sections/__ksymtab', 0o664, b'0xffffffffa02b1610\n')
+f('sys/module/snd_seq/sections/.rodata', 0o664, b'0xffffffffa02b10e0\n')
+f('sys/module/snd_seq/sections/__param', 0o664, b'0xffffffffa02b1320\n')
+f('sys/module/snd_seq/sections/.bss', 0o664, b'0xffffffffa02b6f80\n')
+f('sys/module/snd_seq/sections/.text', 0o664, b'0xffffffffa02a9000\n')
+f('sys/module/snd_seq/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/snd_seq/sections/__kcrctab', 0o664, b'0xffffffffa02b16e0\n')
+f('sys/module/snd_seq/sections/.data', 0o664, b'0xffffffffa02b6860\n')
+f('sys/module/snd_seq/sections/.symtab', 0o664, b'0xffffffffa02b1fc8\n')
+f('sys/module/snd_seq/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa02b6bc0\n')
+f('sys/module/snd_seq/sections/.rodata.str1.1', 0o664, b'0xffffffffa02b18b6\n')
+d('sys/module/snd_seq/notes', 0o775)
+f('sys/module/snd_seq/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00O@T\xdaF\x1cl\x11\xfev\xdd\xaa \xea\x87\x92P\xfe\xb1\xf8')
+d('sys/module/usb_storage', 0o775)
+f('sys/module/usb_storage/initstate', 0o664, b'live\n')
+f('sys/module/usb_storage/srcversion', 0o664, b'D07F7C47643AB7AFB6BEF6F\n')
+f('sys/module/usb_storage/refcnt', 0o664, b'1\n')
+d('sys/module/usb_storage/drivers', 0o775)
+l('sys/module/usb_storage/drivers/usb:usb-storage', '../../../bus/usb/drivers/usb-storage')
+d('sys/module/usb_storage/parameters', 0o775)
+f('sys/module/usb_storage/parameters/swi_tru_install', 0o664, b'1\n')
+f('sys/module/usb_storage/parameters/delay_use', 0o664, b'5\n')
+d('sys/module/usb_storage/sections', 0o775)
+f('sys/module/usb_storage/sections/.smp_locks', 0o664, b'0xffffffffa02e1820\n')
+f('sys/module/usb_storage/sections/.exit.text', 0o664, b'0xffffffffa02e056c\n')
+f('sys/module/usb_storage/sections/.note.gnu.build-id', 0o664, b'0xffffffffa02e0580\n')
+f('sys/module/usb_storage/sections/.strtab', 0o664, b'0xffffffffa02e42d0\n')
+f('sys/module/usb_storage/sections/.rodata', 0o664, b'0xffffffffa02e05b0\n')
+f('sys/module/usb_storage/sections/__param', 0o664, b'0xffffffffa02e18b0\n')
+f('sys/module/usb_storage/sections/.bss', 0o664, b'0xffffffffa02e9400\n')
+f('sys/module/usb_storage/sections/.text', 0o664, b'0xffffffffa02dd000\n')
+f('sys/module/usb_storage/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/usb_storage/sections/.data', 0o664, b'0xffffffffa02e5dc0\n')
+f('sys/module/usb_storage/sections/.symtab', 0o664, b'0xffffffffa02e1900\n')
+f('sys/module/usb_storage/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa02e9040\n')
+f('sys/module/usb_storage/sections/.rodata.str1.1', 0o664, b'0xffffffffa02e0ab1\n')
+d('sys/module/usb_storage/notes', 0o775)
+f('sys/module/usb_storage/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00B~(&&u\xc4Ax\xd8|\x80n\xc4G(i\xf3kG')
+d('sys/module/acpi_cpufreq', 0o775)
+f('sys/module/acpi_cpufreq/initstate', 0o664, b'live\n')
+f('sys/module/acpi_cpufreq/srcversion', 0o664, b'09166B6001DCE2189668F16\n')
+f('sys/module/acpi_cpufreq/refcnt', 0o664, b'1\n')
+d('sys/module/acpi_cpufreq/parameters', 0o775)
+f('sys/module/acpi_cpufreq/parameters/acpi_pstate_strict', 0o664, b'0\n')
+d('sys/module/acpi_cpufreq/sections', 0o775)
+f('sys/module/acpi_cpufreq/sections/.smp_locks', 0o664, b'0xffffffffa0254d68\n')
+f('sys/module/acpi_cpufreq/sections/.exit.text', 0o664, b'0xffffffffa0254c4c\n')
+f('sys/module/acpi_cpufreq/sections/.note.gnu.build-id', 0o664, b'0xffffffffa0254c6c\n')
+f('sys/module/acpi_cpufreq/sections/.strtab', 0o664, b'0xffffffffa0255620\n')
+f('sys/module/acpi_cpufreq/sections/.rodata', 0o664, b'0xffffffffa0254ca0\n')
+f('sys/module/acpi_cpufreq/sections/__param', 0o664, b'0xffffffffa0254d70\n')
+f('sys/module/acpi_cpufreq/sections/.bss', 0o664, b'0xffffffffa0256000\n')
+f('sys/module/acpi_cpufreq/sections/.text', 0o664, b'0xffffffffa0254000\n')
+f('sys/module/acpi_cpufreq/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/acpi_cpufreq/sections/.data', 0o664, b'0xffffffffa0255bc0\n')
+f('sys/module/acpi_cpufreq/sections/.symtab', 0o664, b'0xffffffffa0254dc8\n')
+f('sys/module/acpi_cpufreq/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa0255c40\n')
+f('sys/module/acpi_cpufreq/sections/.rodata.str1.1', 0o664, b'0xffffffffa0254d98\n')
+d('sys/module/acpi_cpufreq/notes', 0o775)
+f('sys/module/acpi_cpufreq/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xa4\xfd\x13\xe7*\xbd\x99\x95\x99C\xf6\x95\x04\xf1r\xf9\xf7}aL')
+d('sys/module/button', 0o775)
+f('sys/module/button/initstate', 0o664, b'live\n')
+f('sys/module/button/srcversion', 0o664, b'2713981C971D8EC4C059338\n')
+f('sys/module/button/refcnt', 0o664, b'0\n')
+d('sys/module/button/sections', 0o775)
+f('sys/module/button/sections/.smp_locks', 0o664, b'0xffffffffa00a7c98\n')
+f('sys/module/button/sections/.exit.text', 0o664, b'0xffffffffa00a781c\n')
+f('sys/module/button/sections/.note.gnu.build-id', 0o664, b'0xffffffffa00a7898\n')
+f('sys/module/button/sections/.strtab', 0o664, b'0xffffffffa00a84d8\n')
+f('sys/module/button/sections/.rodata', 0o664, b'0xffffffffa00a78c0\n')
+f('sys/module/button/sections/.bss', 0o664, b'0xffffffffa00a8f40\n')
+f('sys/module/button/sections/.text', 0o664, b'0xffffffffa00a7000\n')
+f('sys/module/button/sections/.init.text', 0o664, b'0xffffffffa00aa000\n')
+f('sys/module/button/sections/.data', 0o664, b'0xffffffffa00a89e0\n')
+f('sys/module/button/sections/.symtab', 0o664, b'0xffffffffa00a7cb0\n')
+f('sys/module/button/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa00a8b80\n')
+f('sys/module/button/sections/.rodata.str1.1', 0o664, b'0xffffffffa00a7b60\n')
+d('sys/module/button/notes', 0o775)
+f('sys/module/button/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00;\xc1\xa4qIi\xa7\xa0g\x7fb\xcb\xb4\xba\x80\xb1\x17Z#\xb5')
+d('sys/module/processor', 0o775)
+f('sys/module/processor/initstate', 0o664, b'live\n')
+f('sys/module/processor/srcversion', 0o664, b'8A1C302AFF80867DBAC4684\n')
+f('sys/module/processor/refcnt', 0o664, b'4\n')
+d('sys/module/processor/holders', 0o775)
+l('sys/module/processor/holders/acpi_cpufreq', '../../acpi_cpufreq')
+l('sys/module/processor/holders/thermal', '../../thermal')
+d('sys/module/processor/parameters', 0o775)
+f('sys/module/processor/parameters/ignore_ppc', 0o664, b'0\n')
+f('sys/module/processor/parameters/latency_factor', 0o664, b'2\n')
+d('sys/module/processor/sections', 0o775)
+f('sys/module/processor/sections/.smp_locks', 0o664, b'0xffffffffa0077788\n')
+f('sys/module/processor/sections/__ex_table', 0o664, b'0xffffffffa0077768\n')
+f('sys/module/processor/sections/__bug_table', 0o664, b'0xffffffffa0077621\n')
+f('sys/module/processor/sections/__ksymtab_strings', 0o664, b'0xffffffffa00776b8\n')
+f('sys/module/processor/sections/.exit.text', 0o664, b'0xffffffffa00763a9\n')
+f('sys/module/processor/sections/.note.gnu.build-id', 0o664, b'0xffffffffa00765c4\n')
+f('sys/module/processor/sections/.strtab', 0o664, b'0xffffffffa0079438\n')
+f('sys/module/processor/sections/.fixup', 0o664, b'0xffffffffa00765ad\n')
+f('sys/module/processor/sections/__ksymtab', 0o664, b'0xffffffffa0077640\n')
+f('sys/module/processor/sections/.rodata', 0o664, b'0xffffffffa00765f0\n')
+f('sys/module/processor/sections/.data.read_mostly', 0o664, b'0xffffffffa007b7d8\n')
+f('sys/module/processor/sections/__param', 0o664, b'0xffffffffa00777f0\n')
+f('sys/module/processor/sections/.bss', 0o664, b'0xffffffffa007bbc0\n')
+f('sys/module/processor/sections/.text', 0o664, b'0xffffffffa0072000\n')
+f('sys/module/processor/sections/.init.text', 0o664, b'0xffffffffa007d000\n')
+f('sys/module/processor/sections/__kcrctab', 0o664, b'0xffffffffa0077690\n')
+f('sys/module/processor/sections/.data', 0o664, b'0xffffffffa007ab90\n')
+f('sys/module/processor/sections/.cpuinit.data', 0o664, b'0xffffffffa007b040\n')
+f('sys/module/processor/sections/.symtab', 0o664, b'0xffffffffa0077890\n')
+f('sys/module/processor/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa007b800\n')
+f('sys/module/processor/sections/.rodata.str1.1', 0o664, b'0xffffffffa0076863\n')
+f('sys/module/processor/sections/.cpuinit.text', 0o664, b'0xffffffffa0075abc\n')
+f('sys/module/processor/sections/.ref.text', 0o664, b'0xffffffffa007641a\n')
+d('sys/module/processor/notes', 0o775)
+f('sys/module/processor/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xa1\x01$C\tS,+Ue\\\x8cg\xb0Z\xe9\xa1\xaf[\xe5')
+d('sys/module/oprofile', 0o775)
+d('sys/module/oprofile/parameters', 0o775)
+f('sys/module/oprofile/parameters/timer', 0o664, b'0\n')
+d('sys/module/spurious', 0o775)
+d('sys/module/spurious/parameters', 0o775)
+f('sys/module/spurious/parameters/noirqdebug', 0o664, b'N\n')
+f('sys/module/spurious/parameters/irqfixup', 0o664, b'0\n')
+d('sys/module/raid1', 0o775)
+f('sys/module/raid1/initstate', 0o664, b'live\n')
+f('sys/module/raid1/srcversion', 0o664, b'EA08FDD37C2EEFA95DE4413\n')
+f('sys/module/raid1/refcnt', 0o664, b'1\n')
+d('sys/module/raid1/sections', 0o775)
+f('sys/module/raid1/sections/.smp_locks', 0o664, b'0xffffffffa0236438\n')
+f('sys/module/raid1/sections/__bug_table', 0o664, b'0xffffffffa02369c0\n')
+f('sys/module/raid1/sections/.note.gnu.build-id', 0o664, b'0xffffffffa0236414\n')
+f('sys/module/raid1/sections/.strtab', 0o664, b'0xffffffffa02376f8\n')
+f('sys/module/raid1/sections/.bss', 0o664, b'0xffffffffa0238280\n')
+f('sys/module/raid1/sections/.text', 0o664, b'0xffffffffa0232000\n')
+f('sys/module/raid1/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/raid1/sections/.data', 0o664, b'0xffffffffa0237e20\n')
+f('sys/module/raid1/sections/.symtab', 0o664, b'0xffffffffa0236a08\n')
+f('sys/module/raid1/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa0237ec0\n')
+f('sys/module/raid1/sections/.rodata.str1.1', 0o664, b'0xffffffffa0236618\n')
+d('sys/module/raid1/notes', 0o775)
+f('sys/module/raid1/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xcd\xdf0\xe8v}\x0cuP}\x93\xe1\x19\xcd\xed~\xf7\x14\xdd@')
+d('sys/module/edd', 0o775)
+f('sys/module/edd/version', 0o664, b'0.16\n')
+f('sys/module/edd/initstate', 0o664, b'live\n')
+f('sys/module/edd/srcversion', 0o664, b'ED68C1ACC4B2D1B19C7BEA7\n')
+f('sys/module/edd/refcnt', 0o664, b'0\n')
+d('sys/module/edd/sections', 0o775)
+f('sys/module/edd/sections/.exit.text', 0o664, b'0xffffffffa02a1de8\n')
+f('sys/module/edd/sections/.note.gnu.build-id', 0o664, b'0xffffffffa02a1e6c\n')
+f('sys/module/edd/sections/.strtab', 0o664, b'0xffffffffa02a2b88\n')
+f('sys/module/edd/sections/.rodata', 0o664, b'0xffffffffa02a1ea0\n')
+f('sys/module/edd/sections/.bss', 0o664, b'0xffffffffa02a3880\n')
+f('sys/module/edd/sections/.text', 0o664, b'0xffffffffa02a1000\n')
+f('sys/module/edd/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/edd/sections/.data', 0o664, b'0xffffffffa02a3120\n')
+f('sys/module/edd/sections/.symtab', 0o664, b'0xffffffffa02a22b8\n')
+f('sys/module/edd/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa02a34c0\n')
+f('sys/module/edd/sections/.rodata.str1.1', 0o664, b'0xffffffffa02a1f18\n')
+d('sys/module/edd/notes', 0o775)
+f('sys/module/edd/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xbe\x92\xcfW\xc8l\x08\xaf\xb6\x1a\xb7!E\xb8\xd1\x9eU\xd2\xddM')
+d('sys/module/hwmon', 0o775)
+f('sys/module/hwmon/initstate', 0o664, b'live\n')
+f('sys/module/hwmon/srcversion', 0o664, b'9344A0FAA4A298DC9AEBDC8\n')
+f('sys/module/hwmon/refcnt', 0o664, b'1\n')
+d('sys/module/hwmon/holders', 0o775)
+l('sys/module/hwmon/holders/thinkpad_acpi', '../../thinkpad_acpi')
+d('sys/module/hwmon/sections', 0o775)
+f('sys/module/hwmon/sections/__ksymtab_gpl', 0o664, b'0xffffffffa007d1d0\n')
+f('sys/module/hwmon/sections/__ksymtab_strings', 0o664, b'0xffffffffa007d200\n')
+f('sys/module/hwmon/sections/.exit.text', 0o664, b'0xffffffffa007d138\n')
+f('sys/module/hwmon/sections/.note.gnu.build-id', 0o664, b'0xffffffffa007d14c\n')
+f('sys/module/hwmon/sections/.strtab', 0o664, b'0xffffffffa007d770\n')
+f('sys/module/hwmon/sections/.bss', 0o664, b'0xffffffffa007de80\n')
+f('sys/module/hwmon/sections/.text', 0o664, b'0xffffffffa007d000\n')
+f('sys/module/hwmon/sections/.init.text', 0o664, b'0xffffffffa009a000\n')
+f('sys/module/hwmon/sections/.data', 0o664, b'0xffffffffa007da20\n')
+f('sys/module/hwmon/sections/.symtab', 0o664, b'0xffffffffa007d230\n')
+f('sys/module/hwmon/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa007dac0\n')
+f('sys/module/hwmon/sections/.rodata.str1.1', 0o664, b'0xffffffffa007d170\n')
+f('sys/module/hwmon/sections/__kcrctab_gpl', 0o664, b'0xffffffffa007d1f0\n')
+d('sys/module/hwmon/notes', 0o775)
+f('sys/module/hwmon/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\x0fR\x0b\x94!\x19\xde\x14\x93\xac\x9e@\xa2&\xcam,\xba\x12\xd1')
+d('sys/module/backlight', 0o775)
+f('sys/module/backlight/initstate', 0o664, b'live\n')
+f('sys/module/backlight/srcversion', 0o664, b'AFD1565C65F3DA6D942CB52\n')
+f('sys/module/backlight/refcnt', 0o664, b'1\n')
+d('sys/module/backlight/holders', 0o775)
+l('sys/module/backlight/holders/thinkpad_acpi', '../../thinkpad_acpi')
+d('sys/module/backlight/sections', 0o775)
+f('sys/module/backlight/sections/__ksymtab_strings', 0o664, b'0xffffffffa0131700\n')
+f('sys/module/backlight/sections/.exit.text', 0o664, b'0xffffffffa01315ec\n')
+f('sys/module/backlight/sections/.note.gnu.build-id', 0o664, b'0xffffffffa0131600\n')
+f('sys/module/backlight/sections/.strtab', 0o664, b'0xffffffffa0131de0\n')
+f('sys/module/backlight/sections/__ksymtab', 0o664, b'0xffffffffa01316d0\n')
+f('sys/module/backlight/sections/.bss', 0o664, b'0xffffffffa01326c0\n')
+f('sys/module/backlight/sections/.text', 0o664, b'0xffffffffa0131000\n')
+f('sys/module/backlight/sections/.init.text', 0o664, b'0xffffffffa0070000\n')
+f('sys/module/backlight/sections/__kcrctab', 0o664, b'0xffffffffa01316f0\n')
+f('sys/module/backlight/sections/.data', 0o664, b'0xffffffffa0132220\n')
+f('sys/module/backlight/sections/.symtab', 0o664, b'0xffffffffa0131738\n')
+f('sys/module/backlight/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa0132300\n')
+f('sys/module/backlight/sections/.rodata.str1.1', 0o664, b'0xffffffffa0131624\n')
+d('sys/module/backlight/notes', 0o775)
+f('sys/module/backlight/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00d\xb6_\xb64[\x83\x90Fm(\x91J\xb1\xce\xf5\xaa\xd2\xf4}')
+d('sys/module/snd', 0o775)
+f('sys/module/snd/initstate', 0o664, b'live\n')
+f('sys/module/snd/srcversion', 0o664, b'D48337942305C9A41A7CC12\n')
+f('sys/module/snd/refcnt', 0o664, b'13\n')
+d('sys/module/snd/holders', 0o775)
+l('sys/module/snd/holders/snd_seq', '../../snd_seq')
+l('sys/module/snd/holders/snd_timer', '../../snd_timer')
+l('sys/module/snd/holders/snd_pcm', '../../snd_pcm')
+l('sys/module/snd/holders/snd_hda_intel', '../../snd_hda_intel')
+l('sys/module/snd/holders/snd_mixer_oss', '../../snd_mixer_oss')
+l('sys/module/snd/holders/snd_pcm_oss', '../../snd_pcm_oss')
+l('sys/module/snd/holders/snd_seq_device', '../../snd_seq_device')
+d('sys/module/snd/parameters', 0o775)
+f('sys/module/snd/parameters/slots', 0o664, b'snd-hda-intel,<NULL>,<NULL>,<NULL>,<NULL>,<NULL>,<NULL>,<NULL>\n')
+f('sys/module/snd/parameters/major', 0o664, b'116\n')
+f('sys/module/snd/parameters/cards_limit', 0o664, b'1\n')
+d('sys/module/snd/sections', 0o775)
+f('sys/module/snd/sections/__ksymtab_strings', 0o664, b'0xffffffffa00d32e8\n')
+f('sys/module/snd/sections/.exit.text', 0o664, b'0xffffffffa00d1bc4\n')
+f('sys/module/snd/sections/.note.gnu.build-id', 0o664, b'0xffffffffa00d1c8c\n')
+f('sys/module/snd/sections/.strtab', 0o664, b'0xffffffffa00d6cc8\n')
+f('sys/module/snd/sections/__ksymtab', 0o664, b'0xffffffffa00d2d00\n')
+f('sys/module/snd/sections/.rodata', 0o664, b'0xffffffffa00d1cc0\n')
+f('sys/module/snd/sections/__param', 0o664, b'0xffffffffa00d3270\n')
+f('sys/module/snd/sections/.bss', 0o664, b'0xffffffffa00da480\n')
+f('sys/module/snd/sections/.text', 0o664, b'0xffffffffa00ca000\n')
+f('sys/module/snd/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/snd/sections/__kcrctab', 0o664, b'0xffffffffa00d30a0\n')
+f('sys/module/snd/sections/.data', 0o664, b'0xffffffffa00d9be0\n')
+f('sys/module/snd/sections/.symtab', 0o664, b'0xffffffffa00d3770\n')
+f('sys/module/snd/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa00da0c0\n')
+f('sys/module/snd/sections/.rodata.str1.1', 0o664, b'0xffffffffa00d2558\n')
+d('sys/module/snd/notes', 0o775)
+f('sys/module/snd/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xee\x11+\xc0\xd4\x8f\x10\x02v\xf8\t\xb4\xa8\xf6[z\xd3\xb3\xb7\x87')
+d('sys/module/mac80211', 0o775)
+f('sys/module/mac80211/initstate', 0o664, b'live\n')
+f('sys/module/mac80211/srcversion', 0o664, b'330E8FB2F2933F478C444A4\n')
+f('sys/module/mac80211/refcnt', 0o664, b'1\n')
+d('sys/module/mac80211/holders', 0o775)
+l('sys/module/mac80211/holders/iwl3945', '../../iwl3945')
+d('sys/module/mac80211/parameters', 0o775)
+f('sys/module/mac80211/parameters/ieee80211_default_rc_algo', 0o664, b'pid\n')
+d('sys/module/mac80211/sections', 0o775)
+f('sys/module/mac80211/sections/__ksymtab_gpl', 0o664, b'0xffffffffa0127a50\n')
+f('sys/module/mac80211/sections/.smp_locks', 0o664, b'0xffffffffa01270a0\n')
+f('sys/module/mac80211/sections/__bug_table', 0o664, b'0xffffffffa0124183\n')
+f('sys/module/mac80211/sections/__ksymtab_strings', 0o664, b'0xffffffffa0127630\n')
+f('sys/module/mac80211/sections/.exit.text', 0o664, b'0xffffffffa0122de4\n')
+f('sys/module/mac80211/sections/.note.gnu.build-id', 0o664, b'0xffffffffa0122df4\n')
+f('sys/module/mac80211/sections/.strtab', 0o664, b'0xffffffffa012b890\n')
+f('sys/module/mac80211/sections/__ksymtab', 0o664, b'0xffffffffa01272a0\n')
+f('sys/module/mac80211/sections/.rodata', 0o664, b'0xffffffffa0122e20\n')
+f('sys/module/mac80211/sections/__param', 0o664, b'0xffffffffa0127a28\n')
+f('sys/module/mac80211/sections/.bss', 0o664, b'0xffffffffa012fa40\n')
+f('sys/module/mac80211/sections/.text', 0o664, b'0xffffffffa0109000\n')
+f('sys/module/mac80211/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/mac80211/sections/__kcrctab', 0o664, b'0xffffffffa0127500\n')
+f('sys/module/mac80211/sections/.data', 0o664, b'0xffffffffa012f340\n')
+f('sys/module/mac80211/sections/.symtab', 0o664, b'0xffffffffa0127a80\n')
+f('sys/module/mac80211/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa012f680\n')
+f('sys/module/mac80211/sections/.rodata.str1.1', 0o664, b'0xffffffffa0123c40\n')
+f('sys/module/mac80211/sections/__kcrctab_gpl', 0o664, b'0xffffffffa0127a70\n')
+d('sys/module/mac80211/notes', 0o775)
+f('sys/module/mac80211/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00"i\xe2\xa0\x92\xbc7\xc4#\xbc\xda\xf11\x02\x13\xd5\x155\x1cS')
+d('sys/module/printk', 0o775)
+d('sys/module/printk/parameters', 0o775)
+f('sys/module/printk/parameters/time', 0o664, b'N\n')
+d('sys/module/rtc_lib', 0o775)
+f('sys/module/rtc_lib/initstate', 0o664, b'live\n')
+f('sys/module/rtc_lib/srcversion', 0o664, b'7884E7FF8728D88C6BD1427\n')
+f('sys/module/rtc_lib/refcnt', 0o664, b'1\n')
+d('sys/module/rtc_lib/holders', 0o775)
+l('sys/module/rtc_lib/holders/rtc_core', '../../rtc_core')
+d('sys/module/rtc_lib/sections', 0o775)
+f('sys/module/rtc_lib/sections/__ksymtab_strings', 0o664, b'0xffffffffa009c3f8\n')
+f('sys/module/rtc_lib/sections/.note.gnu.build-id', 0o664, b'0xffffffffa009c31c\n')
+f('sys/module/rtc_lib/sections/.strtab', 0o664, b'0xffffffffa009c8f0\n')
+f('sys/module/rtc_lib/sections/__ksymtab', 0o664, b'0xffffffffa009c380\n')
+f('sys/module/rtc_lib/sections/.rodata', 0o664, b'0xffffffffa009c340\n')
+f('sys/module/rtc_lib/sections/.bss', 0o664, b'0xffffffffa009cf80\n')
+f('sys/module/rtc_lib/sections/.text', 0o664, b'0xffffffffa009c000\n')
+f('sys/module/rtc_lib/sections/__kcrctab', 0o664, b'0xffffffffa009c3d0\n')
+f('sys/module/rtc_lib/sections/.data', 0o664, b'0xffffffffa009cba8\n')
+f('sys/module/rtc_lib/sections/.symtab', 0o664, b'0xffffffffa009c440\n')
+f('sys/module/rtc_lib/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa009cbc0\n')
+d('sys/module/rtc_lib/notes', 0o775)
+f('sys/module/rtc_lib/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xb4\xe2\xcfLw\x17j\xb2\xc7\xf1 \xfa\xc7G\x99+b^+S')
+d('sys/module/mousedev', 0o775)
+d('sys/module/mousedev/parameters', 0o775)
+f('sys/module/mousedev/parameters/tap_time', 0o664, b'200\n')
+f('sys/module/mousedev/parameters/yres', 0o664, b'768\n')
+f('sys/module/mousedev/parameters/xres', 0o664, b'1024\n')
+d('sys/module/rtc_cmos', 0o775)
+f('sys/module/rtc_cmos/initstate', 0o664, b'live\n')
+f('sys/module/rtc_cmos/srcversion', 0o664, b'7BE4B8C2A52556D0C62CB0B\n')
+f('sys/module/rtc_cmos/refcnt', 0o664, b'0\n')
+d('sys/module/rtc_cmos/sections', 0o775)
+f('sys/module/rtc_cmos/sections/.exit.text', 0o664, b'0xffffffffa00fe370\n')
+f('sys/module/rtc_cmos/sections/.note.gnu.build-id', 0o664, b'0xffffffffa00fe4e4\n')
+f('sys/module/rtc_cmos/sections/.strtab', 0o664, b'0xffffffffa00ff1a8\n')
+f('sys/module/rtc_cmos/sections/.rodata', 0o664, b'0xffffffffa00fe520\n')
+f('sys/module/rtc_cmos/sections/.bss', 0o664, b'0xffffffffa00ffd40\n')
+f('sys/module/rtc_cmos/sections/.text', 0o664, b'0xffffffffa00fd000\n')
+f('sys/module/rtc_cmos/sections/.init.text', 0o664, b'0xffffffffa007d000\n')
+f('sys/module/rtc_cmos/sections/.data', 0o664, b'0xffffffffa00ff800\n')
+f('sys/module/rtc_cmos/sections/.devinit.text', 0o664, b'0xffffffffa00fe44f\n')
+f('sys/module/rtc_cmos/sections/.symtab', 0o664, b'0xffffffffa00fe6e0\n')
+f('sys/module/rtc_cmos/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa00ff980\n')
+f('sys/module/rtc_cmos/sections/.rodata.str1.1', 0o664, b'0xffffffffa00fe6a2\n')
+d('sys/module/rtc_cmos/notes', 0o775)
+f('sys/module/rtc_cmos/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xf4\x82\xed4\xe7\x10\xb9\x7f\xa9 \x0c\xedIf0\x86u\xd41\x87')
+d('sys/module/battery', 0o775)
+f('sys/module/battery/initstate', 0o664, b'live\n')
+f('sys/module/battery/srcversion', 0o664, b'5A2CE8D302B31A112CFB57A\n')
+f('sys/module/battery/refcnt', 0o664, b'0\n')
+d('sys/module/battery/parameters', 0o775)
+f('sys/module/battery/parameters/cache_time', 0o664, b'1000\n')
+d('sys/module/battery/sections', 0o775)
+f('sys/module/battery/sections/.exit.text', 0o664, b'0xffffffffa008008c\n')
+f('sys/module/battery/sections/.note.gnu.build-id', 0o664, b'0xffffffffa00800ac\n')
+f('sys/module/battery/sections/.strtab', 0o664, b'0xffffffffa0081318\n')
+f('sys/module/battery/sections/.rodata', 0o664, b'0xffffffffa00800d0\n')
+f('sys/module/battery/sections/__param', 0o664, b'0xffffffffa0080798\n')
+f('sys/module/battery/sections/.bss', 0o664, b'0xffffffffa0082440\n')
+f('sys/module/battery/sections/.text', 0o664, b'0xffffffffa007f000\n')
+f('sys/module/battery/sections/.init.text', 0o664, b'0xffffffffa0084000\n')
+f('sys/module/battery/sections/.data', 0o664, b'0xffffffffa0081a90\n')
+f('sys/module/battery/sections/.symtab', 0o664, b'0xffffffffa00807c0\n')
+f('sys/module/battery/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa0082080\n')
+f('sys/module/battery/sections/.rodata.str1.1', 0o664, b'0xffffffffa008025b\n')
+d('sys/module/battery/notes', 0o775)
+f('sys/module/battery/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xe3\xa8\xcc.j\xb3\xda\xc8\x88\x03\xca\xf6\xf0*\x9c-\xffE!\xd3')
+d('sys/module/yenta_socket', 0o775)
+f('sys/module/yenta_socket/initstate', 0o664, b'live\n')
+f('sys/module/yenta_socket/srcversion', 0o664, b'B0538CB6E6ED071E80A4575\n')
+f('sys/module/yenta_socket/refcnt', 0o664, b'1\n')
+d('sys/module/yenta_socket/drivers', 0o775)
+l('sys/module/yenta_socket/drivers/pci:yenta_cardbus', '../../../bus/pci/drivers/yenta_cardbus')
+d('sys/module/yenta_socket/parameters', 0o775)
+f('sys/module/yenta_socket/parameters/isa_probe', 0o664, b'Y\n')
+f('sys/module/yenta_socket/parameters/disable_clkrun', 0o664, b'N\n')
+f('sys/module/yenta_socket/parameters/pwr_irqs_off', 0o664, b'N\n')
+d('sys/module/yenta_socket/sections', 0o775)
+f('sys/module/yenta_socket/sections/__bug_table', 0o664, b'0xffffffffa0104aa6\n')
+f('sys/module/yenta_socket/sections/.exit.text', 0o664, b'0xffffffffa0103c44\n')
+f('sys/module/yenta_socket/sections/.note.gnu.build-id', 0o664, b'0xffffffffa0104330\n')
+f('sys/module/yenta_socket/sections/.strtab', 0o664, b'0xffffffffa0105e80\n')
+f('sys/module/yenta_socket/sections/.rodata', 0o664, b'0xffffffffa0104354\n')
+f('sys/module/yenta_socket/sections/__param', 0o664, b'0xffffffffa0104ad8\n')
+f('sys/module/yenta_socket/sections/.bss', 0o664, b'0xffffffffa0107800\n')
+f('sys/module/yenta_socket/sections/.text', 0o664, b'0xffffffffa0101000\n')
+f('sys/module/yenta_socket/sections/.init.text', 0o664, b'0xffffffffa0084000\n')
+f('sys/module/yenta_socket/sections/.data', 0o664, b'0xffffffffa0106ac0\n')
+f('sys/module/yenta_socket/sections/.devinit.text', 0o664, b'0xffffffffa0103c60\n')
+f('sys/module/yenta_socket/sections/.symtab', 0o664, b'0xffffffffa0104b78\n')
+f('sys/module/yenta_socket/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa0107440\n')
+f('sys/module/yenta_socket/sections/.rodata.str1.1', 0o664, b'0xffffffffa0104388\n')
+d('sys/module/yenta_socket/notes', 0o775)
+f('sys/module/yenta_socket/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00H\xa8\xe9\xf1\x06e\xb4\xe4\xd7\xa1\x7f\xf8G)\x1a\xa3\xec\xe7m<')
+d('sys/module/acpi', 0o775)
+d('sys/module/acpi/parameters', 0o775)
+f('sys/module/acpi/parameters/acpica_version', 0o664, b'20080609\n')
+d('sys/module/cdc_acm', 0o775)
+f('sys/module/cdc_acm/initstate', 0o664, b'live\n')
+f('sys/module/cdc_acm/srcversion', 0o664, b'5DED3866AA046376E4E36DD\n')
+f('sys/module/cdc_acm/refcnt', 0o664, b'0\n')
+d('sys/module/cdc_acm/drivers', 0o775)
+l('sys/module/cdc_acm/drivers/usb:cdc_acm', '../../../bus/usb/drivers/cdc_acm')
+d('sys/module/cdc_acm/sections', 0o775)
+f('sys/module/cdc_acm/sections/.smp_locks', 0o664, b'0xffffffffa02d9660\n')
+f('sys/module/cdc_acm/sections/.exit.text', 0o664, b'0xffffffffa02d949c\n')
+f('sys/module/cdc_acm/sections/.note.gnu.build-id', 0o664, b'0xffffffffa02d94c8\n')
+f('sys/module/cdc_acm/sections/.strtab', 0o664, b'0xffffffffa02da838\n')
+f('sys/module/cdc_acm/sections/.rodata', 0o664, b'0xffffffffa02d9500\n')
+f('sys/module/cdc_acm/sections/.bss', 0o664, b'0xffffffffa02db8c0\n')
+f('sys/module/cdc_acm/sections/.text', 0o664, b'0xffffffffa02d7000\n')
+f('sys/module/cdc_acm/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/cdc_acm/sections/.data', 0o664, b'0xffffffffa02db0e0\n')
+f('sys/module/cdc_acm/sections/.symtab', 0o664, b'0xffffffffa02d9968\n')
+f('sys/module/cdc_acm/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa02db500\n')
+f('sys/module/cdc_acm/sections/.rodata.str1.1', 0o664, b'0xffffffffa02d9698\n')
+d('sys/module/cdc_acm/notes', 0o775)
+f('sys/module/cdc_acm/notes/.note.gnu.build-id', 0o664, b"\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xe1=\x89\xe9\xe8L\t\xfe|o\x9c+\xfe\x81\xe8\xc6P'\xa4$")
+d('sys/module/snd_timer', 0o775)
+f('sys/module/snd_timer/initstate', 0o664, b'live\n')
+f('sys/module/snd_timer/srcversion', 0o664, b'1F1836030C5B604CF478CFC\n')
+f('sys/module/snd_timer/refcnt', 0o664, b'2\n')
+d('sys/module/snd_timer/holders', 0o775)
+l('sys/module/snd_timer/holders/snd_seq', '../../snd_seq')
+l('sys/module/snd_timer/holders/snd_pcm', '../../snd_pcm')
+d('sys/module/snd_timer/parameters', 0o775)
+f('sys/module/snd_timer/parameters/timer_tstamp_monotonic', 0o664, b'1\n')
+f('sys/module/snd_timer/parameters/timer_limit', 0o664, b'1\n')
+d('sys/module/snd_timer/sections', 0o775)
+f('sys/module/snd_timer/sections/.smp_locks', 0o664, b'0xffffffffa00f8908\n')
+f('sys/module/snd_timer/sections/__bug_table', 0o664, b'0xffffffffa00f888f\n')
+f('sys/module/snd_timer/sections/__ksymtab_strings', 0o664, b'0xffffffffa00f8a98\n')
+f('sys/module/snd_timer/sections/.exit.text', 0o664, b'0xffffffffa00f8520\n')
+f('sys/module/snd_timer/sections/.note.gnu.build-id', 0o664, b'0xffffffffa00f8590\n')
+f('sys/module/snd_timer/sections/.strtab', 0o664, b'0xffffffffa00f9e90\n')
+f('sys/module/snd_timer/sections/__ksymtab', 0o664, b'0xffffffffa00f8910\n')
+f('sys/module/snd_timer/sections/.rodata', 0o664, b'0xffffffffa00f85c0\n')
+f('sys/module/snd_timer/sections/__param', 0o664, b'0xffffffffa00f8a48\n')
+f('sys/module/snd_timer/sections/.bss', 0o664, b'0xffffffffa00fb200\n')
+f('sys/module/snd_timer/sections/.text', 0o664, b'0xffffffffa00f5000\n')
+f('sys/module/snd_timer/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/snd_timer/sections/__kcrctab', 0o664, b'0xffffffffa00f89e0\n')
+f('sys/module/snd_timer/sections/.data', 0o664, b'0xffffffffa00fad00\n')
+f('sys/module/snd_timer/sections/.symtab', 0o664, b'0xffffffffa00f8b88\n')
+f('sys/module/snd_timer/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa00fae40\n')
+f('sys/module/snd_timer/sections/.rodata.str1.1', 0o664, b'0xffffffffa00f8723\n')
+d('sys/module/snd_timer/notes', 0o775)
+f('sys/module/snd_timer/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xb2uP\xf49\x98_\xdcY\xc1\xbfY\xa4yn\xb0\xbe\x9c\xf2F')
+d('sys/module/e1000e', 0o775)
+f('sys/module/e1000e/version', 0o664, b'0.3.3.3-k2\n')
+f('sys/module/e1000e/initstate', 0o664, b'live\n')
+f('sys/module/e1000e/srcversion', 0o664, b'5B93BF2B618524ED19305C8\n')
+f('sys/module/e1000e/refcnt', 0o664, b'0\n')
+d('sys/module/e1000e/drivers', 0o775)
+l('sys/module/e1000e/drivers/pci:e1000e', '../../../bus/pci/drivers/e1000e')
+d('sys/module/e1000e/parameters', 0o775)
+f('sys/module/e1000e/parameters/copybreak', 0o664, b'256\n')
+d('sys/module/e1000e/sections', 0o775)
+f('sys/module/e1000e/sections/.devinit.data', 0o664, b'0xffffffffa0024fe0\n')
+f('sys/module/e1000e/sections/.smp_locks', 0o664, b'0xffffffffa001e730\n')
+f('sys/module/e1000e/sections/__bug_table', 0o664, b'0xffffffffa001e590\n')
+f('sys/module/e1000e/sections/.exit.text', 0o664, b'0xffffffffa001c64f\n')
+f('sys/module/e1000e/sections/.note.gnu.build-id', 0o664, b'0xffffffffa001c750\n')
+f('sys/module/e1000e/sections/.strtab', 0o664, b'0xffffffffa0021ac0\n')
+f('sys/module/e1000e/sections/.devexit.text', 0o664, b'0xffffffffa001c672\n')
+f('sys/module/e1000e/sections/.rodata', 0o664, b'0xffffffffa001c780\n')
+f('sys/module/e1000e/sections/__param', 0o664, b'0xffffffffa001e5f0\n')
+f('sys/module/e1000e/sections/.bss', 0o664, b'0xffffffffa0025800\n')
+f('sys/module/e1000e/sections/.text', 0o664, b'0xffffffffa0009000\n')
+f('sys/module/e1000e/sections/.init.text', 0o664, b'0xffffffffa0027000\n')
+f('sys/module/e1000e/sections/.data', 0o664, b'0xffffffffa00243c0\n')
+f('sys/module/e1000e/sections/.devinit.text', 0o664, b'0xffffffffa001b380\n')
+f('sys/module/e1000e/sections/.symtab', 0o664, b'0xffffffffa001e8b0\n')
+f('sys/module/e1000e/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa0025440\n')
+f('sys/module/e1000e/sections/.rodata.str1.1', 0o664, b'0xffffffffa001d6f0\n')
+d('sys/module/e1000e/notes', 0o775)
+f('sys/module/e1000e/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xcbJ\xb1\x8eG^\xf7\xba\xbf\xa6\x1b\x03\xfasqDl\xf7"\xf1')
+d('sys/module/aes_x86_64', 0o775)
+f('sys/module/aes_x86_64/initstate', 0o664, b'live\n')
+f('sys/module/aes_x86_64/srcversion', 0o664, b'4E315E23114A08593D5D731\n')
+f('sys/module/aes_x86_64/refcnt', 0o664, b'2\n')
+d('sys/module/aes_x86_64/sections', 0o775)
+f('sys/module/aes_x86_64/sections/.exit.text', 0o664, b'0xffffffffa02d471c\n')
+f('sys/module/aes_x86_64/sections/.note.gnu.build-id', 0o664, b'0xffffffffa02d4730\n')
+f('sys/module/aes_x86_64/sections/.strtab', 0o664, b'0xffffffffa02d4b60\n')
+f('sys/module/aes_x86_64/sections/.bss', 0o664, b'0xffffffffa02d5200\n')
+f('sys/module/aes_x86_64/sections/.text', 0o664, b'0xffffffffa02d3000\n')
+f('sys/module/aes_x86_64/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/aes_x86_64/sections/.data', 0o664, b'0xffffffffa02d4d20\n')
+f('sys/module/aes_x86_64/sections/.symtab', 0o664, b'0xffffffffa02d4758\n')
+f('sys/module/aes_x86_64/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa02d4e40\n')
+d('sys/module/aes_x86_64/notes', 0o775)
+f('sys/module/aes_x86_64/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\x1e3\x8c\xa9\xdd\xa1\xeb\\\xcf\xd3\x0f\xd1\xfc\xaa\xd2y\x08+f\xca')
+d('sys/module/dm_mod', 0o775)
+f('sys/module/dm_mod/initstate', 0o664, b'live\n')
+f('sys/module/dm_mod/srcversion', 0o664, b'458AEB289C7AA031FFD0011\n')
+f('sys/module/dm_mod/refcnt', 0o664, b'0\n')
+d('sys/module/dm_mod/sections', 0o775)
+f('sys/module/dm_mod/sections/__ksymtab_gpl', 0o664, b'0xffffffffa02122b0\n')
+f('sys/module/dm_mod/sections/.smp_locks', 0o664, b'0xffffffffa0210eb8\n')
+f('sys/module/dm_mod/sections/__bug_table', 0o664, b'0xffffffffa0211f54\n')
+f('sys/module/dm_mod/sections/__ksymtab_strings', 0o664, b'0xffffffffa0212310\n')
+f('sys/module/dm_mod/sections/.exit.text', 0o664, b'0xffffffffa0210c20\n')
+f('sys/module/dm_mod/sections/.note.gnu.build-id', 0o664, b'0xffffffffa0210c54\n')
+f('sys/module/dm_mod/sections/.strtab', 0o664, b'0xffffffffa02151f0\n')
+f('sys/module/dm_mod/sections/__ksymtab', 0o664, b'0xffffffffa02120d0\n')
+f('sys/module/dm_mod/sections/.rodata', 0o664, b'0xffffffffa0210c80\n')
+f('sys/module/dm_mod/sections/__param', 0o664, b'0xffffffffa02120a8\n')
+f('sys/module/dm_mod/sections/.bss', 0o664, b'0xffffffffa02177c0\n')
+f('sys/module/dm_mod/sections/.text', 0o664, b'0xffffffffa0209000\n')
+f('sys/module/dm_mod/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/dm_mod/sections/__kcrctab', 0o664, b'0xffffffffa0212210\n')
+f('sys/module/dm_mod/sections/.data', 0o664, b'0xffffffffa0216f40\n')
+f('sys/module/dm_mod/sections/.init.data', 0o664, b'0xffffffffa00652c0\n')
+f('sys/module/dm_mod/sections/.symtab', 0o664, b'0xffffffffa02124a8\n')
+f('sys/module/dm_mod/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa0217400\n')
+f('sys/module/dm_mod/sections/.rodata.str1.1', 0o664, b'0xffffffffa0211c4d\n')
+f('sys/module/dm_mod/sections/__kcrctab_gpl', 0o664, b'0xffffffffa02122f0\n')
+d('sys/module/dm_mod/notes', 0o775)
+f('sys/module/dm_mod/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00^(\xdd\x16OD6\xfb\x89\xe6\xca3Vl\xb0\xd7MBp\x84')
+d('sys/module/usbhid', 0o775)
+f('sys/module/usbhid/initstate', 0o664, b'live\n')
+f('sys/module/usbhid/srcversion', 0o664, b'3D7B82FE16E5E534DE4C12B\n')
+f('sys/module/usbhid/refcnt', 0o664, b'0\n')
+d('sys/module/usbhid/drivers', 0o775)
+l('sys/module/usbhid/drivers/usb:usbhid', '../../../bus/usb/drivers/usbhid')
+d('sys/module/usbhid/parameters', 0o775)
+f('sys/module/usbhid/parameters/mousepoll', 0o664, b'0\n')
+f('sys/module/usbhid/parameters/rdesc_quirks', 0o664, b'<NULL>,<NULL>,<NULL>,<NULL>\n')
+f('sys/module/usbhid/parameters/quirks', 0o664, b'<NULL>,<NULL>,<NULL>,<NULL>\n')
+d('sys/module/usbhid/sections', 0o775)
+f('sys/module/usbhid/sections/__ksymtab_gpl', 0o664, b'0xffffffffa0201e60\n')
+f('sys/module/usbhid/sections/.smp_locks', 0o664, b'0xffffffffa0201700\n')
+f('sys/module/usbhid/sections/__ksymtab_strings', 0o664, b'0xffffffffa0201e78\n')
+f('sys/module/usbhid/sections/.exit.text', 0o664, b'0xffffffffa0200c6c\n')
+f('sys/module/usbhid/sections/.note.gnu.build-id', 0o664, b'0xffffffffa0200c84\n')
+f('sys/module/usbhid/sections/.strtab', 0o664, b'0xffffffffa0202e68\n')
+f('sys/module/usbhid/sections/.rodata', 0o664, b'0xffffffffa0200cc0\n')
+f('sys/module/usbhid/sections/__param', 0o664, b'0xffffffffa0201de0\n')
+f('sys/module/usbhid/sections/.bss', 0o664, b'0xffffffffa0203d80\n')
+f('sys/module/usbhid/sections/.text', 0o664, b'0xffffffffa01fe000\n')
+f('sys/module/usbhid/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/usbhid/sections/.data', 0o664, b'0xffffffffa02037c0\n')
+f('sys/module/usbhid/sections/.symtab', 0o664, b'0xffffffffa0201e90\n')
+f('sys/module/usbhid/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa02039c0\n')
+f('sys/module/usbhid/sections/.rodata.str1.1', 0o664, b'0xffffffffa02017a8\n')
+f('sys/module/usbhid/sections/__kcrctab_gpl', 0o664, b'0xffffffffa0201e70\n')
+d('sys/module/usbhid/notes', 0o775)
+f('sys/module/usbhid/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00F\xd8\xa9\xb5\x91:~\xd6KY>\x94\xe1\x1d\xab\xf6\xe5\xeeu*')
+d('sys/module/iwl3945', 0o775)
+f('sys/module/iwl3945/version', 0o664, b'1.2.26ks\n')
+f('sys/module/iwl3945/initstate', 0o664, b'live\n')
+f('sys/module/iwl3945/srcversion', 0o664, b'5C079549ABD48E07B20F3C7\n')
+f('sys/module/iwl3945/refcnt', 0o664, b'0\n')
+d('sys/module/iwl3945/drivers', 0o775)
+l('sys/module/iwl3945/drivers/pci:iwl3945', '../../../bus/pci/drivers/iwl3945')
+d('sys/module/iwl3945/parameters', 0o775)
+f('sys/module/iwl3945/parameters/disable_hw_scan', 0o664, b'0\n')
+f('sys/module/iwl3945/parameters/queues_num', 0o664, b'8\n')
+f('sys/module/iwl3945/parameters/debug', 0o664, b'0\n')
+f('sys/module/iwl3945/parameters/disable', 0o664, b'0\n')
+f('sys/module/iwl3945/parameters/hwcrypto', 0o664, b'0\n')
+f('sys/module/iwl3945/parameters/antenna', 0o664, b'0\n')
+f('sys/module/iwl3945/parameters/qos_enable', 0o664, b'1\n')
+d('sys/module/iwl3945/sections', 0o775)
+f('sys/module/iwl3945/sections/.smp_locks', 0o664, b'0xffffffffa015e0e0\n')
+f('sys/module/iwl3945/sections/__bug_table', 0o664, b'0xffffffffa015e300\n')
+f('sys/module/iwl3945/sections/.exit.text', 0o664, b'0xffffffffa015b2e4\n')
+f('sys/module/iwl3945/sections/.note.gnu.build-id', 0o664, b'0xffffffffa015b2fc\n')
+f('sys/module/iwl3945/sections/.strtab', 0o664, b'0xffffffffa0160f20\n')
+f('sys/module/iwl3945/sections/.devexit.text', 0o664, b'0xffffffffa015b044\n')
+f('sys/module/iwl3945/sections/.rodata', 0o664, b'0xffffffffa015b320\n')
+f('sys/module/iwl3945/sections/__param', 0o664, b'0xffffffffa015e4b0\n')
+f('sys/module/iwl3945/sections/.bss', 0o664, b'0xffffffffa0163d80\n')
+f('sys/module/iwl3945/sections/.text', 0o664, b'0xffffffffa014b000\n')
+f('sys/module/iwl3945/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/iwl3945/sections/.data', 0o664, b'0xffffffffa0162f00\n')
+f('sys/module/iwl3945/sections/.symtab', 0o664, b'0xffffffffa015e5c8\n')
+f('sys/module/iwl3945/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa01639c0\n')
+f('sys/module/iwl3945/sections/.rodata.str1.1', 0o664, b'0xffffffffa015bc0c\n')
+d('sys/module/iwl3945/notes', 0o775)
+f('sys/module/iwl3945/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xd1^"`\xf9\xf2&\x0b\xe0T\x9b\xe1,\xab\x88\x9bos\x0b\xdb')
+d('sys/module/rsrc_nonstatic', 0o775)
+f('sys/module/rsrc_nonstatic/initstate', 0o664, b'live\n')
+f('sys/module/rsrc_nonstatic/srcversion', 0o664, b'8554CBDFE6293476856E830\n')
+f('sys/module/rsrc_nonstatic/refcnt', 0o664, b'1\n')
+d('sys/module/rsrc_nonstatic/holders', 0o775)
+l('sys/module/rsrc_nonstatic/holders/yenta_socket', '../../yenta_socket')
+d('sys/module/rsrc_nonstatic/parameters', 0o775)
+f('sys/module/rsrc_nonstatic/parameters/probe_mem', 0o664, b'1\n')
+d('sys/module/rsrc_nonstatic/sections', 0o775)
+f('sys/module/rsrc_nonstatic/sections/__ksymtab_strings', 0o664, b'0xffffffffa00ef8a0\n')
+f('sys/module/rsrc_nonstatic/sections/.exit.text', 0o664, b'0xffffffffa00ef624\n')
+f('sys/module/rsrc_nonstatic/sections/.note.gnu.build-id', 0o664, b'0xffffffffa00ef69c\n')
+f('sys/module/rsrc_nonstatic/sections/.strtab', 0o664, b'0xffffffffa00f0260\n')
+f('sys/module/rsrc_nonstatic/sections/__ksymtab', 0o664, b'0xffffffffa00ef860\n')
+f('sys/module/rsrc_nonstatic/sections/.devexit.text', 0o664, b'0xffffffffa00ef636\n')
+f('sys/module/rsrc_nonstatic/sections/.rodata', 0o664, b'0xffffffffa00ef6c0\n')
+f('sys/module/rsrc_nonstatic/sections/__param', 0o664, b'0xffffffffa00ef878\n')
+f('sys/module/rsrc_nonstatic/sections/.bss', 0o664, b'0xffffffffa00f0dc0\n')
+f('sys/module/rsrc_nonstatic/sections/.text', 0o664, b'0xffffffffa00ee000\n')
+f('sys/module/rsrc_nonstatic/sections/.init.text', 0o664, b'0xffffffffa0084000\n')
+f('sys/module/rsrc_nonstatic/sections/__kcrctab', 0o664, b'0xffffffffa00ef870\n')
+f('sys/module/rsrc_nonstatic/sections/.ref.data', 0o664, b'0xffffffffa00f09c0\n')
+f('sys/module/rsrc_nonstatic/sections/.data', 0o664, b'0xffffffffa00f0820\n')
+f('sys/module/rsrc_nonstatic/sections/.devinit.text', 0o664, b'0xffffffffa00ef665\n')
+f('sys/module/rsrc_nonstatic/sections/.symtab', 0o664, b'0xffffffffa00ef8b8\n')
+f('sys/module/rsrc_nonstatic/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa00f0a00\n')
+f('sys/module/rsrc_nonstatic/sections/.rodata.str1.1', 0o664, b'0xffffffffa00ef78d\n')
+d('sys/module/rsrc_nonstatic/notes', 0o775)
+f('sys/module/rsrc_nonstatic/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xd5n\x94\x07\x89\xe1\x08\xe3\x07C\xb9\x83\x0c\x19*6\xe8\xe3\x10R')
+d('sys/module/thinkpad_acpi', 0o775)
+f('sys/module/thinkpad_acpi/version', 0o664, b'0.21\n')
+f('sys/module/thinkpad_acpi/initstate', 0o664, b'live\n')
+f('sys/module/thinkpad_acpi/srcversion', 0o664, b'FA276F7EFAA90BF39100654\n')
+f('sys/module/thinkpad_acpi/refcnt', 0o664, b'0\n')
+d('sys/module/thinkpad_acpi/drivers', 0o775)
+l('sys/module/thinkpad_acpi/drivers/platform:thinkpad_hwmon', '../../../bus/platform/drivers/thinkpad_hwmon')
+l('sys/module/thinkpad_acpi/drivers/platform:thinkpad_acpi', '../../../bus/platform/drivers/thinkpad_acpi')
+d('sys/module/thinkpad_acpi/sections', 0o775)
+f('sys/module/thinkpad_acpi/sections/.smp_locks', 0o664, b'0xffffffffa01e6088\n')
+f('sys/module/thinkpad_acpi/sections/__bug_table', 0o664, b'0xffffffffa01e60e0\n')
+f('sys/module/thinkpad_acpi/sections/.note.gnu.build-id', 0o664, b'0xffffffffa01e3a80\n')
+f('sys/module/thinkpad_acpi/sections/.strtab', 0o664, b'0xffffffffa01e98b8\n')
+f('sys/module/thinkpad_acpi/sections/.rodata', 0o664, b'0xffffffffa01e3ac0\n')
+f('sys/module/thinkpad_acpi/sections/__param', 0o664, b'0xffffffffa01e61a0\n')
+f('sys/module/thinkpad_acpi/sections/.bss', 0o664, b'0xffffffffa01ed600\n')
+f('sys/module/thinkpad_acpi/sections/.text', 0o664, b'0xffffffffa01dd000\n')
+f('sys/module/thinkpad_acpi/sections/.init.text', 0o664, b'0xffffffffa01ef000\n')
+f('sys/module/thinkpad_acpi/sections/.data', 0o664, b'0xffffffffa01ebd60\n')
+f('sys/module/thinkpad_acpi/sections/.init.data', 0o664, b'0xffffffffa01f1700\n')
+f('sys/module/thinkpad_acpi/sections/.symtab', 0o664, b'0xffffffffa01e6498\n')
+f('sys/module/thinkpad_acpi/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa01ed240\n')
+f('sys/module/thinkpad_acpi/sections/.rodata.str1.1', 0o664, b'0xffffffffa01e3df0\n')
+d('sys/module/thinkpad_acpi/notes', 0o775)
+f('sys/module/thinkpad_acpi/notes/.note.gnu.build-id', 0o664, b"\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00]\xca\x1f\xba\xb1J'\xa8\x14\x83cj=h\x11\xe60;\x08\xd6")
+d('sys/module/psmouse', 0o775)
+d('sys/module/psmouse/drivers', 0o775)
+l('sys/module/psmouse/drivers/serio:psmouse', '../../../bus/serio/drivers/psmouse')
+d('sys/module/psmouse/parameters', 0o775)
+f('sys/module/psmouse/parameters/proto', 0o664, b'''auto
+
+''')
+f('sys/module/psmouse/parameters/resync_time', 0o664, b'0\n')
+f('sys/module/psmouse/parameters/resolution', 0o664, b'200\n')
+f('sys/module/psmouse/parameters/resetafter', 0o664, b'5\n')
+f('sys/module/psmouse/parameters/rate', 0o664, b'100\n')
+f('sys/module/psmouse/parameters/smartscroll', 0o664, b'Y\n')
+d('sys/module/md_mod', 0o775)
+f('sys/module/md_mod/initstate', 0o664, b'live\n')
+f('sys/module/md_mod/srcversion', 0o664, b'1DB954BE8FA97D4755DC15B\n')
+f('sys/module/md_mod/refcnt', 0o664, b'1\n')
+d('sys/module/md_mod/holders', 0o775)
+l('sys/module/md_mod/holders/raid1', '../../raid1')
+d('sys/module/md_mod/parameters', 0o775)
+f('sys/module/md_mod/parameters/start_ro', 0o664, b'0\n')
+f('sys/module/md_mod/parameters/start_dirty_degraded', 0o664, b'0\n')
+d('sys/module/md_mod/sections', 0o775)
+f('sys/module/md_mod/sections/__ksymtab_gpl', 0o664, b'0xffffffffa022a790\n')
+f('sys/module/md_mod/sections/.smp_locks', 0o664, b'0xffffffffa022a038\n')
+f('sys/module/md_mod/sections/__bug_table', 0o664, b'0xffffffffa022a4b8\n')
+f('sys/module/md_mod/sections/__ksymtab_strings', 0o664, b'0xffffffffa022a7f0\n')
+f('sys/module/md_mod/sections/.exit.text', 0o664, b'0xffffffffa02283a0\n')
+f('sys/module/md_mod/sections/.note.gnu.build-id', 0o664, b'0xffffffffa02284c8\n')
+f('sys/module/md_mod/sections/.strtab', 0o664, b'0xffffffffa022d7a0\n')
+f('sys/module/md_mod/sections/__ksymtab', 0o664, b'0xffffffffa022a590\n')
+f('sys/module/md_mod/sections/.rodata', 0o664, b'0xffffffffa0228500\n')
+f('sys/module/md_mod/sections/__param', 0o664, b'0xffffffffa022a740\n')
+f('sys/module/md_mod/sections/.bss', 0o664, b'0xffffffffa0230880\n')
+f('sys/module/md_mod/sections/.text', 0o664, b'0xffffffffa021a000\n')
+f('sys/module/md_mod/sections/.init.text', 0o664, b'0xffffffffa0070000\n')
+f('sys/module/md_mod/sections/__kcrctab', 0o664, b'0xffffffffa022a6b0\n')
+f('sys/module/md_mod/sections/.data', 0o664, b'0xffffffffa022f660\n')
+f('sys/module/md_mod/sections/.symtab', 0o664, b'0xffffffffa022a968\n')
+f('sys/module/md_mod/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa02304c0\n')
+f('sys/module/md_mod/sections/.rodata.str1.1', 0o664, b'0xffffffffa022869e\n')
+f('sys/module/md_mod/sections/__kcrctab_gpl', 0o664, b'0xffffffffa022a7d0\n')
+d('sys/module/md_mod/notes', 0o775)
+f('sys/module/md_mod/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xbd\xb6!\x84\x88Z\x8bnL\x0f\xf0\xbe\xf0]\n"\xd8\xf3\xb0*')
+d('sys/module/snd_pcm', 0o775)
+f('sys/module/snd_pcm/initstate', 0o664, b'live\n')
+f('sys/module/snd_pcm/srcversion', 0o664, b'96530AD1426FF7F73757C4F\n')
+f('sys/module/snd_pcm/refcnt', 0o664, b'2\n')
+d('sys/module/snd_pcm/holders', 0o775)
+l('sys/module/snd_pcm/holders/snd_hda_intel', '../../snd_hda_intel')
+l('sys/module/snd_pcm/holders/snd_pcm_oss', '../../snd_pcm_oss')
+d('sys/module/snd_pcm/parameters', 0o775)
+f('sys/module/snd_pcm/parameters/preallocate_dma', 0o664, b'1\n')
+f('sys/module/snd_pcm/parameters/maximum_substreams', 0o664, b'4\n')
+d('sys/module/snd_pcm/sections', 0o775)
+f('sys/module/snd_pcm/sections/.smp_locks', 0o664, b'0xffffffffa0141af8\n')
+f('sys/module/snd_pcm/sections/__ex_table', 0o664, b'0xffffffffa0141b30\n')
+f('sys/module/snd_pcm/sections/__ksymtab_strings', 0o664, b'0xffffffffa01415f0\n')
+f('sys/module/snd_pcm/sections/.exit.text', 0o664, b'0xffffffffa01401d4\n')
+f('sys/module/snd_pcm/sections/.note.gnu.build-id', 0o664, b'0xffffffffa0140260\n')
+f('sys/module/snd_pcm/sections/.strtab', 0o664, b'0xffffffffa0145428\n')
+f('sys/module/snd_pcm/sections/.fixup', 0o664, b'0xffffffffa01401fe\n')
+f('sys/module/snd_pcm/sections/__ksymtab', 0o664, b'0xffffffffa01410b0\n')
+f('sys/module/snd_pcm/sections/.rodata', 0o664, b'0xffffffffa01402a0\n')
+f('sys/module/snd_pcm/sections/__param', 0o664, b'0xffffffffa0141bb0\n')
+f('sys/module/snd_pcm/sections/.bss', 0o664, b'0xffffffffa0149640\n')
+f('sys/module/snd_pcm/sections/.text', 0o664, b'0xffffffffa0134000\n')
+f('sys/module/snd_pcm/sections/.init.text', 0o664, b'0xffffffffa007d000\n')
+f('sys/module/snd_pcm/sections/__kcrctab', 0o664, b'0xffffffffa0141430\n')
+f('sys/module/snd_pcm/sections/.data', 0o664, b'0xffffffffa0148b60\n')
+f('sys/module/snd_pcm/sections/.symtab', 0o664, b'0xffffffffa0141c00\n')
+f('sys/module/snd_pcm/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa0149280\n')
+f('sys/module/snd_pcm/sections/.rodata.str1.1', 0o664, b'0xffffffffa0140930\n')
+d('sys/module/snd_pcm/notes', 0o775)
+f('sys/module/snd_pcm/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xc8N\x86\x9c\x8dq\x14\x04\xe7\xed\xee\x9b\xe0\x8f\xe4\x8fvF{\xfe')
+d('sys/module/snd_hda_intel', 0o775)
+f('sys/module/snd_hda_intel/initstate', 0o664, b'live\n')
+f('sys/module/snd_hda_intel/srcversion', 0o664, b'B76633A09F11336101E5480\n')
+f('sys/module/snd_hda_intel/refcnt', 0o664, b'3\n')
+d('sys/module/snd_hda_intel/drivers', 0o775)
+l('sys/module/snd_hda_intel/drivers/pci:HDA Intel', '../../../bus/pci/drivers/HDA Intel')
+d('sys/module/snd_hda_intel/parameters', 0o775)
+f('sys/module/snd_hda_intel/parameters/bdl_pos_adj', 0o664, b'1,-1,-1,-1,-1,-1,-1,-1\n')
+f('sys/module/snd_hda_intel/parameters/enable', 0o664, b'Y,Y,Y,Y,Y,Y,Y,Y\n')
+f('sys/module/snd_hda_intel/parameters/id', 0o664, b'<NULL>,<NULL>,<NULL>,<NULL>,<NULL>,<NULL>,<NULL>,<NULL>\n')
+f('sys/module/snd_hda_intel/parameters/probe_mask', 0o664, b'1,-1,-1,-1,-1,-1,-1,-1\n')
+f('sys/module/snd_hda_intel/parameters/enable_msi', 0o664, b'0\n')
+f('sys/module/snd_hda_intel/parameters/index', 0o664, b'-1,-1,-1,-1,-1,-1,-1,-1\n')
+f('sys/module/snd_hda_intel/parameters/single_cmd', 0o664, b'N\n')
+f('sys/module/snd_hda_intel/parameters/model', 0o664, b'<NULL>,<NULL>,<NULL>,<NULL>,<NULL>,<NULL>,<NULL>,<NULL>\n')
+f('sys/module/snd_hda_intel/parameters/position_fix', 0o664, b'0,0,0,0,0,0,0,0\n')
+d('sys/module/snd_hda_intel/sections', 0o775)
+f('sys/module/snd_hda_intel/sections/.devinit.data', 0o664, b'0xffffffffa01d7340\n')
+f('sys/module/snd_hda_intel/sections/.exit.text', 0o664, b'0xffffffffa0182a58\n')
+f('sys/module/snd_hda_intel/sections/.note.gnu.build-id', 0o664, b'0xffffffffa0183f4c\n')
+f('sys/module/snd_hda_intel/sections/.strtab', 0o664, b'0xffffffffa0193910\n')
+f('sys/module/snd_hda_intel/sections/.devexit.text', 0o664, b'0xffffffffa0182a6a\n')
+f('sys/module/snd_hda_intel/sections/.rodata', 0o664, b'0xffffffffa0183f80\n')
+f('sys/module/snd_hda_intel/sections/__param', 0o664, b'0xffffffffa0189de8\n')
+f('sys/module/snd_hda_intel/sections/.bss', 0o664, b'0xffffffffa01d7800\n')
+f('sys/module/snd_hda_intel/sections/.text', 0o664, b'0xffffffffa0165000\n')
+f('sys/module/snd_hda_intel/sections/.init.text', 0o664, b'0xffffffffa0070000\n')
+f('sys/module/snd_hda_intel/sections/.data', 0o664, b'0xffffffffa019bd40\n')
+f('sys/module/snd_hda_intel/sections/.devinit.text', 0o664, b'0xffffffffa0182aa0\n')
+f('sys/module/snd_hda_intel/sections/.symtab', 0o664, b'0xffffffffa0189f50\n')
+f('sys/module/snd_hda_intel/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa01d7440\n')
+f('sys/module/snd_hda_intel/sections/.rodata.str1.1', 0o664, b'0xffffffffa0186d8b\n')
+d('sys/module/snd_hda_intel/notes', 0o775)
+f('sys/module/snd_hda_intel/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x002\xfe\x91\xd2K\x86\x1d\x92P\xdcX/c\x07=\xf3\xceY\xbc-')
+d('sys/module/ehci_hcd', 0o775)
+f('sys/module/ehci_hcd/initstate', 0o664, b'live\n')
+f('sys/module/ehci_hcd/srcversion', 0o664, b'6EBBF13EC8AD467D8AB11A4\n')
+f('sys/module/ehci_hcd/refcnt', 0o664, b'0\n')
+d('sys/module/ehci_hcd/drivers', 0o775)
+l('sys/module/ehci_hcd/drivers/pci:ehci_hcd', '../../../bus/pci/drivers/ehci_hcd')
+d('sys/module/ehci_hcd/parameters', 0o775)
+f('sys/module/ehci_hcd/parameters/park', 0o664, b'0\n')
+f('sys/module/ehci_hcd/parameters/ignore_oc', 0o664, b'N\n')
+f('sys/module/ehci_hcd/parameters/log2_irq_thresh', 0o664, b'0\n')
+d('sys/module/ehci_hcd/sections', 0o775)
+f('sys/module/ehci_hcd/sections/.smp_locks', 0o664, b'0xffffffffa00e4048\n')
+f('sys/module/ehci_hcd/sections/__bug_table', 0o664, b'0xffffffffa00e3f22\n')
+f('sys/module/ehci_hcd/sections/.exit.text', 0o664, b'0xffffffffa00e3b98\n')
+f('sys/module/ehci_hcd/sections/.note.gnu.build-id', 0o664, b'0xffffffffa00e3bac\n')
+f('sys/module/ehci_hcd/sections/.strtab', 0o664, b'0xffffffffa00e54a8\n')
+f('sys/module/ehci_hcd/sections/.rodata', 0o664, b'0xffffffffa00e3be0\n')
+f('sys/module/ehci_hcd/sections/__param', 0o664, b'0xffffffffa00e42f0\n')
+f('sys/module/ehci_hcd/sections/.bss', 0o664, b'0xffffffffa00e6480\n')
+f('sys/module/ehci_hcd/sections/.text', 0o664, b'0xffffffffa00dd000\n')
+f('sys/module/ehci_hcd/sections/.init.text', 0o664, b'0xffffffffa006b000\n')
+f('sys/module/ehci_hcd/sections/.data', 0o664, b'0xffffffffa00e5f40\n')
+f('sys/module/ehci_hcd/sections/.symtab', 0o664, b'0xffffffffa00e4368\n')
+f('sys/module/ehci_hcd/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa00e60c0\n')
+f('sys/module/ehci_hcd/sections/.rodata.str1.1', 0o664, b'0xffffffffa00e3dd0\n')
+d('sys/module/ehci_hcd/notes', 0o775)
+f('sys/module/ehci_hcd/notes/.note.gnu.build-id', 0o664, b"\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00 \xc7\x01\xa9Mi;\xcaNB'\x08T\xc4\xf9\x80\xd7\x10\xb3h")
+d('sys/module/sg', 0o775)
+f('sys/module/sg/version', 0o664, b'3.5.34\n')
+f('sys/module/sg/initstate', 0o664, b'live\n')
+f('sys/module/sg/srcversion', 0o664, b'DC7DE342543B6D7AB46D718\n')
+f('sys/module/sg/refcnt', 0o664, b'0\n')
+d('sys/module/sg/parameters', 0o775)
+f('sys/module/sg/parameters/allow_dio', 0o664, b'0\n')
+f('sys/module/sg/parameters/scatter_elem_sz', 0o664, b'32768\n')
+f('sys/module/sg/parameters/def_reserved_size', 0o664, b'32768\n')
+d('sys/module/sg/sections', 0o775)
+f('sys/module/sg/sections/.smp_locks', 0o664, b'0xffffffffa00054d8\n')
+f('sys/module/sg/sections/__ex_table', 0o664, b'0xffffffffa0005530\n')
+f('sys/module/sg/sections/__bug_table', 0o664, b'0xffffffffa00054e8\n')
+f('sys/module/sg/sections/.exit.text', 0o664, b'0xffffffffa00049f0\n')
+f('sys/module/sg/sections/.note.gnu.build-id', 0o664, b'0xffffffffa0004afc\n')
+f('sys/module/sg/sections/.strtab', 0o664, b'0xffffffffa0006710\n')
+f('sys/module/sg/sections/.fixup', 0o664, b'0xffffffffa0004a33\n')
+f('sys/module/sg/sections/.rodata', 0o664, b'0xffffffffa0004b20\n')
+f('sys/module/sg/sections/__param', 0o664, b'0xffffffffa0005630\n')
+f('sys/module/sg/sections/.bss', 0o664, b'0xffffffffa0007640\n')
+f('sys/module/sg/sections/.text', 0o664, b'0xffffffffa0000000\n')
+f('sys/module/sg/sections/.init.text', 0o664, b'0xffffffffa0009000\n')
+f('sys/module/sg/sections/.data', 0o664, b'0xffffffffa0007040\n')
+f('sys/module/sg/sections/.symtab', 0o664, b'0xffffffffa00056a8\n')
+f('sys/module/sg/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa0007280\n')
+f('sys/module/sg/sections/.rodata.str1.1', 0o664, b'0xffffffffa0004bc0\n')
+d('sys/module/sg/notes', 0o775)
+f('sys/module/sg/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00q\x06\xb5<\xb3\x13\xd4\xe6\xc5W\xbb;{\x14\x93\xd5\x07\xc7\x13\xfa')
+d('sys/module/snd_mixer_oss', 0o775)
+f('sys/module/snd_mixer_oss/initstate', 0o664, b'live\n')
+f('sys/module/snd_mixer_oss/srcversion', 0o664, b'9D2BFE821DD0ACFA2CFF364\n')
+f('sys/module/snd_mixer_oss/refcnt', 0o664, b'1\n')
+d('sys/module/snd_mixer_oss/holders', 0o775)
+l('sys/module/snd_mixer_oss/holders/snd_pcm_oss', '../../snd_pcm_oss')
+d('sys/module/snd_mixer_oss/sections', 0o775)
+f('sys/module/snd_mixer_oss/sections/__ksymtab_strings', 0o664, b'0xffffffffa02bba78\n')
+f('sys/module/snd_mixer_oss/sections/.exit.text', 0o664, b'0xffffffffa02bb508\n')
+f('sys/module/snd_mixer_oss/sections/.note.gnu.build-id', 0o664, b'0xffffffffa02bb54c\n')
+f('sys/module/snd_mixer_oss/sections/.strtab', 0o664, b'0xffffffffa02bc470\n')
+f('sys/module/snd_mixer_oss/sections/__ksymtab', 0o664, b'0xffffffffa02bba60\n')
+f('sys/module/snd_mixer_oss/sections/.rodata', 0o664, b'0xffffffffa02bb580\n')
+f('sys/module/snd_mixer_oss/sections/.bss', 0o664, b'0xffffffffa02bd240\n')
+f('sys/module/snd_mixer_oss/sections/.text', 0o664, b'0xffffffffa02b9000\n')
+f('sys/module/snd_mixer_oss/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/snd_mixer_oss/sections/__kcrctab', 0o664, b'0xffffffffa02bba70\n')
+f('sys/module/snd_mixer_oss/sections/.data', 0o664, b'0xffffffffa02bcb20\n')
+f('sys/module/snd_mixer_oss/sections/.symtab', 0o664, b'0xffffffffa02bba98\n')
+f('sys/module/snd_mixer_oss/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa02bce80\n')
+f('sys/module/snd_mixer_oss/sections/.rodata.str1.1', 0o664, b'0xffffffffa02bb760\n')
+d('sys/module/snd_mixer_oss/notes', 0o775)
+f('sys/module/snd_mixer_oss/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xc3u\x0b\x0eh,\x90W\xba\xf3S\xa9\x16\\<\x97u\x0f.\xa6')
+d('sys/module/pcmcia', 0o775)
+f('sys/module/pcmcia/initstate', 0o664, b'live\n')
+f('sys/module/pcmcia/srcversion', 0o664, b'6544CB07B8D7D79F19A4CD6\n')
+f('sys/module/pcmcia/refcnt', 0o664, b'0\n')
+d('sys/module/pcmcia/parameters', 0o775)
+f('sys/module/pcmcia/parameters/io_speed', 0o664, b'0\n')
+d('sys/module/pcmcia/sections', 0o775)
+f('sys/module/pcmcia/sections/__ksymtab_strings', 0o664, b'0xffffffffa01f9890\n')
+f('sys/module/pcmcia/sections/.exit.text', 0o664, b'0xffffffffa01f85c4\n')
+f('sys/module/pcmcia/sections/.note.gnu.build-id', 0o664, b'0xffffffffa01f86c8\n')
+f('sys/module/pcmcia/sections/.strtab', 0o664, b'0xffffffffa01fb138\n')
+f('sys/module/pcmcia/sections/__ksymtab', 0o664, b'0xffffffffa01f9710\n')
+f('sys/module/pcmcia/sections/.rodata', 0o664, b'0xffffffffa01f8700\n')
+f('sys/module/pcmcia/sections/__param', 0o664, b'0xffffffffa01f9a00\n')
+f('sys/module/pcmcia/sections/.bss', 0o664, b'0xffffffffa01fcb40\n')
+f('sys/module/pcmcia/sections/.text', 0o664, b'0xffffffffa01f5000\n')
+f('sys/module/pcmcia/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/pcmcia/sections/__kcrctab', 0o664, b'0xffffffffa01f9810\n')
+f('sys/module/pcmcia/sections/.ref.data', 0o664, b'0xffffffffa01fc720\n')
+f('sys/module/pcmcia/sections/.data', 0o664, b'0xffffffffa01fc3a0\n')
+f('sys/module/pcmcia/sections/.devinit.text', 0o664, b'0xffffffffa01f85e2\n')
+f('sys/module/pcmcia/sections/.symtab', 0o664, b'0xffffffffa01f9a28\n')
+f('sys/module/pcmcia/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa01fc780\n')
+f('sys/module/pcmcia/sections/.rodata.str1.1', 0o664, b'0xffffffffa01f913d\n')
+d('sys/module/pcmcia/notes', 0o775)
+f('sys/module/pcmcia/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00v\xd6BR5q\xd2\xd4\x05y\xe0\x84j\x17\xab\xb2\xe6o\xd43')
+d('sys/module/nvram', 0o775)
+f('sys/module/nvram/initstate', 0o664, b'live\n')
+f('sys/module/nvram/srcversion', 0o664, b'ECD12B2949BC771BDCE8146\n')
+f('sys/module/nvram/refcnt', 0o664, b'1\n')
+d('sys/module/nvram/holders', 0o775)
+l('sys/module/nvram/holders/thinkpad_acpi', '../../thinkpad_acpi')
+d('sys/module/nvram/sections', 0o775)
+f('sys/module/nvram/sections/__ksymtab_strings', 0o664, b'0xffffffffa00ad2c0\n')
+f('sys/module/nvram/sections/.exit.text', 0o664, b'0xffffffffa00ace3c\n')
+f('sys/module/nvram/sections/.note.gnu.build-id', 0o664, b'0xffffffffa00ace5c\n')
+f('sys/module/nvram/sections/.strtab', 0o664, b'0xffffffffa00adc38\n')
+f('sys/module/nvram/sections/__ksymtab', 0o664, b'0xffffffffa00ad230\n')
+f('sys/module/nvram/sections/.rodata', 0o664, b'0xffffffffa00ace80\n')
+f('sys/module/nvram/sections/.bss', 0o664, b'0xffffffffa00ae640\n')
+f('sys/module/nvram/sections/.text', 0o664, b'0xffffffffa00ac000\n')
+f('sys/module/nvram/sections/.init.text', 0o664, b'0xffffffffa00b0000\n')
+f('sys/module/nvram/sections/__kcrctab', 0o664, b'0xffffffffa00ad290\n')
+f('sys/module/nvram/sections/.data', 0o664, b'0xffffffffa00ae200\n')
+f('sys/module/nvram/sections/.symtab', 0o664, b'0xffffffffa00ad338\n')
+f('sys/module/nvram/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa00ae280\n')
+f('sys/module/nvram/sections/.rodata.str1.1', 0o664, b'0xffffffffa00acfb8\n')
+d('sys/module/nvram/notes', 0o775)
+f('sys/module/nvram/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\x00j\xf9\trf\x94M\xafD\\s\xced\xcc\x97c\xd5L\n')
+d('sys/module/scsi_mod', 0o775)
+d('sys/module/scsi_mod/parameters', 0o775)
+f('sys/module/scsi_mod/parameters/scan', 0o664, b'sync\n')
+f('sys/module/scsi_mod/parameters/default_dev_flags', 0o664, b'0\n')
+f('sys/module/scsi_mod/parameters/scsi_logging_level', 0o664, b'0\n')
+f('sys/module/scsi_mod/parameters/inq_timeout', 0o664, b'5\n')
+f('sys/module/scsi_mod/parameters/max_luns', 0o664, b'512\n')
+f('sys/module/scsi_mod/parameters/max_report_luns', 0o664, b'511\n')
+d('sys/module/pcmcia_core', 0o775)
+f('sys/module/pcmcia_core/initstate', 0o664, b'live\n')
+f('sys/module/pcmcia_core/srcversion', 0o664, b'7C1220572DE8897E4D560EB\n')
+f('sys/module/pcmcia_core/refcnt', 0o664, b'3\n')
+d('sys/module/pcmcia_core/holders', 0o775)
+l('sys/module/pcmcia_core/holders/yenta_socket', '../../yenta_socket')
+l('sys/module/pcmcia_core/holders/rsrc_nonstatic', '../../rsrc_nonstatic')
+l('sys/module/pcmcia_core/holders/pcmcia', '../../pcmcia')
+d('sys/module/pcmcia_core/parameters', 0o775)
+f('sys/module/pcmcia_core/parameters/setup_delay', 0o664, b'10\n')
+f('sys/module/pcmcia_core/parameters/cis_speed', 0o664, b'300\n')
+f('sys/module/pcmcia_core/parameters/unreset_delay', 0o664, b'10\n')
+f('sys/module/pcmcia_core/parameters/shutdown_delay', 0o664, b'3\n')
+f('sys/module/pcmcia_core/parameters/cis_width', 0o664, b'0\n')
+f('sys/module/pcmcia_core/parameters/unreset_limit', 0o664, b'30\n')
+f('sys/module/pcmcia_core/parameters/reset_time', 0o664, b'10\n')
+f('sys/module/pcmcia_core/parameters/resume_delay', 0o664, b'20\n')
+f('sys/module/pcmcia_core/parameters/unreset_check', 0o664, b'10\n')
+f('sys/module/pcmcia_core/parameters/vcc_settle', 0o664, b'40\n')
+d('sys/module/pcmcia_core/sections', 0o775)
+f('sys/module/pcmcia_core/sections/__ksymtab_strings', 0o664, b'0xffffffffa0094310\n')
+f('sys/module/pcmcia_core/sections/.exit.text', 0o664, b'0xffffffffa0093558\n')
+f('sys/module/pcmcia_core/sections/.note.gnu.build-id', 0o664, b'0xffffffffa0093668\n')
+f('sys/module/pcmcia_core/sections/.strtab', 0o664, b'0xffffffffa0096898\n')
+f('sys/module/pcmcia_core/sections/__ksymtab', 0o664, b'0xffffffffa0093e50\n')
+f('sys/module/pcmcia_core/sections/.rodata', 0o664, b'0xffffffffa00936a0\n')
+f('sys/module/pcmcia_core/sections/__param', 0o664, b'0xffffffffa0094180\n')
+f('sys/module/pcmcia_core/sections/.bss', 0o664, b'0xffffffffa0098f40\n')
+f('sys/module/pcmcia_core/sections/.text', 0o664, b'0xffffffffa008f000\n')
+f('sys/module/pcmcia_core/sections/.init.text', 0o664, b'0xffffffffa009a000\n')
+f('sys/module/pcmcia_core/sections/__kcrctab', 0o664, b'0xffffffffa0094070\n')
+f('sys/module/pcmcia_core/sections/.data', 0o664, b'0xffffffffa0098700\n')
+f('sys/module/pcmcia_core/sections/.symtab', 0o664, b'0xffffffffa00945d0\n')
+f('sys/module/pcmcia_core/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa0098b80\n')
+f('sys/module/pcmcia_core/sections/.rodata.str1.1', 0o664, b'0xffffffffa0093a88\n')
+f('sys/module/pcmcia_core/sections/.ref.text', 0o664, b'0xffffffffa0093580\n')
+d('sys/module/pcmcia_core/notes', 0o775)
+f('sys/module/pcmcia_core/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00M\xe5~\xb9\x10\x7f(\xb8\x18\xe2ma\xb4\xdc\x9a\x8er\xb2t\xbc')
+d('sys/module/rtc_core', 0o775)
+f('sys/module/rtc_core/initstate', 0o664, b'live\n')
+f('sys/module/rtc_core/srcversion', 0o664, b'8684A14821938B7D8E50DB5\n')
+f('sys/module/rtc_core/refcnt', 0o664, b'1\n')
+d('sys/module/rtc_core/holders', 0o775)
+l('sys/module/rtc_core/holders/rtc_cmos', '../../rtc_cmos')
+d('sys/module/rtc_core/sections', 0o775)
+f('sys/module/rtc_core/sections/__ksymtab_gpl', 0o664, b'0xffffffffa00ea380\n')
+f('sys/module/rtc_core/sections/.smp_locks', 0o664, b'0xffffffffa00ea5b8\n')
+f('sys/module/rtc_core/sections/__ksymtab_strings', 0o664, b'0xffffffffa00ea4d0\n')
+f('sys/module/rtc_core/sections/.exit.text', 0o664, b'0xffffffffa00e9e60\n')
+f('sys/module/rtc_core/sections/.note.gnu.build-id', 0o664, b'0xffffffffa00e9ea4\n')
+f('sys/module/rtc_core/sections/.strtab', 0o664, b'0xffffffffa00eb9c0\n')
+f('sys/module/rtc_core/sections/.rodata', 0o664, b'0xffffffffa00e9ee0\n')
+f('sys/module/rtc_core/sections/.bss', 0o664, b'0xffffffffa00ecd80\n')
+f('sys/module/rtc_core/sections/.text', 0o664, b'0xffffffffa00e8000\n')
+f('sys/module/rtc_core/sections/.init.text', 0o664, b'0xffffffffa007d000\n')
+f('sys/module/rtc_core/sections/.data', 0o664, b'0xffffffffa00ec760\n')
+f('sys/module/rtc_core/sections/.symtab', 0o664, b'0xffffffffa00ea5e0\n')
+f('sys/module/rtc_core/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa00ec9c0\n')
+f('sys/module/rtc_core/sections/.rodata.str1.1', 0o664, b'0xffffffffa00ea098\n')
+f('sys/module/rtc_core/sections/__kcrctab_gpl', 0o664, b'0xffffffffa00ea460\n')
+d('sys/module/rtc_core/notes', 0o775)
+f('sys/module/rtc_core/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xfbj\x90X\x98\xf7\x0e\x95\x19\xc6\xa1\xa1\xcd\xe0\x835$\x0e\x96\x17')
+d('sys/module/led_class', 0o775)
+f('sys/module/led_class/initstate', 0o664, b'live\n')
+f('sys/module/led_class/srcversion', 0o664, b'B916A50F53ABBBB19DFF203\n')
+f('sys/module/led_class/refcnt', 0o664, b'2\n')
+d('sys/module/led_class/holders', 0o775)
+l('sys/module/led_class/holders/iwl3945', '../../iwl3945')
+l('sys/module/led_class/holders/thinkpad_acpi', '../../thinkpad_acpi')
+d('sys/module/led_class/sections', 0o775)
+f('sys/module/led_class/sections/__ksymtab_gpl', 0o664, b'0xffffffffa00f23c0\n')
+f('sys/module/led_class/sections/__ksymtab_strings', 0o664, b'0xffffffffa00f2420\n')
+f('sys/module/led_class/sections/.exit.text', 0o664, b'0xffffffffa00f2330\n')
+f('sys/module/led_class/sections/.note.gnu.build-id', 0o664, b'0xffffffffa00f2344\n')
+f('sys/module/led_class/sections/.strtab', 0o664, b'0xffffffffa00f2bf8\n')
+f('sys/module/led_class/sections/.bss', 0o664, b'0xffffffffa00f3500\n')
+f('sys/module/led_class/sections/.text', 0o664, b'0xffffffffa00f2000\n')
+f('sys/module/led_class/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/led_class/sections/.data', 0o664, b'0xffffffffa00f30c0\n')
+f('sys/module/led_class/sections/.symtab', 0o664, b'0xffffffffa00f2478\n')
+f('sys/module/led_class/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa00f3140\n')
+f('sys/module/led_class/sections/.rodata.str1.1', 0o664, b'0xffffffffa00f2368\n')
+f('sys/module/led_class/sections/__kcrctab_gpl', 0o664, b'0xffffffffa00f2400\n')
+d('sys/module/led_class/notes', 0o775)
+f('sys/module/led_class/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00Iq;\xaf\xad\xf1\xe5\xcf8\xa5\x86u\xa9tMV\x02*\xfd\r')
+d('sys/module/libata', 0o775)
+d('sys/module/libata/parameters', 0o775)
+f('sys/module/libata/parameters/acpi_gtf_filter', 0o664, b'7\n')
+f('sys/module/libata/parameters/noacpi', 0o664, b'0\n')
+f('sys/module/libata/parameters/atapi_passthru16', 0o664, b'1\n')
+f('sys/module/libata/parameters/ata_probe_timeout', 0o664, b'0\n')
+f('sys/module/libata/parameters/dma', 0o664, b'7\n')
+f('sys/module/libata/parameters/atapi_dmadir', 0o664, b'0\n')
+f('sys/module/libata/parameters/fua', 0o664, b'0\n')
+f('sys/module/libata/parameters/ignore_hpa', 0o664, b'0\n')
+f('sys/module/libata/parameters/atapi_enabled', 0o664, b'1\n')
+f('sys/module/libata/parameters/allow_tpm', 0o664, b'0\n')
+d('sys/module/thermal', 0o775)
+f('sys/module/thermal/initstate', 0o664, b'live\n')
+f('sys/module/thermal/srcversion', 0o664, b'1787CE9FEB053C917D031A9\n')
+f('sys/module/thermal/refcnt', 0o664, b'0\n')
+d('sys/module/thermal/parameters', 0o775)
+f('sys/module/thermal/parameters/act', 0o664, b'0\n')
+f('sys/module/thermal/parameters/tzp', 0o664, b'0\n')
+f('sys/module/thermal/parameters/crt', 0o664, b'0\n')
+f('sys/module/thermal/parameters/psv', 0o664, b'0\n')
+d('sys/module/thermal/sections', 0o775)
+f('sys/module/thermal/sections/.exit.text', 0o664, b'0xffffffffa00a1f14\n')
+f('sys/module/thermal/sections/.note.gnu.build-id', 0o664, b'0xffffffffa00a1f3c\n')
+f('sys/module/thermal/sections/.strtab', 0o664, b'0xffffffffa00a3b28\n')
+f('sys/module/thermal/sections/.rodata', 0o664, b'0xffffffffa00a1f60\n')
+f('sys/module/thermal/sections/__param', 0o664, b'0xffffffffa00a29d0\n')
+f('sys/module/thermal/sections/.bss', 0o664, b'0xffffffffa00a4bc0\n')
+f('sys/module/thermal/sections/.text', 0o664, b'0xffffffffa00a0000\n')
+f('sys/module/thermal/sections/.init.text', 0o664, b'0xffffffffa0070000\n')
+f('sys/module/thermal/sections/.data', 0o664, b'0xffffffffa00a4640\n')
+f('sys/module/thermal/sections/.init.data', 0o664, b'0xffffffffa0070090\n')
+f('sys/module/thermal/sections/.symtab', 0o664, b'0xffffffffa00a2ac0\n')
+f('sys/module/thermal/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa00a4800\n')
+f('sys/module/thermal/sections/.rodata.str1.1', 0o664, b'0xffffffffa00a242a\n')
+d('sys/module/thermal/notes', 0o775)
+f('sys/module/thermal/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\x97\xa9\xec\xf2\x01\x86!\x94\x89\xa4n%q\t\xb7\xb4\x97a\x1a\x85')
+d('sys/module/keyboard', 0o775)
+d('sys/module/keyboard/parameters', 0o775)
+f('sys/module/keyboard/parameters/brl_nbchords', 0o664, b'1\n')
+f('sys/module/keyboard/parameters/brl_timeout', 0o664, b'300\n')
+d('sys/module/ahci', 0o775)
+d('sys/module/ahci/drivers', 0o775)
+l('sys/module/ahci/drivers/pci:ahci', '../../../bus/pci/drivers/ahci')
+d('sys/module/ahci/parameters', 0o775)
+f('sys/module/ahci/parameters/marvell_enable', 0o664, b'1\n')
+f('sys/module/ahci/parameters/ahci_em_messages', 0o664, b'1\n')
+f('sys/module/ahci/parameters/skip_host_reset', 0o664, b'0\n')
+d('sys/module/snd_pcm_oss', 0o775)
+f('sys/module/snd_pcm_oss/initstate', 0o664, b'live\n')
+f('sys/module/snd_pcm_oss/srcversion', 0o664, b'E3D05A52B04130012283029\n')
+f('sys/module/snd_pcm_oss/refcnt', 0o664, b'0\n')
+d('sys/module/snd_pcm_oss/parameters', 0o775)
+f('sys/module/snd_pcm_oss/parameters/dsp_map', 0o664, b'0,0,0,0,0,0,0,0\n')
+f('sys/module/snd_pcm_oss/parameters/nonblock_open', 0o664, b'Y\n')
+f('sys/module/snd_pcm_oss/parameters/adsp_map', 0o664, b'1,1,1,1,1,1,1,1\n')
+d('sys/module/snd_pcm_oss/sections', 0o775)
+f('sys/module/snd_pcm_oss/sections/.exit.text', 0o664, b'0xffffffffa02c6e7c\n')
+f('sys/module/snd_pcm_oss/sections/.note.gnu.build-id', 0o664, b'0xffffffffa02c6e94\n')
+f('sys/module/snd_pcm_oss/sections/.strtab', 0o664, b'0xffffffffa02c8818\n')
+f('sys/module/snd_pcm_oss/sections/.rodata', 0o664, b'0xffffffffa02c6ec0\n')
+f('sys/module/snd_pcm_oss/sections/__param', 0o664, b'0xffffffffa02c7378\n')
+f('sys/module/snd_pcm_oss/sections/.bss', 0o664, b'0xffffffffa02c9b00\n')
+f('sys/module/snd_pcm_oss/sections/.text', 0o664, b'0xffffffffa02bf000\n')
+f('sys/module/snd_pcm_oss/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/snd_pcm_oss/sections/.data', 0o664, b'0xffffffffa02c96c0\n')
+f('sys/module/snd_pcm_oss/sections/.symtab', 0o664, b'0xffffffffa02c73f0\n')
+f('sys/module/snd_pcm_oss/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa02c9740\n')
+f('sys/module/snd_pcm_oss/sections/.rodata.str1.1', 0o664, b'0xffffffffa02c71a8\n')
+d('sys/module/snd_pcm_oss/notes', 0o775)
+f('sys/module/snd_pcm_oss/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xd7y|\xbf\xa5\x8aZm\x86\x85CF\x11s\xd3\xf5f\xbd7\xc6')
+d('sys/module/ac', 0o775)
+f('sys/module/ac/initstate', 0o664, b'live\n')
+f('sys/module/ac/srcversion', 0o664, b'6E9CD20EE5BE8425A61B938\n')
+f('sys/module/ac/refcnt', 0o664, b'0\n')
+d('sys/module/ac/sections', 0o775)
+f('sys/module/ac/sections/.exit.text', 0o664, b'0xffffffffa006d43c\n')
+f('sys/module/ac/sections/.note.gnu.build-id', 0o664, b'0xffffffffa006d45c\n')
+f('sys/module/ac/sections/.strtab', 0o664, b'0xffffffffa006dd28\n')
+f('sys/module/ac/sections/.rodata', 0o664, b'0xffffffffa006d480\n')
+f('sys/module/ac/sections/.bss', 0o664, b'0xffffffffa006e600\n')
+f('sys/module/ac/sections/.text', 0o664, b'0xffffffffa006d000\n')
+f('sys/module/ac/sections/.init.text', 0o664, b'0xffffffffa0070000\n')
+f('sys/module/ac/sections/.data', 0o664, b'0xffffffffa006e0d0\n')
+f('sys/module/ac/sections/.symtab', 0o664, b'0xffffffffa006d668\n')
+f('sys/module/ac/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa006e240\n')
+f('sys/module/ac/sections/.rodata.str1.1', 0o664, b'0xffffffffa006d5a0\n')
+d('sys/module/ac/notes', 0o775)
+f('sys/module/ac/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00^h\xf0\x19\xcc\x94"G\xf8\xbc\x1c\xf0\xa3\x8d?\xec\xa5\xc4\x95\x9f')
+d('sys/module/dock', 0o775)
+d('sys/module/dock/parameters', 0o775)
+f('sys/module/dock/parameters/immediate_undock', 0o664, b'Y\n')
+d('sys/module/pcie_aspm', 0o775)
+d('sys/module/pcie_aspm/parameters', 0o775)
+f('sys/module/pcie_aspm/parameters/policy', 0o664, b'[default] performance powersave \n')
+d('sys/module/lockdep', 0o775)
+d('sys/module/lockdep/parameters', 0o775)
+f('sys/module/lockdep/parameters/lock_stat', 0o664, b'1\n')
+d('sys/module/tcp_cubic', 0o775)
+d('sys/module/tcp_cubic/parameters', 0o775)
+f('sys/module/tcp_cubic/parameters/tcp_friendliness', 0o664, b'1\n')
+f('sys/module/tcp_cubic/parameters/beta', 0o664, b'717\n')
+f('sys/module/tcp_cubic/parameters/bic_scale', 0o664, b'41\n')
+f('sys/module/tcp_cubic/parameters/fast_convergence', 0o664, b'1\n')
+f('sys/module/tcp_cubic/parameters/initial_ssthresh', 0o664, b'0\n')
+d('sys/module/ecb', 0o775)
+f('sys/module/ecb/initstate', 0o664, b'live\n')
+f('sys/module/ecb/srcversion', 0o664, b'5BBA8E5CDEA4EA8BA5ED31D\n')
+f('sys/module/ecb/refcnt', 0o664, b'2\n')
+d('sys/module/ecb/sections', 0o775)
+f('sys/module/ecb/sections/.exit.text', 0o664, b'0xffffffffa0027300\n')
+f('sys/module/ecb/sections/.note.gnu.build-id', 0o664, b'0xffffffffa0027314\n')
+f('sys/module/ecb/sections/.strtab', 0o664, b'0xffffffffa00277c0\n')
+f('sys/module/ecb/sections/.bss', 0o664, b'0xffffffffa0027e80\n')
+f('sys/module/ecb/sections/.text', 0o664, b'0xffffffffa0027000\n')
+f('sys/module/ecb/sections/.init.text', 0o664, b'0xffffffffa006b000\n')
+f('sys/module/ecb/sections/.data', 0o664, b'0xffffffffa0027a40\n')
+f('sys/module/ecb/sections/.symtab', 0o664, b'0xffffffffa0027340\n')
+f('sys/module/ecb/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa0027ac0\n')
+f('sys/module/ecb/sections/.rodata.str1.1', 0o664, b'0xffffffffa0027338\n')
+d('sys/module/ecb/notes', 0o775)
+f('sys/module/ecb/notes/.note.gnu.build-id', 0o664, b"\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xc20'\x18T\x8bW#\xf5\xe5\xf8JvI\xcb\xc4\x91\x95\nJ")
+d('sys/module/snd_page_alloc', 0o775)
+f('sys/module/snd_page_alloc/initstate', 0o664, b'live\n')
+f('sys/module/snd_page_alloc/srcversion', 0o664, b'D9E59C27F28D5DA2B935016\n')
+f('sys/module/snd_page_alloc/refcnt', 0o664, b'2\n')
+d('sys/module/snd_page_alloc/holders', 0o775)
+l('sys/module/snd_page_alloc/holders/snd_pcm', '../../snd_pcm')
+l('sys/module/snd_page_alloc/holders/snd_hda_intel', '../../snd_hda_intel')
+d('sys/module/snd_page_alloc/sections', 0o775)
+f('sys/module/snd_page_alloc/sections/__ksymtab_strings', 0o664, b'0xffffffffa00350e8\n')
+f('sys/module/snd_page_alloc/sections/.exit.text', 0o664, b'0xffffffffa0034cc0\n')
+f('sys/module/snd_page_alloc/sections/.note.gnu.build-id', 0o664, b'0xffffffffa0034cf8\n')
+f('sys/module/snd_page_alloc/sections/.strtab', 0o664, b'0xffffffffa0035be8\n')
+f('sys/module/snd_page_alloc/sections/__ksymtab', 0o664, b'0xffffffffa0035040\n')
+f('sys/module/snd_page_alloc/sections/.rodata', 0o664, b'0xffffffffa0034d20\n')
+f('sys/module/snd_page_alloc/sections/.bss', 0o664, b'0xffffffffa0036780\n')
+f('sys/module/snd_page_alloc/sections/.text', 0o664, b'0xffffffffa0034000\n')
+f('sys/module/snd_page_alloc/sections/.init.text', 0o664, b'0xffffffffa0038000\n')
+f('sys/module/snd_page_alloc/sections/__kcrctab', 0o664, b'0xffffffffa00350b0\n')
+f('sys/module/snd_page_alloc/sections/.data', 0o664, b'0xffffffffa0036300\n')
+f('sys/module/snd_page_alloc/sections/.symtab', 0o664, b'0xffffffffa0035180\n')
+f('sys/module/snd_page_alloc/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa00363c0\n')
+f('sys/module/snd_page_alloc/sections/.rodata.str1.1', 0o664, b'0xffffffffa0034fd5\n')
+d('sys/module/snd_page_alloc/notes', 0o775)
+f('sys/module/snd_page_alloc/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00s\xc1\x8a\x9a\xf7g\x83-x\xc0\xbe\x98\xb0[\x95"\xd7\x97Q=')
+d('sys/module/loop', 0o775)
+f('sys/module/loop/initstate', 0o664, b'live\n')
+f('sys/module/loop/srcversion', 0o664, b'7595F5D46DFDB4A2D489DDD\n')
+f('sys/module/loop/refcnt', 0o664, b'0\n')
+d('sys/module/loop/sections', 0o775)
+f('sys/module/loop/sections/__bug_table', 0o664, b'0xffffffffa023ca1f\n')
+f('sys/module/loop/sections/__ksymtab_strings', 0o664, b'0xffffffffa023caf0\n')
+f('sys/module/loop/sections/.exit.text', 0o664, b'0xffffffffa023c72c\n')
+f('sys/module/loop/sections/.note.gnu.build-id', 0o664, b'0xffffffffa023c7e4\n')
+f('sys/module/loop/sections/.strtab', 0o664, b'0xffffffffa023d960\n')
+f('sys/module/loop/sections/__ksymtab', 0o664, b'0xffffffffa023ca70\n')
+f('sys/module/loop/sections/.rodata', 0o664, b'0xffffffffa023c808\n')
+f('sys/module/loop/sections/__param', 0o664, b'0xffffffffa023caa0\n')
+f('sys/module/loop/sections/.bss', 0o664, b'0xffffffffa023e780\n')
+f('sys/module/loop/sections/.text', 0o664, b'0xffffffffa023a000\n')
+f('sys/module/loop/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/loop/sections/__kcrctab', 0o664, b'0xffffffffa023ca90\n')
+f('sys/module/loop/sections/.data', 0o664, b'0xffffffffa023e180\n')
+f('sys/module/loop/sections/.symtab', 0o664, b'0xffffffffa023cb20\n')
+f('sys/module/loop/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa023e3c0\n')
+f('sys/module/loop/sections/.rodata.str1.1', 0o664, b'0xffffffffa023c88a\n')
+d('sys/module/loop/notes', 0o775)
+f('sys/module/loop/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x007;\xf4\xa1\x0e\xe8\x13\xedX\xe6\xbc\xa4\xcd\xde_\x7fe\x84\x90\x85')
+d('sys/module/aes_generic', 0o775)
+f('sys/module/aes_generic/initstate', 0o664, b'live\n')
+f('sys/module/aes_generic/srcversion', 0o664, b'CE7DEF557FD2F72DE36DE4A\n')
+f('sys/module/aes_generic/refcnt', 0o664, b'1\n')
+d('sys/module/aes_generic/holders', 0o775)
+l('sys/module/aes_generic/holders/aes_x86_64', '../../aes_x86_64')
+d('sys/module/aes_generic/sections', 0o775)
+f('sys/module/aes_generic/sections/__ksymtab_gpl', 0o664, b'0xffffffffa02ccef0\n')
+f('sys/module/aes_generic/sections/__ksymtab_strings', 0o664, b'0xffffffffa02ccf80\n')
+f('sys/module/aes_generic/sections/.exit.text', 0o664, b'0xffffffffa02cceb8\n')
+f('sys/module/aes_generic/sections/.note.gnu.build-id', 0o664, b'0xffffffffa02ccecc\n')
+f('sys/module/aes_generic/sections/.strtab', 0o664, b'0xffffffffa02cd678\n')
+f('sys/module/aes_generic/sections/.bss', 0o664, b'0xffffffffa02cdf80\n')
+f('sys/module/aes_generic/sections/.text', 0o664, b'0xffffffffa02cb000\n')
+f('sys/module/aes_generic/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/aes_generic/sections/.data', 0o664, b'0xffffffffa02cda80\n')
+f('sys/module/aes_generic/sections/.init.data', 0o664, b'0xffffffffa0065300\n')
+f('sys/module/aes_generic/sections/.symtab', 0o664, b'0xffffffffa02ccfe8\n')
+f('sys/module/aes_generic/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa02cdbc0\n')
+f('sys/module/aes_generic/sections/__kcrctab_gpl', 0o664, b'0xffffffffa02ccf50\n')
+d('sys/module/aes_generic/notes', 0o775)
+f('sys/module/aes_generic/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00V@\xa6&\x10\xf7X\xe0q\xbf\xb9G\xd9d\x004\x06h\xe6\x13')
+d('sys/module/snd_seq_device', 0o775)
+f('sys/module/snd_seq_device/initstate', 0o664, b'live\n')
+f('sys/module/snd_seq_device/srcversion', 0o664, b'A166653189DAF15E3F2B588\n')
+f('sys/module/snd_seq_device/refcnt', 0o664, b'1\n')
+d('sys/module/snd_seq_device/holders', 0o775)
+l('sys/module/snd_seq_device/holders/snd_seq', '../../snd_seq')
+d('sys/module/snd_seq_device/sections', 0o775)
+f('sys/module/snd_seq_device/sections/__ksymtab_strings', 0o664, b'0xffffffffa02a5d10\n')
+f('sys/module/snd_seq_device/sections/.exit.text', 0o664, b'0xffffffffa02a5a5c\n')
+f('sys/module/snd_seq_device/sections/.note.gnu.build-id', 0o664, b'0xffffffffa02a5a90\n')
+f('sys/module/snd_seq_device/sections/.strtab', 0o664, b'0xffffffffa02a66e0\n')
+f('sys/module/snd_seq_device/sections/__ksymtab', 0o664, b'0xffffffffa02a5c80\n')
+f('sys/module/snd_seq_device/sections/.bss', 0o664, b'0xffffffffa02a7280\n')
+f('sys/module/snd_seq_device/sections/.text', 0o664, b'0xffffffffa02a5000\n')
+f('sys/module/snd_seq_device/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/snd_seq_device/sections/__kcrctab', 0o664, b'0xffffffffa02a5ce0\n')
+f('sys/module/snd_seq_device/sections/.data', 0o664, b'0xffffffffa02a6de0\n')
+f('sys/module/snd_seq_device/sections/.symtab', 0o664, b'0xffffffffa02a5db0\n')
+f('sys/module/snd_seq_device/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa02a6ec0\n')
+f('sys/module/snd_seq_device/sections/.rodata.str1.1', 0o664, b'0xffffffffa02a5bd0\n')
+d('sys/module/snd_seq_device/notes', 0o775)
+f('sys/module/snd_seq_device/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xb6B\x93\xc2\xcc\x83\xa8\xfc\xc2r\xf6\x8c\xcej\n\xc5\x87ys\r')
+d('sys/module/8250', 0o775)
+d('sys/module/8250/parameters', 0o775)
+f('sys/module/8250/parameters/share_irqs', 0o664, b'0\n')
+f('sys/module/8250/parameters/nr_uarts', 0o664, b'4\n')
+d('sys/module/ipv6', 0o775)
+f('sys/module/ipv6/initstate', 0o664, b'live\n')
+f('sys/module/ipv6/srcversion', 0o664, b'184C844E7A78529619B4C9D\n')
+f('sys/module/ipv6/refcnt', 0o664, b'10\n')
+d('sys/module/ipv6/sections', 0o775)
+f('sys/module/ipv6/sections/__ksymtab_gpl', 0o664, b'0xffffffffa028ac10\n')
+f('sys/module/ipv6/sections/.smp_locks', 0o664, b'0xffffffffa028a240\n')
+f('sys/module/ipv6/sections/__bug_table', 0o664, b'0xffffffffa0288edd\n')
+f('sys/module/ipv6/sections/__ksymtab_strings', 0o664, b'0xffffffffa028b108\n')
+f('sys/module/ipv6/sections/.exit.text', 0o664, b'0xffffffffa0285e40\n')
+f('sys/module/ipv6/sections/.note.gnu.build-id', 0o664, b'0xffffffffa0286024\n')
+f('sys/module/ipv6/sections/.strtab', 0o664, b'0xffffffffa02937f0\n')
+f('sys/module/ipv6/sections/__ksymtab', 0o664, b'0xffffffffa028ad90\n')
+f('sys/module/ipv6/sections/.rodata', 0o664, b'0xffffffffa0286060\n')
+f('sys/module/ipv6/sections/.data.read_mostly', 0o664, b'0xffffffffa029cf20\n')
+f('sys/module/ipv6/sections/.bss', 0o664, b'0xffffffffa029dd80\n')
+f('sys/module/ipv6/sections/.text', 0o664, b'0xffffffffa0258000\n')
+f('sys/module/ipv6/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/ipv6/sections/__kcrctab', 0o664, b'0xffffffffa028afe0\n')
+f('sys/module/ipv6/sections/.data', 0o664, b'0xffffffffa02998c0\n')
+f('sys/module/ipv6/sections/.init.data', 0o664, b'0xffffffffa0065d80\n')
+f('sys/module/ipv6/sections/.symtab', 0o664, b'0xffffffffa028b4c8\n')
+f('sys/module/ipv6/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa029d9c0\n')
+f('sys/module/ipv6/sections/.rodata.str1.1', 0o664, b'0xffffffffa02883c0\n')
+f('sys/module/ipv6/sections/.ref.text', 0o664, b'0xffffffffa0285f40\n')
+f('sys/module/ipv6/sections/__kcrctab_gpl', 0o664, b'0xffffffffa028ad10\n')
+d('sys/module/ipv6/notes', 0o775)
+f('sys/module/ipv6/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\x90\x01\xde\xf3>\xfd_r\xbc\xbb\x16\xbd\xceIf\xc2vC\xbd\xc9')
+d('sys/module/microcode', 0o775)
+f('sys/module/microcode/initstate', 0o664, b'live\n')
+f('sys/module/microcode/srcversion', 0o664, b'FC3DA13E858B639D12F2043\n')
+f('sys/module/microcode/refcnt', 0o664, b'0\n')
+d('sys/module/microcode/sections', 0o775)
+f('sys/module/microcode/sections/__bug_table', 0o664, b'0xffffffffa02516f7\n')
+f('sys/module/microcode/sections/.exit.text', 0o664, b'0xffffffffa0250ff6\n')
+f('sys/module/microcode/sections/.note.gnu.build-id', 0o664, b'0xffffffffa0251040\n')
+f('sys/module/microcode/sections/.strtab', 0o664, b'0xffffffffa02520b8\n')
+f('sys/module/microcode/sections/.rodata', 0o664, b'0xffffffffa0251080\n')
+f('sys/module/microcode/sections/.bss', 0o664, b'0xffffffffa0252c40\n')
+f('sys/module/microcode/sections/.text', 0o664, b'0xffffffffa0250000\n')
+f('sys/module/microcode/sections/.init.text', 0o664, b'0xffffffffa0065000\n')
+f('sys/module/microcode/sections/.ref.data', 0o664, b'0xffffffffa0252850\n')
+f('sys/module/microcode/sections/.data', 0o664, b'0xffffffffa0252600\n')
+f('sys/module/microcode/sections/.symtab', 0o664, b'0xffffffffa0251740\n')
+f('sys/module/microcode/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa0252880\n')
+f('sys/module/microcode/sections/.rodata.str1.1', 0o664, b'0xffffffffa0251218\n')
+f('sys/module/microcode/sections/.cpuinit.text', 0o664, b'0xffffffffa0250d90\n')
+d('sys/module/microcode/notes', 0o775)
+f('sys/module/microcode/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\x81 p\x0b\x99+\x14\x05\x9c\xb2\xf6{\xacs\xa9\xf3<\xb5\x99\x1a')
+d('sys/module/i8042', 0o775)
+d('sys/module/i8042/parameters', 0o775)
+f('sys/module/i8042/parameters/debug', 0o664, b'N\n')
+f('sys/module/i8042/parameters/panicblink', 0o664, b'500\n')
+d('sys/module/usbcore', 0o775)
+f('sys/module/usbcore/initstate', 0o664, b'live\n')
+f('sys/module/usbcore/srcversion', 0o664, b'4FF77EB8DAB25F4076D7357\n')
+f('sys/module/usbcore/refcnt', 0o664, b'5\n')
+d('sys/module/usbcore/holders', 0o775)
+l('sys/module/usbcore/holders/uhci_hcd', '../../uhci_hcd')
+l('sys/module/usbcore/holders/usb_storage', '../../usb_storage')
+l('sys/module/usbcore/holders/cdc_acm', '../../cdc_acm')
+l('sys/module/usbcore/holders/usbhid', '../../usbhid')
+l('sys/module/usbcore/holders/ehci_hcd', '../../ehci_hcd')
+d('sys/module/usbcore/drivers', 0o775)
+l('sys/module/usbcore/drivers/usb:usbfs', '../../../bus/usb/drivers/usbfs')
+l('sys/module/usbcore/drivers/usb:usb', '../../../bus/usb/drivers/usb')
+l('sys/module/usbcore/drivers/usb:hub', '../../../bus/usb/drivers/hub')
+d('sys/module/usbcore/parameters', 0o775)
+f('sys/module/usbcore/parameters/use_both_schemes', 0o664, b'Y\n')
+f('sys/module/usbcore/parameters/blinkenlights', 0o664, b'N\n')
+f('sys/module/usbcore/parameters/usbfs_snoop', 0o664, b'N\n')
+f('sys/module/usbcore/parameters/autosuspend', 0o664, b'2\n')
+f('sys/module/usbcore/parameters/nousb', 0o664, b'N\n')
+f('sys/module/usbcore/parameters/old_scheme_first', 0o664, b'N\n')
+d('sys/module/usbcore/sections', 0o775)
+f('sys/module/usbcore/sections/__ksymtab_gpl', 0o664, b'0xffffffffa004ea30\n')
+f('sys/module/usbcore/sections/.smp_locks', 0o664, b'0xffffffffa004f930\n')
+f('sys/module/usbcore/sections/__ex_table', 0o664, b'0xffffffffa004fa58\n')
+f('sys/module/usbcore/sections/__bug_table', 0o664, b'0xffffffffa004fa40\n')
+f('sys/module/usbcore/sections/__ksymtab_strings', 0o664, b'0xffffffffa004f300\n')
+f('sys/module/usbcore/sections/.exit.text', 0o664, b'0xffffffffa004ba30\n')
+f('sys/module/usbcore/sections/.note.gnu.build-id', 0o664, b'0xffffffffa004bb30\n')
+f('sys/module/usbcore/sections/.strtab', 0o664, b'0xffffffffa0055cf8\n')
+f('sys/module/usbcore/sections/.fixup', 0o664, b'0xffffffffa004ba87\n')
+f('sys/module/usbcore/sections/.rodata', 0o664, b'0xffffffffa004bb60\n')
+f('sys/module/usbcore/sections/__param', 0o664, b'0xffffffffa004f210\n')
+f('sys/module/usbcore/sections/.bss', 0o664, b'0xffffffffa005cec0\n')
+f('sys/module/usbcore/sections/.text', 0o664, b'0xffffffffa0038000\n')
+f('sys/module/usbcore/sections/.init.text', 0o664, b'0xffffffffa0027000\n')
+f('sys/module/usbcore/sections/.data', 0o664, b'0xffffffffa005af00\n')
+f('sys/module/usbcore/sections/.symtab', 0o664, b'0xffffffffa004fb18\n')
+f('sys/module/usbcore/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa005cb00\n')
+f('sys/module/usbcore/sections/.rodata.str1.1', 0o664, b'0xffffffffa004c044\n')
+f('sys/module/usbcore/sections/__kcrctab_gpl', 0o664, b'0xffffffffa004ef70\n')
+d('sys/module/usbcore/notes', 0o775)
+f('sys/module/usbcore/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00!\xbeP\xa2@m\xffg\xff\x1b\xa8\x8f\xd2\xb3\x11\x14[\xb0\x89\x1e')
+d('sys/module/intel_agp', 0o775)
+f('sys/module/intel_agp/initstate', 0o664, b'live\n')
+f('sys/module/intel_agp/srcversion', 0o664, b'98AFACFFF6A1ADC3A6FAB67\n')
+f('sys/module/intel_agp/refcnt', 0o664, b'0\n')
+d('sys/module/intel_agp/drivers', 0o775)
+l('sys/module/intel_agp/drivers/pci:agpgart-intel', '../../../bus/pci/drivers/agpgart-intel')
+d('sys/module/intel_agp/sections', 0o775)
+f('sys/module/intel_agp/sections/.smp_locks', 0o664, b'0xffffffffa008ae38\n')
+f('sys/module/intel_agp/sections/.exit.text', 0o664, b'0xffffffffa00893ac\n')
+f('sys/module/intel_agp/sections/.note.gnu.build-id', 0o664, b'0xffffffffa00896b0\n')
+f('sys/module/intel_agp/sections/.strtab', 0o664, b'0xffffffffa008c1b8\n')
+f('sys/module/intel_agp/sections/.devexit.text', 0o664, b'0xffffffffa00893be\n')
+f('sys/module/intel_agp/sections/.rodata', 0o664, b'0xffffffffa00896e0\n')
+f('sys/module/intel_agp/sections/.bss', 0o664, b'0xffffffffa008da00\n')
+f('sys/module/intel_agp/sections/.text', 0o664, b'0xffffffffa0086000\n')
+f('sys/module/intel_agp/sections/.init.text', 0o664, b'0xffffffffa008f000\n')
+f('sys/module/intel_agp/sections/.data', 0o664, b'0xffffffffa008cf60\n')
+f('sys/module/intel_agp/sections/.devinit.text', 0o664, b'0xffffffffa0089400\n')
+f('sys/module/intel_agp/sections/.symtab', 0o664, b'0xffffffffa008ae50\n')
+f('sys/module/intel_agp/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa008d640\n')
+f('sys/module/intel_agp/sections/.rodata.str1.1', 0o664, b'0xffffffffa008a9c0\n')
+d('sys/module/intel_agp/notes', 0o775)
+f('sys/module/intel_agp/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\xb0\xb5IU\x04F\xdb\x80\xdf\x9a8\xedq\x0b\xd4\xc7K\x851\x86')
+d('sys/module/evdev', 0o775)
+f('sys/module/evdev/initstate', 0o664, b'live\n')
+f('sys/module/evdev/srcversion', 0o664, b'6F6934C1F95317926EA0520\n')
+f('sys/module/evdev/refcnt', 0o664, b'5\n')
+d('sys/module/evdev/sections', 0o775)
+f('sys/module/evdev/sections/.exit.text', 0o664, b'0xffffffffa00b3724\n')
+f('sys/module/evdev/sections/.note.gnu.build-id', 0o664, b'0xffffffffa00b3738\n')
+f('sys/module/evdev/sections/.strtab', 0o664, b'0xffffffffa00b4610\n')
+f('sys/module/evdev/sections/.rodata', 0o664, b'0xffffffffa00b3760\n')
+f('sys/module/evdev/sections/.bss', 0o664, b'0xffffffffa00b50c0\n')
+f('sys/module/evdev/sections/.text', 0o664, b'0xffffffffa00b2000\n')
+f('sys/module/evdev/sections/.init.text', 0o664, b'0xffffffffa00b7000\n')
+f('sys/module/evdev/sections/.data', 0o664, b'0xffffffffa00b4be0\n')
+f('sys/module/evdev/sections/.symtab', 0o664, b'0xffffffffa00b3b60\n')
+f('sys/module/evdev/sections/.gnu.linkonce.this_module', 0o664, b'0xffffffffa00b4d00\n')
+f('sys/module/evdev/sections/.rodata.str1.1', 0o664, b'0xffffffffa00b3a38\n')
+d('sys/module/evdev/notes', 0o775)
+f('sys/module/evdev/notes/.note.gnu.build-id', 0o664, b'\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00\x8d/u!\xb1\xf2\xe7\x10z\x8a\xf7\x0c\x88\x17\x1c4i\\2\xa8')
+d('sys/module/atkbd', 0o775)
+d('sys/module/atkbd/drivers', 0o775)
+l('sys/module/atkbd/drivers/serio:atkbd', '../../../bus/serio/drivers/atkbd')
+d('sys/class', 0o755)
+d('sys/class/rfkill', 0o755)
+l('sys/class/rfkill/rfkill0', '../../devices/platform/thinkpad_acpi/rfkill/rfkill0')
+d('sys/class/rtc', 0o755)
+l('sys/class/rtc/rtc0', '../../devices/pnp0/00:07/rtc/rtc0')
+d('sys/class/usb_endpoint', 0o755)
+l('sys/class/usb_endpoint/usbdev1.1_ep00', '../../devices/pci0000:00/0000:00:1d.0/usb1/usb_endpoint/usbdev1.1_ep00')
+l('sys/class/usb_endpoint/usbdev4.3_ep83', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep83')
+l('sys/class/usb_endpoint/usbdev4.2_ep04', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep04')
+l('sys/class/usb_endpoint/usbdev1.1_ep81', '../../devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/usb_endpoint/usbdev1.1_ep81')
+l('sys/class/usb_endpoint/usbdev3.1_ep81', '../../devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/usb_endpoint/usbdev3.1_ep81')
+l('sys/class/usb_endpoint/usbdev4.1_ep00', '../../devices/pci0000:00/0000:00:1d.3/usb4/usb_endpoint/usbdev4.1_ep00')
+l('sys/class/usb_endpoint/usbdev3.4_ep00', '../../devices/pci0000:00/0000:00:1d.2/usb3/3-1/usb_endpoint/usbdev3.4_ep00')
+l('sys/class/usb_endpoint/usbdev4.2_ep00', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-1/usb_endpoint/usbdev4.2_ep00')
+l('sys/class/usb_endpoint/usbdev5.7_ep81', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep81')
+l('sys/class/usb_endpoint/usbdev5.9_ep81', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/usb_endpoint/usbdev5.9_ep81')
+l('sys/class/usb_endpoint/usbdev5.9_ep83', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/usb_endpoint/usbdev5.9_ep83')
+l('sys/class/usb_endpoint/usbdev5.9_ep84', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep84')
+l('sys/class/usb_endpoint/usbdev5.9_ep00', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/usb_endpoint/usbdev5.9_ep00')
+l('sys/class/usb_endpoint/usbdev4.2_ep03', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep03')
+l('sys/class/usb_endpoint/usbdev4.2_ep84', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep84')
+l('sys/class/usb_endpoint/usbdev3.1_ep00', '../../devices/pci0000:00/0000:00:1d.2/usb3/usb_endpoint/usbdev3.1_ep00')
+l('sys/class/usb_endpoint/usbdev4.2_ep83', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep83')
+l('sys/class/usb_endpoint/usbdev4.2_ep02', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep02')
+l('sys/class/usb_endpoint/usbdev4.3_ep00', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-2/usb_endpoint/usbdev4.3_ep00')
+l('sys/class/usb_endpoint/usbdev5.7_ep00', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/usb_endpoint/usbdev5.7_ep00')
+l('sys/class/usb_endpoint/usbdev4.1_ep81', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/usb_endpoint/usbdev4.1_ep81')
+l('sys/class/usb_endpoint/usbdev5.9_ep02', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep02')
+l('sys/class/usb_endpoint/usbdev4.2_ep82', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep82')
+l('sys/class/usb_endpoint/usbdev2.1_ep81', '../../devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/usb_endpoint/usbdev2.1_ep81')
+l('sys/class/usb_endpoint/usbdev4.3_ep81', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep81')
+l('sys/class/usb_endpoint/usbdev2.1_ep00', '../../devices/pci0000:00/0000:00:1d.1/usb2/usb_endpoint/usbdev2.1_ep00')
+l('sys/class/usb_endpoint/usbdev5.1_ep81', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/usb_endpoint/usbdev5.1_ep81')
+l('sys/class/usb_endpoint/usbdev4.2_ep81', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep81')
+l('sys/class/usb_endpoint/usbdev3.4_ep81', '../../devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/usb_endpoint/usbdev3.4_ep81')
+l('sys/class/usb_endpoint/usbdev4.3_ep02', '../../devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep02')
+l('sys/class/usb_endpoint/usbdev5.7_ep02', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep02')
+l('sys/class/usb_endpoint/usbdev5.1_ep00', '../../devices/pci0000:00/0000:00:1d.7/usb5/usb_endpoint/usbdev5.1_ep00')
+l('sys/class/usb_endpoint/usbdev5.9_ep01', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep01')
+l('sys/class/usb_endpoint/usbdev5.9_ep82', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep82')
+d('sys/class/ieee80211', 0o755)
+l('sys/class/ieee80211/phy0', '../../devices/pci0000:00/0000:00:1c.1/0000:03:00.0/ieee80211/phy0')
+d('sys/class/scsi_disk', 0o755)
+l('sys/class/scsi_disk/7:0:0:0', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_disk/7:0:0:0')
+l('sys/class/scsi_disk/0:0:0:0', '../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0')
+d('sys/class/vc', 0o755)
+l('sys/class/vc/vcsa3', '../../devices/virtual/vc/vcsa3')
+l('sys/class/vc/vcsa6', '../../devices/virtual/vc/vcsa6')
+l('sys/class/vc/vcsa2', '../../devices/virtual/vc/vcsa2')
+l('sys/class/vc/vcsa', '../../devices/virtual/vc/vcsa')
+l('sys/class/vc/vcs2', '../../devices/virtual/vc/vcs2')
+l('sys/class/vc/vcs7', '../../devices/virtual/vc/vcs7')
+l('sys/class/vc/vcsa5', '../../devices/virtual/vc/vcsa5')
+l('sys/class/vc/vcsa10', '../../devices/virtual/vc/vcsa10')
+l('sys/class/vc/vcs10', '../../devices/virtual/vc/vcs10')
+l('sys/class/vc/vcsa1', '../../devices/virtual/vc/vcsa1')
+l('sys/class/vc/vcsa4', '../../devices/virtual/vc/vcsa4')
+l('sys/class/vc/vcs', '../../devices/virtual/vc/vcs')
+l('sys/class/vc/vcs1', '../../devices/virtual/vc/vcs1')
+l('sys/class/vc/vcs4', '../../devices/virtual/vc/vcs4')
+l('sys/class/vc/vcsa7', '../../devices/virtual/vc/vcsa7')
+l('sys/class/vc/vcs6', '../../devices/virtual/vc/vcs6')
+l('sys/class/vc/vcs3', '../../devices/virtual/vc/vcs3')
+l('sys/class/vc/vcs5', '../../devices/virtual/vc/vcs5')
+d('sys/class/mem', 0o755)
+l('sys/class/mem/zero', '../../devices/virtual/mem/zero')
+l('sys/class/mem/kmsg', '../../devices/virtual/mem/kmsg')
+l('sys/class/mem/mem', '../../devices/virtual/mem/mem')
+l('sys/class/mem/urandom', '../../devices/virtual/mem/urandom')
+l('sys/class/mem/port', '../../devices/virtual/mem/port')
+l('sys/class/mem/null', '../../devices/virtual/mem/null')
+l('sys/class/mem/kmem', '../../devices/virtual/mem/kmem')
+l('sys/class/mem/full', '../../devices/virtual/mem/full')
+l('sys/class/mem/random', '../../devices/virtual/mem/random')
+d('sys/class/pci_bus', 0o755)
+l('sys/class/pci_bus/0000:00', '../../devices/pci0000:00/pci_bus/0000:00')
+l('sys/class/pci_bus/0000:01', '../../devices/pci0000:00/0000:00:01.0/pci_bus/0000:01')
+l('sys/class/pci_bus/0000:03', '../../devices/pci0000:00/0000:00:1c.1/pci_bus/0000:03')
+l('sys/class/pci_bus/0000:0c', '../../devices/pci0000:00/0000:00:1c.3/pci_bus/0000:0c')
+l('sys/class/pci_bus/0000:16', '../../devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pci_bus/0000:16')
+l('sys/class/pci_bus/0000:04', '../../devices/pci0000:00/0000:00:1c.2/pci_bus/0000:04')
+l('sys/class/pci_bus/0000:02', '../../devices/pci0000:00/0000:00:1c.0/pci_bus/0000:02')
+l('sys/class/pci_bus/0000:15', '../../devices/pci0000:00/0000:00:1e.0/pci_bus/0000:15')
+d('sys/class/hwmon', 0o755)
+l('sys/class/hwmon/hwmon0', '../../devices/platform/thinkpad_hwmon/hwmon/hwmon0')
+d('sys/class/net', 0o755)
+l('sys/class/net/wmaster0', '../../devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0')
+l('sys/class/net/wlan0', '../../devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0')
+l('sys/class/net/lo', '../../devices/virtual/net/lo')
+l('sys/class/net/eth0', '../../devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0')
+d('sys/class/dmi', 0o755)
+l('sys/class/dmi/id', '../../devices/virtual/dmi/id')
+d('sys/class/firmware', 0o755)
+f('sys/class/firmware/timeout', 0o644, b'60\n')
+d('sys/class/scsi_generic', 0o755)
+l('sys/class/scsi_generic/sg0', '../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_generic/sg0')
+l('sys/class/scsi_generic/sg1', '../../devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/scsi_generic/sg1')
+l('sys/class/scsi_generic/sg2', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_generic/sg2')
+d('sys/class/bdi', 0o755)
+l('sys/class/bdi/7:1', '../../devices/virtual/bdi/7:1')
+l('sys/class/bdi/7:0', '../../devices/virtual/bdi/7:0')
+l('sys/class/bdi/7:2', '../../devices/virtual/bdi/7:2')
+l('sys/class/bdi/7:4', '../../devices/virtual/bdi/7:4')
+l('sys/class/bdi/7:3', '../../devices/virtual/bdi/7:3')
+l('sys/class/bdi/11:0', '../../devices/virtual/bdi/11:0')
+l('sys/class/bdi/7:5', '../../devices/virtual/bdi/7:5')
+l('sys/class/bdi/8:0', '../../devices/virtual/bdi/8:0')
+l('sys/class/bdi/default', '../../devices/virtual/bdi/default')
+l('sys/class/bdi/0:16', '../../devices/virtual/bdi/0:16')
+l('sys/class/bdi/8:16', '../../devices/virtual/bdi/8:16')
+l('sys/class/bdi/9:0', '../../devices/virtual/bdi/9:0')
+l('sys/class/bdi/7:7', '../../devices/virtual/bdi/7:7')
+l('sys/class/bdi/7:6', '../../devices/virtual/bdi/7:6')
+d('sys/class/leds', 0o755)
+l('sys/class/leds/iwl-phy0:TX', '../../devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:TX')
+l('sys/class/leds/tpacpi::bay_active', '../../devices/platform/thinkpad_acpi/leds/tpacpi::bay_active')
+l('sys/class/leds/tpacpi:orange:batt', '../../devices/platform/thinkpad_acpi/leds/tpacpi:orange:batt')
+l('sys/class/leds/tpacpi::dock_active', '../../devices/platform/thinkpad_acpi/leds/tpacpi::dock_active')
+l('sys/class/leds/tpacpi::unknown_led', '../../devices/platform/thinkpad_acpi/leds/tpacpi::unknown_led')
+l('sys/class/leds/iwl-phy0:assoc', '../../devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:assoc')
+l('sys/class/leds/tpacpi:green:batt', '../../devices/platform/thinkpad_acpi/leds/tpacpi:green:batt')
+l('sys/class/leds/iwl-phy0:radio', '../../devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:radio')
+l('sys/class/leds/iwl-phy0:RX', '../../devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:RX')
+l('sys/class/leds/tpacpi::dock_batt', '../../devices/platform/thinkpad_acpi/leds/tpacpi::dock_batt')
+l('sys/class/leds/tpacpi::thinklight', '../../devices/platform/thinkpad_acpi/leds/tpacpi::thinklight')
+l('sys/class/leds/tpacpi::power', '../../devices/platform/thinkpad_acpi/leds/tpacpi::power')
+l('sys/class/leds/tpacpi::standby', '../../devices/platform/thinkpad_acpi/leds/tpacpi::standby')
+d('sys/class/usb_host', 0o755)
+l('sys/class/usb_host/usb_host1', '../../devices/pci0000:00/0000:00:1d.0/usb_host/usb_host1')
+l('sys/class/usb_host/usb_host2', '../../devices/pci0000:00/0000:00:1d.1/usb_host/usb_host2')
+l('sys/class/usb_host/usb_host4', '../../devices/pci0000:00/0000:00:1d.3/usb_host/usb_host4')
+l('sys/class/usb_host/usb_host5', '../../devices/pci0000:00/0000:00:1d.7/usb_host/usb_host5')
+l('sys/class/usb_host/usb_host3', '../../devices/pci0000:00/0000:00:1d.2/usb_host/usb_host3')
+d('sys/class/pcmcia_socket', 0o755)
+l('sys/class/pcmcia_socket/pcmcia_socket0', '../../devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pcmcia_socket/pcmcia_socket0')
+d('sys/class/sound', 0o755)
+l('sys/class/sound/audio', '../../devices/pci0000:00/0000:00:1b.0/sound/card0/audio')
+l('sys/class/sound/dsp', '../../devices/pci0000:00/0000:00:1b.0/sound/card0/dsp')
+l('sys/class/sound/timer', '../../devices/virtual/sound/timer')
+l('sys/class/sound/card0', '../../devices/pci0000:00/0000:00:1b.0/sound/card0')
+l('sys/class/sound/seq', '../../devices/virtual/sound/seq')
+l('sys/class/sound/mixer', '../../devices/pci0000:00/0000:00:1b.0/sound/card0/mixer')
+l('sys/class/sound/pcmC0D0p', '../../devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D0p')
+l('sys/class/sound/controlC0', '../../devices/pci0000:00/0000:00:1b.0/sound/card0/controlC0')
+l('sys/class/sound/pcmC0D0c', '../../devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D0c')
+l('sys/class/sound/adsp', '../../devices/pci0000:00/0000:00:1b.0/sound/card0/adsp')
+l('sys/class/sound/pcmC0D1p', '../../devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D1p')
+d('sys/class/misc', 0o755)
+l('sys/class/misc/uinput', '../../devices/virtual/misc/uinput')
+l('sys/class/misc/fuse', '../../devices/virtual/misc/fuse')
+l('sys/class/misc/hpet', '../../devices/virtual/misc/hpet')
+l('sys/class/misc/cpu_dma_latency', '../../devices/virtual/misc/cpu_dma_latency')
+l('sys/class/misc/mcelog', '../../devices/virtual/misc/mcelog')
+l('sys/class/misc/device-mapper', '../../devices/virtual/misc/device-mapper')
+l('sys/class/misc/psaux', '../../devices/virtual/misc/psaux')
+l('sys/class/misc/nvram', '../../devices/virtual/misc/nvram')
+l('sys/class/misc/network_latency', '../../devices/virtual/misc/network_latency')
+l('sys/class/misc/network_throughput', '../../devices/virtual/misc/network_throughput')
+l('sys/class/misc/microcode', '../../devices/virtual/misc/microcode')
+d('sys/class/vtconsole', 0o755)
+l('sys/class/vtconsole/vtcon1', '../../devices/virtual/vtconsole/vtcon1')
+l('sys/class/vtconsole/vtcon0', '../../devices/virtual/vtconsole/vtcon0')
+d('sys/class/bsg', 0o755)
+l('sys/class/bsg/7:0:0:0', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/bsg/7:0:0:0')
+l('sys/class/bsg/0:0:0:0', '../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0')
+l('sys/class/bsg/4:0:0:0', '../../devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/bsg/4:0:0:0')
+d('sys/class/input', 0o755)
+l('sys/class/input/event0', '../../devices/platform/i8042/serio0/input/input0/event0')
+l('sys/class/input/input0', '../../devices/platform/i8042/serio0/input/input0')
+l('sys/class/input/event4', '../../devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/event4')
+l('sys/class/input/mouse0', '../../devices/platform/i8042/serio1/input/input1/mouse0')
+l('sys/class/input/mouse1', '../../devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/mouse1')
+l('sys/class/input/event2', '../../devices/platform/pcspkr/input/input2/event2')
+l('sys/class/input/input2', '../../devices/platform/pcspkr/input/input2')
+l('sys/class/input/input5', '../../devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5')
+l('sys/class/input/input8', '../../devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8')
+l('sys/class/input/input3', '../../devices/LNXSYSTM:00/LNXPWRBN:00/input/input3')
+l('sys/class/input/input1', '../../devices/platform/i8042/serio1/input/input1')
+l('sys/class/input/mice', '../../devices/virtual/input/mice')
+l('sys/class/input/event6', '../../devices/virtual/input/input6/event6')
+l('sys/class/input/input6', '../../devices/virtual/input/input6')
+l('sys/class/input/event3', '../../devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/event3')
+l('sys/class/input/event1', '../../devices/platform/i8042/serio1/input/input1/event1')
+l('sys/class/input/input4', '../../devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4')
+l('sys/class/input/event7', '../../devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/event7')
+l('sys/class/input/event5', '../../devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/event5')
+d('sys/class/thermal', 0o755)
+l('sys/class/thermal/thermal_zone1', '../../devices/virtual/thermal/thermal_zone1')
+l('sys/class/thermal/cooling_device1', '../../devices/virtual/thermal/cooling_device1')
+l('sys/class/thermal/cooling_device0', '../../devices/virtual/thermal/cooling_device0')
+l('sys/class/thermal/thermal_zone0', '../../devices/virtual/thermal/thermal_zone0')
+d('sys/class/power_supply', 0o755)
+l('sys/class/power_supply/AC', '../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/ACPI0003:00/power_supply/AC')
+l('sys/class/power_supply/BAT0', '../../devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0')
+d('sys/class/block', 0o755)
+l('sys/class/block/loop1', '../../devices/virtual/block/loop1')
+l('sys/class/block/loop7', '../../devices/virtual/block/loop7')
+l('sys/class/block/loop0', '../../devices/virtual/block/loop0')
+l('sys/class/block/sda10', '../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10')
+l('sys/class/block/sr0', '../../devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0')
+l('sys/class/block/loop5', '../../devices/virtual/block/loop5')
+l('sys/class/block/loop3', '../../devices/virtual/block/loop3')
+l('sys/class/block/sda9', '../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9')
+l('sys/class/block/sda7', '../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7')
+l('sys/class/block/loop6', '../../devices/virtual/block/loop6')
+l('sys/class/block/sdb', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb')
+l('sys/class/block/sda1', '../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1')
+l('sys/class/block/loop2', '../../devices/virtual/block/loop2')
+l('sys/class/block/sda8', '../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8')
+l('sys/class/block/sda5', '../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5')
+l('sys/class/block/loop4', '../../devices/virtual/block/loop4')
+l('sys/class/block/sda6', '../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6')
+l('sys/class/block/sda', '../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda')
+l('sys/class/block/md0', '../../devices/virtual/block/md0')
+l('sys/class/block/sdb1', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/sdb1')
+d('sys/class/scsi_host', 0o755)
+l('sys/class/scsi_host/host0', '../../devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0')
+l('sys/class/scsi_host/host5', '../../devices/pci0000:00/0000:00:1f.1/host5/scsi_host/host5')
+l('sys/class/scsi_host/host1', '../../devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1')
+l('sys/class/scsi_host/host4', '../../devices/pci0000:00/0000:00:1f.1/host4/scsi_host/host4')
+l('sys/class/scsi_host/host2', '../../devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2')
+l('sys/class/scsi_host/host7', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/scsi_host/host7')
+l('sys/class/scsi_host/host3', '../../devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3')
+d('sys/class/graphics', 0o755)
+l('sys/class/graphics/fbcon', '../../devices/virtual/graphics/fbcon')
+l('sys/class/graphics/fb0', '../../devices/platform/vesafb.0/graphics/fb0')
+d('sys/class/tty', 0o755)
+l('sys/class/tty/tty51', '../../devices/virtual/tty/tty51')
+l('sys/class/tty/tty24', '../../devices/virtual/tty/tty24')
+l('sys/class/tty/tty61', '../../devices/virtual/tty/tty61')
+l('sys/class/tty/ttyS1', '../../devices/platform/serial8250/tty/ttyS1')
+l('sys/class/tty/tty40', '../../devices/virtual/tty/tty40')
+l('sys/class/tty/tty60', '../../devices/virtual/tty/tty60')
+l('sys/class/tty/tty15', '../../devices/virtual/tty/tty15')
+l('sys/class/tty/tty27', '../../devices/virtual/tty/tty27')
+l('sys/class/tty/tty7', '../../devices/virtual/tty/tty7')
+l('sys/class/tty/tty43', '../../devices/virtual/tty/tty43')
+l('sys/class/tty/tty23', '../../devices/virtual/tty/tty23')
+l('sys/class/tty/tty14', '../../devices/virtual/tty/tty14')
+l('sys/class/tty/tty56', '../../devices/virtual/tty/tty56')
+l('sys/class/tty/tty3', '../../devices/virtual/tty/tty3')
+l('sys/class/tty/ttyS3', '../../devices/platform/serial8250/tty/ttyS3')
+l('sys/class/tty/tty49', '../../devices/virtual/tty/tty49')
+l('sys/class/tty/tty47', '../../devices/virtual/tty/tty47')
+l('sys/class/tty/tty57', '../../devices/virtual/tty/tty57')
+l('sys/class/tty/tty30', '../../devices/virtual/tty/tty30')
+l('sys/class/tty/tty45', '../../devices/virtual/tty/tty45')
+l('sys/class/tty/tty22', '../../devices/virtual/tty/tty22')
+l('sys/class/tty/tty55', '../../devices/virtual/tty/tty55')
+l('sys/class/tty/tty11', '../../devices/virtual/tty/tty11')
+l('sys/class/tty/tty53', '../../devices/virtual/tty/tty53')
+l('sys/class/tty/tty12', '../../devices/virtual/tty/tty12')
+l('sys/class/tty/tty28', '../../devices/virtual/tty/tty28')
+l('sys/class/tty/tty58', '../../devices/virtual/tty/tty58')
+l('sys/class/tty/tty32', '../../devices/virtual/tty/tty32')
+l('sys/class/tty/tty44', '../../devices/virtual/tty/tty44')
+l('sys/class/tty/tty6', '../../devices/virtual/tty/tty6')
+l('sys/class/tty/tty9', '../../devices/virtual/tty/tty9')
+l('sys/class/tty/tty26', '../../devices/virtual/tty/tty26')
+l('sys/class/tty/tty10', '../../devices/virtual/tty/tty10')
+l('sys/class/tty/tty39', '../../devices/virtual/tty/tty39')
+l('sys/class/tty/tty0', '../../devices/virtual/tty/tty0')
+l('sys/class/tty/tty36', '../../devices/virtual/tty/tty36')
+l('sys/class/tty/tty34', '../../devices/virtual/tty/tty34')
+l('sys/class/tty/tty16', '../../devices/virtual/tty/tty16')
+l('sys/class/tty/tty25', '../../devices/virtual/tty/tty25')
+l('sys/class/tty/tty13', '../../devices/virtual/tty/tty13')
+l('sys/class/tty/tty52', '../../devices/virtual/tty/tty52')
+l('sys/class/tty/ttyS0', '../../devices/platform/serial8250/tty/ttyS0')
+l('sys/class/tty/tty31', '../../devices/virtual/tty/tty31')
+l('sys/class/tty/tty35', '../../devices/virtual/tty/tty35')
+l('sys/class/tty/tty54', '../../devices/virtual/tty/tty54')
+l('sys/class/tty/tty63', '../../devices/virtual/tty/tty63')
+l('sys/class/tty/tty1', '../../devices/virtual/tty/tty1')
+l('sys/class/tty/tty33', '../../devices/virtual/tty/tty33')
+l('sys/class/tty/tty18', '../../devices/virtual/tty/tty18')
+l('sys/class/tty/ttyACM0', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0')
+l('sys/class/tty/tty42', '../../devices/virtual/tty/tty42')
+l('sys/class/tty/tty8', '../../devices/virtual/tty/tty8')
+l('sys/class/tty/tty37', '../../devices/virtual/tty/tty37')
+l('sys/class/tty/tty5', '../../devices/virtual/tty/tty5')
+l('sys/class/tty/tty48', '../../devices/virtual/tty/tty48')
+l('sys/class/tty/tty17', '../../devices/virtual/tty/tty17')
+l('sys/class/tty/tty62', '../../devices/virtual/tty/tty62')
+l('sys/class/tty/tty59', '../../devices/virtual/tty/tty59')
+l('sys/class/tty/tty50', '../../devices/virtual/tty/tty50')
+l('sys/class/tty/tty21', '../../devices/virtual/tty/tty21')
+l('sys/class/tty/ttyS2', '../../devices/platform/serial8250/tty/ttyS2')
+l('sys/class/tty/tty19', '../../devices/virtual/tty/tty19')
+l('sys/class/tty/ptmx', '../../devices/virtual/tty/ptmx')
+l('sys/class/tty/tty46', '../../devices/virtual/tty/tty46')
+l('sys/class/tty/tty2', '../../devices/virtual/tty/tty2')
+l('sys/class/tty/console', '../../devices/virtual/tty/console')
+l('sys/class/tty/tty41', '../../devices/virtual/tty/tty41')
+l('sys/class/tty/tty4', '../../devices/virtual/tty/tty4')
+l('sys/class/tty/tty29', '../../devices/virtual/tty/tty29')
+l('sys/class/tty/tty', '../../devices/virtual/tty/tty')
+l('sys/class/tty/tty38', '../../devices/virtual/tty/tty38')
+l('sys/class/tty/tty20', '../../devices/virtual/tty/tty20')
+d('sys/class/scsi_device', 0o755)
+l('sys/class/scsi_device/7:0:0:0', '../../devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_device/7:0:0:0')
+l('sys/class/scsi_device/0:0:0:0', '../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_device/0:0:0:0')
+l('sys/class/scsi_device/4:0:0:0', '../../devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/scsi_device/4:0:0:0')
+d('sys/block', 0o755)
+l('sys/block/loop1', '../devices/virtual/block/loop1')
+l('sys/block/loop7', '../devices/virtual/block/loop7')
+l('sys/block/loop0', '../devices/virtual/block/loop0')
+l('sys/block/sr0', '../devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0')
+l('sys/block/loop5', '../devices/virtual/block/loop5')
+l('sys/block/loop3', '../devices/virtual/block/loop3')
+l('sys/block/loop6', '../devices/virtual/block/loop6')
+l('sys/block/sdb', '../devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb')
+l('sys/block/loop2', '../devices/virtual/block/loop2')
+l('sys/block/loop4', '../devices/virtual/block/loop4')
+l('sys/block/sda', '../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda')
+l('sys/block/md0', '../devices/virtual/block/md0')
+d('sys/devices', 0o755)
+d('sys/devices/system', 0o755)
+d('sys/devices/system/machinecheck', 0o755)
+d('sys/devices/system/machinecheck/machinecheck1', 0o755)
+f('sys/devices/system/machinecheck/machinecheck1/trigger', 0o644, b'\n')
+f('sys/devices/system/machinecheck/machinecheck1/bank0ctl', 0o644, b'ffffffffffffffff\n')
+f('sys/devices/system/machinecheck/machinecheck1/check_interval', 0o644, b'12c\n')
+f('sys/devices/system/machinecheck/machinecheck1/tolerant', 0o644, b'1\n')
+f('sys/devices/system/machinecheck/machinecheck1/bank1ctl', 0o644, b'ffffffffffffffff\n')
+f('sys/devices/system/machinecheck/machinecheck1/bank5ctl', 0o644, b'ffffffffffffffff\n')
+f('sys/devices/system/machinecheck/machinecheck1/bank3ctl', 0o644, b'ffffffffffffffff\n')
+f('sys/devices/system/machinecheck/machinecheck1/bank2ctl', 0o644, b'ffffffffffffffff\n')
+f('sys/devices/system/machinecheck/machinecheck1/bank4ctl', 0o644, b'ffffffffffffffff\n')
+d('sys/devices/system/machinecheck/machinecheck0', 0o755)
+f('sys/devices/system/machinecheck/machinecheck0/trigger', 0o644, b'\n')
+f('sys/devices/system/machinecheck/machinecheck0/bank0ctl', 0o644, b'ffffffffffffffff\n')
+f('sys/devices/system/machinecheck/machinecheck0/check_interval', 0o644, b'12c\n')
+f('sys/devices/system/machinecheck/machinecheck0/tolerant', 0o644, b'1\n')
+f('sys/devices/system/machinecheck/machinecheck0/bank1ctl', 0o644, b'ffffffffffffffff\n')
+f('sys/devices/system/machinecheck/machinecheck0/bank5ctl', 0o644, b'ffffffffffffffff\n')
+f('sys/devices/system/machinecheck/machinecheck0/bank3ctl', 0o644, b'ffffffffffffffff\n')
+f('sys/devices/system/machinecheck/machinecheck0/bank2ctl', 0o644, b'ffffffffffffffff\n')
+f('sys/devices/system/machinecheck/machinecheck0/bank4ctl', 0o644, b'ffffffffffffffff\n')
+d('sys/devices/system/clocksource', 0o755)
+d('sys/devices/system/clocksource/clocksource0', 0o755)
+f('sys/devices/system/clocksource/clocksource0/available_clocksource', 0o644, b'hpet acpi_pm jiffies tsc \n')
+f('sys/devices/system/clocksource/clocksource0/current_clocksource', 0o644, b'hpet\n')
+d('sys/devices/system/cpu', 0o755)
+f('sys/devices/system/cpu/possible', 0o644, b'0-1\n')
+f('sys/devices/system/cpu/online', 0o644, b'0-1\n')
+f('sys/devices/system/cpu/present', 0o644, b'0-1\n')
+f('sys/devices/system/cpu/sched_mc_power_savings', 0o644, b'1\n')
+d('sys/devices/system/cpu/cpu0', 0o755)
+f('sys/devices/system/cpu/cpu0/crash_notes', 0o644, b'7fb20920\n')
+d('sys/devices/system/cpu/cpu0/topology', 0o755)
+f('sys/devices/system/cpu/cpu0/topology/thread_siblings', 0o644, b'01\n')
+f('sys/devices/system/cpu/cpu0/topology/thread_siblings_list', 0o644, b'0\n')
+f('sys/devices/system/cpu/cpu0/topology/core_siblings_list', 0o644, b'0-1\n')
+f('sys/devices/system/cpu/cpu0/topology/core_siblings', 0o644, b'03\n')
+f('sys/devices/system/cpu/cpu0/topology/core_id', 0o644, b'0\n')
+f('sys/devices/system/cpu/cpu0/topology/physical_package_id', 0o644, b'0\n')
+d('sys/devices/system/cpu/cpu0/thermal_throttle', 0o755)
+f('sys/devices/system/cpu/cpu0/thermal_throttle/count', 0o644, b'0\n')
+d('sys/devices/system/cpu/cpu0/cache', 0o755)
+d('sys/devices/system/cpu/cpu0/cache/index0', 0o755)
+f('sys/devices/system/cpu/cpu0/cache/index0/ways_of_associativity', 0o644, b'8\n')
+f('sys/devices/system/cpu/cpu0/cache/index0/type', 0o644, b'Data\n')
+f('sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size', 0o644, b'64\n')
+f('sys/devices/system/cpu/cpu0/cache/index0/number_of_sets', 0o644, b'64\n')
+f('sys/devices/system/cpu/cpu0/cache/index0/size', 0o644, b'32K\n')
+f('sys/devices/system/cpu/cpu0/cache/index0/physical_line_partition', 0o644, b'1\n')
+f('sys/devices/system/cpu/cpu0/cache/index0/shared_cpu_map', 0o644, b'01\n')
+f('sys/devices/system/cpu/cpu0/cache/index0/level', 0o644, b'1\n')
+f('sys/devices/system/cpu/cpu0/cache/index0/shared_cpu_list', 0o644, b'0\n')
+d('sys/devices/system/cpu/cpu0/cache/index2', 0o755)
+f('sys/devices/system/cpu/cpu0/cache/index2/ways_of_associativity', 0o644, b'16\n')
+f('sys/devices/system/cpu/cpu0/cache/index2/type', 0o644, b'Unified\n')
+f('sys/devices/system/cpu/cpu0/cache/index2/coherency_line_size', 0o644, b'64\n')
+f('sys/devices/system/cpu/cpu0/cache/index2/number_of_sets', 0o644, b'4096\n')
+f('sys/devices/system/cpu/cpu0/cache/index2/size', 0o644, b'4096K\n')
+f('sys/devices/system/cpu/cpu0/cache/index2/physical_line_partition', 0o644, b'1\n')
+f('sys/devices/system/cpu/cpu0/cache/index2/shared_cpu_map', 0o644, b'03\n')
+f('sys/devices/system/cpu/cpu0/cache/index2/level', 0o644, b'2\n')
+f('sys/devices/system/cpu/cpu0/cache/index2/shared_cpu_list', 0o644, b'0-1\n')
+d('sys/devices/system/cpu/cpu0/cache/index1', 0o755)
+f('sys/devices/system/cpu/cpu0/cache/index1/ways_of_associativity', 0o644, b'8\n')
+f('sys/devices/system/cpu/cpu0/cache/index1/type', 0o644, b'Instruction\n')
+f('sys/devices/system/cpu/cpu0/cache/index1/coherency_line_size', 0o644, b'64\n')
+f('sys/devices/system/cpu/cpu0/cache/index1/number_of_sets', 0o644, b'64\n')
+f('sys/devices/system/cpu/cpu0/cache/index1/size', 0o644, b'32K\n')
+f('sys/devices/system/cpu/cpu0/cache/index1/physical_line_partition', 0o644, b'1\n')
+f('sys/devices/system/cpu/cpu0/cache/index1/shared_cpu_map', 0o644, b'01\n')
+f('sys/devices/system/cpu/cpu0/cache/index1/level', 0o644, b'1\n')
+f('sys/devices/system/cpu/cpu0/cache/index1/shared_cpu_list', 0o644, b'0\n')
+d('sys/devices/system/cpu/cpu0/cpuidle', 0o755)
+d('sys/devices/system/cpu/cpu0/cpuidle/state2', 0o755)
+f('sys/devices/system/cpu/cpu0/cpuidle/state2/desc', 0o644, b'ACPI FFH INTEL MWAIT 0x10\n')
+f('sys/devices/system/cpu/cpu0/cpuidle/state2/power', 0o644, b'500\n')
+f('sys/devices/system/cpu/cpu0/cpuidle/state2/latency', 0o644, b'1\n')
+f('sys/devices/system/cpu/cpu0/cpuidle/state2/usage', 0o644, b'689\n')
+f('sys/devices/system/cpu/cpu0/cpuidle/state2/name', 0o644, b'C2\n')
+f('sys/devices/system/cpu/cpu0/cpuidle/state2/time', 0o644, b'209561\n')
+d('sys/devices/system/cpu/cpu0/cpuidle/state3', 0o755)
+f('sys/devices/system/cpu/cpu0/cpuidle/state3/desc', 0o644, b'ACPI FFH INTEL MWAIT 0x30\n')
+f('sys/devices/system/cpu/cpu0/cpuidle/state3/power', 0o644, b'100\n')
+f('sys/devices/system/cpu/cpu0/cpuidle/state3/latency', 0o644, b'57\n')
+f('sys/devices/system/cpu/cpu0/cpuidle/state3/usage', 0o644, b'11774\n')
+f('sys/devices/system/cpu/cpu0/cpuidle/state3/name', 0o644, b'C3\n')
+f('sys/devices/system/cpu/cpu0/cpuidle/state3/time', 0o644, b'116651688\n')
+d('sys/devices/system/cpu/cpu0/cpuidle/state1', 0o755)
+f('sys/devices/system/cpu/cpu0/cpuidle/state1/desc', 0o644, b'ACPI FFH INTEL MWAIT 0x0\n')
+f('sys/devices/system/cpu/cpu0/cpuidle/state1/power', 0o644, b'1000\n')
+f('sys/devices/system/cpu/cpu0/cpuidle/state1/latency', 0o644, b'1\n')
+f('sys/devices/system/cpu/cpu0/cpuidle/state1/usage', 0o644, b'2\n')
+f('sys/devices/system/cpu/cpu0/cpuidle/state1/name', 0o644, b'C1\n')
+f('sys/devices/system/cpu/cpu0/cpuidle/state1/time', 0o644, b'1044\n')
+d('sys/devices/system/cpu/cpu0/cpuidle/state0', 0o755)
+f('sys/devices/system/cpu/cpu0/cpuidle/state0/desc', 0o644, b'<null>\n')
+f('sys/devices/system/cpu/cpu0/cpuidle/state0/power', 0o644, b'4294967295\n')
+f('sys/devices/system/cpu/cpu0/cpuidle/state0/latency', 0o644, b'0\n')
+f('sys/devices/system/cpu/cpu0/cpuidle/state0/usage', 0o644, b'0\n')
+f('sys/devices/system/cpu/cpu0/cpuidle/state0/name', 0o644, b'<null>\n')
+f('sys/devices/system/cpu/cpu0/cpuidle/state0/time', 0o644, b'0\n')
+d('sys/devices/system/cpu/cpu0/cpufreq', 0o755)
+f('sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq', 0o644, b'1000000\n')
+f('sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq', 0o644, b'2333000\n')
+f('sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies', 0o644, b'2333000 2000000 1667000 1333000 1000000 \n')
+f('sys/devices/system/cpu/cpu0/cpufreq/scaling_governor', 0o644, b'ondemand\n')
+f('sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors', 0o644, b'ondemand performance \n')
+f('sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq', 0o644, b'1000000\n')
+f('sys/devices/system/cpu/cpu0/cpufreq/affected_cpus', 0o644, b'0 1\n')
+f('sys/devices/system/cpu/cpu0/cpufreq/related_cpus', 0o644, b'0 1\n')
+f('sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed', 0o644, b'<unsupported>\n')
+f('sys/devices/system/cpu/cpu0/cpufreq/scaling_driver', 0o644, b'acpi-cpufreq\n')
+f('sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq', 0o644, b'1000000\n')
+f('sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq', 0o644, b'1000000\n')
+f('sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq', 0o644, b'1000000\n')
+d('sys/devices/system/cpu/cpu0/cpufreq/stats', 0o755)
+f('sys/devices/system/cpu/cpu0/cpufreq/stats/total_trans', 0o644, b'12627\n')
+f('sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state', 0o644, b'''2333000 92206
+2000000 442
+1667000 1009
+1333000 1713
+1000000 740740
+''')
+d('sys/devices/system/cpu/cpu0/cpufreq/ondemand', 0o755)
+f('sys/devices/system/cpu/cpu0/cpufreq/ondemand/powersave_bias', 0o644, b'0\n')
+f('sys/devices/system/cpu/cpu0/cpufreq/ondemand/sampling_rate_max', 0o644, b'10000000\n')
+f('sys/devices/system/cpu/cpu0/cpufreq/ondemand/sampling_rate', 0o644, b'20000\n')
+f('sys/devices/system/cpu/cpu0/cpufreq/ondemand/up_threshold', 0o644, b'90\n')
+f('sys/devices/system/cpu/cpu0/cpufreq/ondemand/ignore_nice_load', 0o644, b'1\n')
+f('sys/devices/system/cpu/cpu0/cpufreq/ondemand/sampling_rate_min', 0o644, b'10000\n')
+d('sys/devices/system/cpu/cpu0/microcode', 0o755)
+f('sys/devices/system/cpu/cpu0/microcode/version', 0o644, b'0xc7\n')
+f('sys/devices/system/cpu/cpu0/microcode/processor_flags', 0o644, b'0x20\n')
+d('sys/devices/system/cpu/cpuidle', 0o755)
+f('sys/devices/system/cpu/cpuidle/current_driver', 0o644, b'acpi_idle\n')
+f('sys/devices/system/cpu/cpuidle/current_governor_ro', 0o644, b'menu\n')
+d('sys/devices/system/cpu/cpu1', 0o755)
+l('sys/devices/system/cpu/cpu1/cpufreq', '../cpu0/cpufreq')
+f('sys/devices/system/cpu/cpu1/crash_notes', 0o644, b'7fb20b68\n')
+f('sys/devices/system/cpu/cpu1/online', 0o644, b'1\n')
+d('sys/devices/system/cpu/cpu1/topology', 0o755)
+f('sys/devices/system/cpu/cpu1/topology/thread_siblings', 0o644, b'02\n')
+f('sys/devices/system/cpu/cpu1/topology/thread_siblings_list', 0o644, b'1\n')
+f('sys/devices/system/cpu/cpu1/topology/core_siblings_list', 0o644, b'0-1\n')
+f('sys/devices/system/cpu/cpu1/topology/core_siblings', 0o644, b'03\n')
+f('sys/devices/system/cpu/cpu1/topology/core_id', 0o644, b'1\n')
+f('sys/devices/system/cpu/cpu1/topology/physical_package_id', 0o644, b'0\n')
+d('sys/devices/system/cpu/cpu1/thermal_throttle', 0o755)
+f('sys/devices/system/cpu/cpu1/thermal_throttle/count', 0o644, b'0\n')
+d('sys/devices/system/cpu/cpu1/cache', 0o755)
+d('sys/devices/system/cpu/cpu1/cache/index0', 0o755)
+f('sys/devices/system/cpu/cpu1/cache/index0/ways_of_associativity', 0o644, b'8\n')
+f('sys/devices/system/cpu/cpu1/cache/index0/type', 0o644, b'Data\n')
+f('sys/devices/system/cpu/cpu1/cache/index0/coherency_line_size', 0o644, b'64\n')
+f('sys/devices/system/cpu/cpu1/cache/index0/number_of_sets', 0o644, b'64\n')
+f('sys/devices/system/cpu/cpu1/cache/index0/size', 0o644, b'32K\n')
+f('sys/devices/system/cpu/cpu1/cache/index0/physical_line_partition', 0o644, b'1\n')
+f('sys/devices/system/cpu/cpu1/cache/index0/shared_cpu_map', 0o644, b'02\n')
+f('sys/devices/system/cpu/cpu1/cache/index0/level', 0o644, b'1\n')
+f('sys/devices/system/cpu/cpu1/cache/index0/shared_cpu_list', 0o644, b'1\n')
+d('sys/devices/system/cpu/cpu1/cache/index2', 0o755)
+f('sys/devices/system/cpu/cpu1/cache/index2/ways_of_associativity', 0o644, b'16\n')
+f('sys/devices/system/cpu/cpu1/cache/index2/type', 0o644, b'Unified\n')
+f('sys/devices/system/cpu/cpu1/cache/index2/coherency_line_size', 0o644, b'64\n')
+f('sys/devices/system/cpu/cpu1/cache/index2/number_of_sets', 0o644, b'4096\n')
+f('sys/devices/system/cpu/cpu1/cache/index2/size', 0o644, b'4096K\n')
+f('sys/devices/system/cpu/cpu1/cache/index2/physical_line_partition', 0o644, b'1\n')
+f('sys/devices/system/cpu/cpu1/cache/index2/shared_cpu_map', 0o644, b'03\n')
+f('sys/devices/system/cpu/cpu1/cache/index2/level', 0o644, b'2\n')
+f('sys/devices/system/cpu/cpu1/cache/index2/shared_cpu_list', 0o644, b'0-1\n')
+d('sys/devices/system/cpu/cpu1/cache/index1', 0o755)
+f('sys/devices/system/cpu/cpu1/cache/index1/ways_of_associativity', 0o644, b'8\n')
+f('sys/devices/system/cpu/cpu1/cache/index1/type', 0o644, b'Instruction\n')
+f('sys/devices/system/cpu/cpu1/cache/index1/coherency_line_size', 0o644, b'64\n')
+f('sys/devices/system/cpu/cpu1/cache/index1/number_of_sets', 0o644, b'64\n')
+f('sys/devices/system/cpu/cpu1/cache/index1/size', 0o644, b'32K\n')
+f('sys/devices/system/cpu/cpu1/cache/index1/physical_line_partition', 0o644, b'1\n')
+f('sys/devices/system/cpu/cpu1/cache/index1/shared_cpu_map', 0o644, b'02\n')
+f('sys/devices/system/cpu/cpu1/cache/index1/level', 0o644, b'1\n')
+f('sys/devices/system/cpu/cpu1/cache/index1/shared_cpu_list', 0o644, b'1\n')
+d('sys/devices/system/cpu/cpu1/cpuidle', 0o755)
+d('sys/devices/system/cpu/cpu1/cpuidle/state2', 0o755)
+f('sys/devices/system/cpu/cpu1/cpuidle/state2/desc', 0o644, b'ACPI FFH INTEL MWAIT 0x10\n')
+f('sys/devices/system/cpu/cpu1/cpuidle/state2/power', 0o644, b'500\n')
+f('sys/devices/system/cpu/cpu1/cpuidle/state2/latency', 0o644, b'1\n')
+f('sys/devices/system/cpu/cpu1/cpuidle/state2/usage', 0o644, b'271\n')
+f('sys/devices/system/cpu/cpu1/cpuidle/state2/name', 0o644, b'C2\n')
+f('sys/devices/system/cpu/cpu1/cpuidle/state2/time', 0o644, b'47233\n')
+d('sys/devices/system/cpu/cpu1/cpuidle/state3', 0o755)
+f('sys/devices/system/cpu/cpu1/cpuidle/state3/desc', 0o644, b'ACPI FFH INTEL MWAIT 0x30\n')
+f('sys/devices/system/cpu/cpu1/cpuidle/state3/power', 0o644, b'100\n')
+f('sys/devices/system/cpu/cpu1/cpuidle/state3/latency', 0o644, b'57\n')
+f('sys/devices/system/cpu/cpu1/cpuidle/state3/usage', 0o644, b'10601\n')
+f('sys/devices/system/cpu/cpu1/cpuidle/state3/name', 0o644, b'C3\n')
+f('sys/devices/system/cpu/cpu1/cpuidle/state3/time', 0o644, b'117038054\n')
+d('sys/devices/system/cpu/cpu1/cpuidle/state1', 0o755)
+f('sys/devices/system/cpu/cpu1/cpuidle/state1/desc', 0o644, b'ACPI FFH INTEL MWAIT 0x0\n')
+f('sys/devices/system/cpu/cpu1/cpuidle/state1/power', 0o644, b'1000\n')
+f('sys/devices/system/cpu/cpu1/cpuidle/state1/latency', 0o644, b'1\n')
+f('sys/devices/system/cpu/cpu1/cpuidle/state1/usage', 0o644, b'1\n')
+f('sys/devices/system/cpu/cpu1/cpuidle/state1/name', 0o644, b'C1\n')
+f('sys/devices/system/cpu/cpu1/cpuidle/state1/time', 0o644, b'8\n')
+d('sys/devices/system/cpu/cpu1/cpuidle/state0', 0o755)
+f('sys/devices/system/cpu/cpu1/cpuidle/state0/desc', 0o644, b'<null>\n')
+f('sys/devices/system/cpu/cpu1/cpuidle/state0/power', 0o644, b'4294967295\n')
+f('sys/devices/system/cpu/cpu1/cpuidle/state0/latency', 0o644, b'0\n')
+f('sys/devices/system/cpu/cpu1/cpuidle/state0/usage', 0o644, b'0\n')
+f('sys/devices/system/cpu/cpu1/cpuidle/state0/name', 0o644, b'<null>\n')
+f('sys/devices/system/cpu/cpu1/cpuidle/state0/time', 0o644, b'0\n')
+d('sys/devices/system/cpu/cpu1/microcode', 0o755)
+f('sys/devices/system/cpu/cpu1/microcode/version', 0o644, b'0xc7\n')
+f('sys/devices/system/cpu/cpu1/microcode/processor_flags', 0o644, b'0x20\n')
+d('sys/devices/pnp0', 0o755)
+f('sys/devices/pnp0/uevent', 0o644, b'')
+d('sys/devices/pnp0/00:04', 0o755)
+l('sys/devices/pnp0/00:04/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0200:00')
+l('sys/devices/pnp0/00:04/subsystem', '../../../bus/pnp')
+f('sys/devices/pnp0/00:04/options', 0o644, b'')
+f('sys/devices/pnp0/00:04/id', 0o644, b'PNP0200\n')
+f('sys/devices/pnp0/00:04/resources', 0o644, b'''state = active
+io 0x0-0xf
+io 0x80-0x8f
+io 0xc0-0xdf
+dma 4
+''')
+f('sys/devices/pnp0/00:04/uevent', 0o644, b'')
+d('sys/devices/pnp0/00:04/power', 0o755)
+f('sys/devices/pnp0/00:04/power/wakeup', 0o644, b'\n')
+d('sys/devices/pnp0/00:0a', 0o755)
+l('sys/devices/pnp0/00:0a/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:01/ATM1200:00')
+l('sys/devices/pnp0/00:0a/subsystem', '../../../bus/pnp')
+f('sys/devices/pnp0/00:0a/options', 0o644, b'')
+f('sys/devices/pnp0/00:0a/id', 0o644, b'''ATM1200
+PNP0c31
+''')
+f('sys/devices/pnp0/00:0a/resources', 0o644, b'''state = active
+mem 0xfed40000-0xfed40fff
+''')
+f('sys/devices/pnp0/00:0a/uevent', 0o644, b'')
+d('sys/devices/pnp0/00:0a/power', 0o755)
+f('sys/devices/pnp0/00:0a/power/wakeup', 0o644, b'\n')
+d('sys/devices/pnp0/00:03', 0o755)
+l('sys/devices/pnp0/00:03/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0103:00')
+l('sys/devices/pnp0/00:03/subsystem', '../../../bus/pnp')
+f('sys/devices/pnp0/00:03/options', 0o644, b'')
+f('sys/devices/pnp0/00:03/id', 0o644, b'PNP0103\n')
+f('sys/devices/pnp0/00:03/resources', 0o644, b'''state = active
+mem 0xfed00000-0xfed003ff
+''')
+f('sys/devices/pnp0/00:03/uevent', 0o644, b'')
+d('sys/devices/pnp0/00:03/power', 0o755)
+f('sys/devices/pnp0/00:03/power/wakeup', 0o644, b'\n')
+d('sys/devices/pnp0/00:02', 0o755)
+l('sys/devices/pnp0/00:02/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C02:00')
+l('sys/devices/pnp0/00:02/subsystem', '../../../bus/pnp')
+l('sys/devices/pnp0/00:02/driver', '../../../bus/pnp/drivers/system')
+f('sys/devices/pnp0/00:02/options', 0o644, b'')
+f('sys/devices/pnp0/00:02/id', 0o644, b'PNP0c02\n')
+f('sys/devices/pnp0/00:02/resources', 0o644, b'''state = active
+io 0x10-0x1f
+io 0x90-0x9f
+io 0x24-0x25
+io 0x28-0x29
+io 0x2c-0x2d
+io 0x30-0x31
+io 0x34-0x35
+io 0x38-0x39
+io 0x3c-0x3d
+io 0xa4-0xa5
+io 0xa8-0xa9
+io 0xac-0xad
+io 0xb0-0xb5
+io 0xb8-0xb9
+io 0xbc-0xbd
+io 0x50-0x53
+io 0x72-0x77
+io 0x164e-0x164f
+io 0x2e-0x2f
+io 0x1000-0x107f
+io 0x1180-0x11bf
+io 0x800-0x80f
+io 0x15e0-0x15ef
+io 0x1600-0x165f
+mem 0xf0000000-0xf3ffffff
+mem 0xfed1c000-0xfed1ffff
+mem 0xfed14000-0xfed17fff
+mem 0xfed18000-0xfed18fff
+mem 0xfed19000-0xfed19fff
+''')
+f('sys/devices/pnp0/00:02/uevent', 0o644, b'DRIVER=system\n')
+d('sys/devices/pnp0/00:02/power', 0o755)
+f('sys/devices/pnp0/00:02/power/wakeup', 0o644, b'\n')
+d('sys/devices/pnp0/00:00', 0o755)
+l('sys/devices/pnp0/00:00/firmware_node', '../../LNXSYSTM:00/device:00/PNP0C01:00')
+l('sys/devices/pnp0/00:00/subsystem', '../../../bus/pnp')
+l('sys/devices/pnp0/00:00/driver', '../../../bus/pnp/drivers/system')
+f('sys/devices/pnp0/00:00/options', 0o644, b'')
+f('sys/devices/pnp0/00:00/id', 0o644, b'PNP0c01\n')
+f('sys/devices/pnp0/00:00/resources', 0o644, b'''state = active
+mem 0x0-0x9ffff
+mem 0xc0000-0xc3fff
+mem 0xc4000-0xc7fff
+mem 0xc8000-0xcbfff
+mem 0xcc000-0xcffff
+mem disabled
+mem disabled
+mem disabled
+mem 0xdc000-0xdffff
+mem 0xe0000-0xe3fff
+mem 0xe4000-0xe7fff
+mem 0xe8000-0xebfff
+mem 0xec000-0xeffff
+mem 0xf0000-0xfffff
+mem 0x100000-0x7fffffff
+mem 0xfec00000-0xfed3ffff
+mem 0xfed41000-0xffffffff
+''')
+f('sys/devices/pnp0/00:00/uevent', 0o644, b'DRIVER=system\n')
+d('sys/devices/pnp0/00:00/power', 0o755)
+f('sys/devices/pnp0/00:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/pnp0/power', 0o755)
+f('sys/devices/pnp0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pnp0/00:09', 0o755)
+l('sys/devices/pnp0/00:09/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:01/IBM0057:00')
+l('sys/devices/pnp0/00:09/subsystem', '../../../bus/pnp')
+l('sys/devices/pnp0/00:09/driver', '../../../bus/pnp/drivers/i8042 aux')
+f('sys/devices/pnp0/00:09/options', 0o644, b'')
+f('sys/devices/pnp0/00:09/id', 0o644, b'''IBM0057
+PNP0f13
+''')
+f('sys/devices/pnp0/00:09/resources', 0o644, b'''state = active
+irq 12
+''')
+f('sys/devices/pnp0/00:09/uevent', 0o644, b'DRIVER=i8042 aux\n')
+d('sys/devices/pnp0/00:09/power', 0o755)
+f('sys/devices/pnp0/00:09/power/wakeup', 0o644, b'\n')
+d('sys/devices/pnp0/00:07', 0o755)
+l('sys/devices/pnp0/00:07/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0B00:00')
+l('sys/devices/pnp0/00:07/subsystem', '../../../bus/pnp')
+l('sys/devices/pnp0/00:07/driver', '../../../bus/pnp/drivers/rtc_cmos')
+f('sys/devices/pnp0/00:07/options', 0o644, b'')
+f('sys/devices/pnp0/00:07/id', 0o644, b'PNP0b00\n')
+f('sys/devices/pnp0/00:07/nvram', 0o644, b'\x00\x00\x00\x00\x00\x00\x03\x80\x02\x00\xfc\x01\x00\x03\x00\x9f\x16\x00\x00\x02\x00\x00\x00\x01\x05\x00\x00\x11\x11\x01\x00\x00\x02e\x00\xfc \x8c\xc1\x01\x00|\x00\x00\x00\x00\x00\x00\x00\x00\x08D\xb0\x11\x00c\x11T/\x06\xd00\x80\x00\x00\x00\x00\x00\xc0\x05R\xfc\x01\x1d\x00[\x0f\x02\x03\x00\x00\x04\x04\x00\xdf8\xd3\xa0\x13r\xf2\x06\x13\xf9\xa7\xf1\x0e\x00\xc5\xfe\x00\x00\xf1\xff\xff\xff\xff\x00\x00\x00IS\xb2\x00')
+f('sys/devices/pnp0/00:07/resources', 0o644, b'''state = active
+io 0x70-0x71
+irq 8
+''')
+f('sys/devices/pnp0/00:07/uevent', 0o644, b'DRIVER=rtc_cmos\n')
+d('sys/devices/pnp0/00:07/rtc', 0o755)
+d('sys/devices/pnp0/00:07/rtc/rtc0', 0o755)
+l('sys/devices/pnp0/00:07/rtc/rtc0/subsystem', '../../../../../class/rtc')
+l('sys/devices/pnp0/00:07/rtc/rtc0/device', '../../../00:07')
+f('sys/devices/pnp0/00:07/rtc/rtc0/date', 0o644, b'2008-09-29\n')
+f('sys/devices/pnp0/00:07/rtc/rtc0/dev', 0o644, b'253:0\n')
+f('sys/devices/pnp0/00:07/rtc/rtc0/max_user_freq', 0o644, b'64\n')
+f('sys/devices/pnp0/00:07/rtc/rtc0/wakealarm', 0o644, b'')
+f('sys/devices/pnp0/00:07/rtc/rtc0/since_epoch', 0o644, b'1222655451\n')
+f('sys/devices/pnp0/00:07/rtc/rtc0/name', 0o644, b'rtc_cmos\n')
+f('sys/devices/pnp0/00:07/rtc/rtc0/time', 0o644, b'02:30:51\n')
+f('sys/devices/pnp0/00:07/rtc/rtc0/uevent', 0o644, b'''MAJOR=253
+MINOR=0
+''')
+d('sys/devices/pnp0/00:07/rtc/rtc0/power', 0o755)
+f('sys/devices/pnp0/00:07/rtc/rtc0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pnp0/00:07/power', 0o755)
+f('sys/devices/pnp0/00:07/power/wakeup', 0o644, b'enabled\n')
+d('sys/devices/pnp0/00:06', 0o755)
+l('sys/devices/pnp0/00:06/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C04:00')
+l('sys/devices/pnp0/00:06/subsystem', '../../../bus/pnp')
+f('sys/devices/pnp0/00:06/options', 0o644, b'')
+f('sys/devices/pnp0/00:06/id', 0o644, b'PNP0c04\n')
+f('sys/devices/pnp0/00:06/resources', 0o644, b'''state = active
+io 0xf0-0xf0
+irq 13
+''')
+f('sys/devices/pnp0/00:06/uevent', 0o644, b'')
+d('sys/devices/pnp0/00:06/power', 0o755)
+f('sys/devices/pnp0/00:06/power/wakeup', 0o644, b'\n')
+d('sys/devices/pnp0/00:08', 0o755)
+l('sys/devices/pnp0/00:08/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0303:00')
+l('sys/devices/pnp0/00:08/subsystem', '../../../bus/pnp')
+l('sys/devices/pnp0/00:08/driver', '../../../bus/pnp/drivers/i8042 kbd')
+f('sys/devices/pnp0/00:08/options', 0o644, b'')
+f('sys/devices/pnp0/00:08/id', 0o644, b'PNP0303\n')
+f('sys/devices/pnp0/00:08/resources', 0o644, b'''state = active
+io 0x60-0x60
+io 0x64-0x64
+irq 1
+''')
+f('sys/devices/pnp0/00:08/uevent', 0o644, b'DRIVER=i8042 kbd\n')
+d('sys/devices/pnp0/00:08/power', 0o755)
+f('sys/devices/pnp0/00:08/power/wakeup', 0o644, b'\n')
+d('sys/devices/pnp0/00:05', 0o755)
+l('sys/devices/pnp0/00:05/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0800:00')
+l('sys/devices/pnp0/00:05/subsystem', '../../../bus/pnp')
+f('sys/devices/pnp0/00:05/options', 0o644, b'')
+f('sys/devices/pnp0/00:05/id', 0o644, b'PNP0800\n')
+f('sys/devices/pnp0/00:05/resources', 0o644, b'''state = active
+io 0x61-0x61
+''')
+f('sys/devices/pnp0/00:05/uevent', 0o644, b'')
+d('sys/devices/pnp0/00:05/power', 0o755)
+f('sys/devices/pnp0/00:05/power/wakeup', 0o644, b'\n')
+d('sys/devices/pnp0/00:01', 0o755)
+l('sys/devices/pnp0/00:01/subsystem', '../../../bus/pnp')
+f('sys/devices/pnp0/00:01/options', 0o644, b'')
+f('sys/devices/pnp0/00:01/id', 0o644, b'''PNP0a08
+PNP0a03
+''')
+f('sys/devices/pnp0/00:01/resources', 0o644, b'''state = active
+io 0xcf8-0xcff
+''')
+f('sys/devices/pnp0/00:01/uevent', 0o644, b'')
+d('sys/devices/pnp0/00:01/power', 0o755)
+f('sys/devices/pnp0/00:01/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00', 0o755)
+l('sys/devices/pci0000:00/firmware_node', '../LNXSYSTM:00/device:00/PNP0A08:00')
+f('sys/devices/pci0000:00/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1d.3', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:20')
+l('sys/devices/pci0000:00/0000:00:1d.3/subsystem', '../../../bus/pci')
+l('sys/devices/pci0000:00/0000:00:1d.3/driver', '../../../bus/pci/drivers/uhci_hcd')
+f('sys/devices/pci0000:00/0000:00:1d.3/local_cpulist', 0o644, b'0-7\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/enable', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/modalias', 0o644, b'pci:v00008086d000027CBsv000017AAsd0000200Abc0Csc03i00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/resource', 0o644, b'''0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000001860 0x000000000000187f 0x0000000000020101
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/config', 0o644, b"\x86\x80\xcb'\x05\x00\x80\x02\x02\x00\x03\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x17\n \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x0f\x02\x00\x00\x00\x00\x00")
+f('sys/devices/pci0000:00/0000:00:1d.3/local_cpus', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/subsystem_device', 0o644, b'0x200a\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/vendor', 0o644, b'0x8086\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/irq', 0o644, b'19\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/pools', 0o644, b'''poolinfo - 0.1
+uhci_qh 13 32 128 1
+uhci_td 3 64 64 1
+buffer-2048 0 0 2048 0
+buffer-512 0 0 512 0
+buffer-128 0 0 128 0
+buffer-32 1 128 32 1
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/device', 0o644, b'0x27cb\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/class', 0o644, b'0x0c0300\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/msi_bus', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1d.3/subsystem_vendor', 0o644, b'0x17aa\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/uevent', 0o644, b'''DRIVER=uhci_hcd
+PCI_CLASS=C0300
+PCI_ID=8086:27CB
+PCI_SUBSYS_ID=17AA:200A
+PCI_SLOT_NAME=0000:00:1d.3
+MODALIAS=pci:v00008086d000027CBsv000017AAsd0000200Abc0Csc03i00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/resource4', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1d.3/broken_parity_status', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb_host', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.3/usb_host/usb_host4', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb_host/usb_host4/subsystem', '../../../../../class/usb_host')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb_host/usb_host4/device', '../../../0000:00:1d.3')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb_host/usb_host4/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb_host/usb_host4/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb_host/usb_host4/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/subsystem', '../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/driver', '../../../../bus/usb/drivers/usb')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/ep_00', 'usb_endpoint/usbdev4.1_ep00')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/version', 0o644, b' 1.10\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/authorized_default', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/maxchild', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/bDeviceClass', 0o644, b'09\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/bcdDevice', 0o644, b'0206\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/devnum', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/bDeviceProtocol', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/idProduct', 0o644, b'0001\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/product', 0o644, b'UHCI Host Controller\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/bDeviceSubClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/configuration', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/dev', 0o644, b'189:384\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/urbnum', 0o644, b'62\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/authorized', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/descriptors', 0o644, b'\x12\x01\x10\x01\t\x00\x00@k\x1d\x01\x00\x06\x02\x03\x02\x01\x01\t\x02\x19\x00\x01\x01\x00\xe0\x00\t\x04\x00\x00\x01\t\x00\x00\x00\x07\x05\x81\x03\x02\x00\xff')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/bNumConfigurations', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/serial', 0o644, b'0000:00:1d.3\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/speed', 0o644, b'12\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/bMaxPacketSize0', 0o644, b'64\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/bmAttributes', 0o644, b'e0\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/busnum', 0o644, b'4\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/quirks', 0o644, b'0x0\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/bConfigurationValue', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/uevent', 0o644, b'''MAJOR=189
+MINOR=384
+DEVTYPE=usb_device
+DRIVER=usb
+PRODUCT=1d6b/1/206
+TYPE=9/0/0
+BUSNUM=004
+DEVNUM=001
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/manufacturer', 0o644, b'Linux 2.6.27-rc7-00106-g6ef190c-dirty uhci_hcd\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/idVendor', 0o644, b'1d6b\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/bNumInterfaces', 0o644, b' 1\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/bMaxPower', 0o644, b' 0mA\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/usb_endpoint/usbdev4.1_ep00', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/usb_endpoint/usbdev4.1_ep00/subsystem', '../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/usb_endpoint/usbdev4.1_ep00/device', '../../../usb4')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/usb_endpoint/usbdev4.1_ep00/interval', 0o644, b'0ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/usb_endpoint/usbdev4.1_ep00/bEndpointAddress', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/usb_endpoint/usbdev4.1_ep00/type', 0o644, b'Control\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/usb_endpoint/usbdev4.1_ep00/dev', 0o644, b'252:7\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/usb_endpoint/usbdev4.1_ep00/direction', 0o644, b'both\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/usb_endpoint/usbdev4.1_ep00/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/usb_endpoint/usbdev4.1_ep00/wMaxPacketSize', 0o644, b'0040\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/usb_endpoint/usbdev4.1_ep00/bmAttributes', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/usb_endpoint/usbdev4.1_ep00/uevent', 0o644, b'''MAJOR=252
+MINOR=7
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/usb_endpoint/usbdev4.1_ep00/bInterval', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/usb_endpoint/usbdev4.1_ep00/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/usb_endpoint/usbdev4.1_ep00/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/subsystem', '../../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/driver', '../../../../../bus/usb/drivers/usb')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/ep_00', 'usb_endpoint/usbdev4.3_ep00')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/version', 0o644, b' 1.00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/maxchild', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/bDeviceClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/bcdDevice', 0o644, b'0001\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/devnum', 0o644, b'3\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/bDeviceProtocol', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/idProduct', 0o644, b'2016\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/product', 0o644, b'Biometric Coprocessor\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/bDeviceSubClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/configuration', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/dev', 0o644, b'189:386\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/urbnum', 0o644, b'9\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/authorized', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/descriptors', 0o644, b"\x12\x01\x00\x01\x00\x00\x00\x08\x83\x04\x16 \x01\x00\x01\x02\x00\x01\t\x02'\x00\x01\x01\x00\xa02\t\x04\x00\x00\x03\xff\x00\x00\x00\x07\x05\x81\x02@\x00\x00\x07\x05\x02\x02@\x00\x00\x07\x05\x83\x03\x04\x00\x14")
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/bNumConfigurations', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/speed', 0o644, b'12\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/bMaxPacketSize0', 0o644, b'8\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/bmAttributes', 0o644, b'a0\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/busnum', 0o644, b'4\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/quirks', 0o644, b'0x0\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/bConfigurationValue', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/uevent', 0o644, b'''MAJOR=189
+MINOR=386
+DEVTYPE=usb_device
+DRIVER=usb
+PRODUCT=483/2016/1
+TYPE=0/0/0
+BUSNUM=004
+DEVNUM=003
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/manufacturer', 0o644, b'STMicroelectronics\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/idVendor', 0o644, b'0483\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/bNumInterfaces', 0o644, b' 1\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/bMaxPower', 0o644, b'100mA\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/usb_endpoint/usbdev4.3_ep00', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/usb_endpoint/usbdev4.3_ep00/subsystem', '../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/usb_endpoint/usbdev4.3_ep00/device', '../../../4-2')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/usb_endpoint/usbdev4.3_ep00/interval', 0o644, b'0ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/usb_endpoint/usbdev4.3_ep00/bEndpointAddress', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/usb_endpoint/usbdev4.3_ep00/type', 0o644, b'Control\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/usb_endpoint/usbdev4.3_ep00/dev', 0o644, b'252:23\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/usb_endpoint/usbdev4.3_ep00/direction', 0o644, b'both\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/usb_endpoint/usbdev4.3_ep00/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/usb_endpoint/usbdev4.3_ep00/wMaxPacketSize', 0o644, b'0008\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/usb_endpoint/usbdev4.3_ep00/bmAttributes', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/usb_endpoint/usbdev4.3_ep00/uevent', 0o644, b'''MAJOR=252
+MINOR=23
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/usb_endpoint/usbdev4.3_ep00/bInterval', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/usb_endpoint/usbdev4.3_ep00/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/usb_endpoint/usbdev4.3_ep00/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/power/active_duration', 0o644, b'8370363\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/power/wakeup', 0o644, b'enabled\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/power/connected_duration', 0o644, b'8370362\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/power/autosuspend', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/power/persist', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/power/level', 0o644, b'on\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/subsystem', '../../../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/ep_83', 'usb_endpoint/usbdev4.3_ep83')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/ep_81', 'usb_endpoint/usbdev4.3_ep81')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/ep_02', 'usb_endpoint/usbdev4.3_ep02')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/modalias', 0o644, b'usb:v0483p2016d0001dc00dsc00dp00icFFisc00ip00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/bInterfaceNumber', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/bNumEndpoints', 0o644, b'03\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/bInterfaceSubClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/bInterfaceClass', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/uevent', 0o644, b'''DEVTYPE=usb_interface
+PRODUCT=483/2016/1
+TYPE=0/0/0
+INTERFACE=255/0/0
+MODALIAS=usb:v0483p2016d0001dc00dsc00dp00icFFisc00ip00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/bInterfaceProtocol', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep83', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep83/subsystem', '../../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep83/device', '../../../4-2:1.0')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep83/interval', 0o644, b'20ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep83/bEndpointAddress', 0o644, b'83\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep83/type', 0o644, b'Interrupt\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep83/dev', 0o644, b'252:22\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep83/direction', 0o644, b'in\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep83/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep83/wMaxPacketSize', 0o644, b'0004\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep83/bmAttributes', 0o644, b'03\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep83/uevent', 0o644, b'''MAJOR=252
+MINOR=22
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep83/bInterval', 0o644, b'14\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep83/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep83/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep81', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep81/subsystem', '../../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep81/device', '../../../4-2:1.0')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep81/interval', 0o644, b'0ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep81/bEndpointAddress', 0o644, b'81\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep81/type', 0o644, b'Bulk\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep81/dev', 0o644, b'252:20\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep81/direction', 0o644, b'in\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep81/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep81/wMaxPacketSize', 0o644, b'0040\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep81/bmAttributes', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep81/uevent', 0o644, b'''MAJOR=252
+MINOR=20
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep81/bInterval', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep81/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep81/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep02', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep02/subsystem', '../../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep02/device', '../../../4-2:1.0')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep02/interval', 0o644, b'0ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep02/bEndpointAddress', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep02/type', 0o644, b'Bulk\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep02/dev', 0o644, b'252:21\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep02/direction', 0o644, b'out\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep02/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep02/wMaxPacketSize', 0o644, b'0040\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep02/bmAttributes', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep02/uevent', 0o644, b'''MAJOR=252
+MINOR=21
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep02/bInterval', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep02/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/usb_endpoint/usbdev4.3_ep02/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-2/4-2:1.0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/subsystem', '../../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/ep_81', 'usb_endpoint/usbdev4.1_ep81')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/driver', '../../../../../bus/usb/drivers/hub')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/modalias', 0o644, b'usb:v1D6Bp0001d0206dc09dsc00dp00ic09isc00ip00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/bInterfaceNumber', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/bNumEndpoints', 0o644, b'01\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/bInterfaceSubClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/bInterfaceClass', 0o644, b'09\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/uevent', 0o644, b'''DEVTYPE=usb_interface
+DRIVER=hub
+PRODUCT=1d6b/1/206
+TYPE=9/0/0
+INTERFACE=9/0/0
+MODALIAS=usb:v1D6Bp0001d0206dc09dsc00dp00ic09isc00ip00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/bInterfaceProtocol', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/usb_endpoint/usbdev4.1_ep81', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/usb_endpoint/usbdev4.1_ep81/subsystem', '../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/usb_endpoint/usbdev4.1_ep81/device', '../../../4-0:1.0')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/usb_endpoint/usbdev4.1_ep81/interval', 0o644, b'255ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/usb_endpoint/usbdev4.1_ep81/bEndpointAddress', 0o644, b'81\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/usb_endpoint/usbdev4.1_ep81/type', 0o644, b'Interrupt\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/usb_endpoint/usbdev4.1_ep81/dev', 0o644, b'252:6\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/usb_endpoint/usbdev4.1_ep81/direction', 0o644, b'in\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/usb_endpoint/usbdev4.1_ep81/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/usb_endpoint/usbdev4.1_ep81/wMaxPacketSize', 0o644, b'0002\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/usb_endpoint/usbdev4.1_ep81/bmAttributes', 0o644, b'03\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/usb_endpoint/usbdev4.1_ep81/uevent', 0o644, b'''MAJOR=252
+MINOR=6
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/usb_endpoint/usbdev4.1_ep81/bInterval', 0o644, b'ff\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/usb_endpoint/usbdev4.1_ep81/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/usb_endpoint/usbdev4.1_ep81/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-0:1.0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/power/active_duration', 0o644, b'8372033\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/power/wakeup', 0o644, b'enabled\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/power/connected_duration', 0o644, b'8372033\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/power/autosuspend', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/power/level', 0o644, b'auto\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/subsystem', '../../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/driver', '../../../../../bus/usb/drivers/usb')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/ep_00', 'usb_endpoint/usbdev4.2_ep00')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/version', 0o644, b' 2.00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/maxchild', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/bDeviceClass', 0o644, b'e0\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/bcdDevice', 0o644, b'0100\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/devnum', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/bDeviceProtocol', 0o644, b'01\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/idProduct', 0o644, b'2110\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/product', 0o644, b'BCM2045B\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/bDeviceSubClass', 0o644, b'01\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/configuration', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/dev', 0o644, b'189:385\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/urbnum', 0o644, b'12\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/authorized', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/descriptors', 0o644, b'\x12\x01\x00\x02\xe0\x01\x01@\\\n\x10!\x00\x01\x01\x02\x00\x01\t\x02\xd8\x00\x04\x01\x00\xe0\x00\t\x04\x00\x00\x03\xe0\x01\x01\x00\x07\x05\x81\x03\x10\x00\x01\x07\x05\x82\x02@\x00\x01\x07\x05\x02\x02@\x00\x01\t\x04\x01\x00\x02\xe0\x01\x01\x00\x07\x05\x83\x01\x00\x00\x01\x07\x05\x03\x01\x00\x00\x01\t\x04\x01\x01\x02\xe0\x01\x01\x00\x07\x05\x83\x01\t\x00\x01\x07\x05\x03\x01\t\x00\x01\t\x04\x01\x02\x02\xe0\x01\x01\x00\x07\x05\x83\x01\x11\x00\x01\x07\x05\x03\x01\x11\x00\x01\t\x04\x01\x03\x02\xe0\x01\x01\x00\x07\x05\x83\x01 \x00\x01\x07\x05\x03\x01 \x00\x01\t\x04\x01\x04\x02\xe0\x01\x01\x00\x07\x05\x83\x01@\x00\x01\x07\x05\x03\x01@\x00\x01\t\x04\x01\x05\x02\xe0\x01\x01\x00\x07\x05\x83\x01@\x00\x01\x07\x05\x03\x01@\x00\x01\t\x04\x02\x00\x02\xff\xff\xff\x00\x07\x05\x84\x02 \x00\x01\x07\x05\x04\x02 \x00\x01\t\x04\x03\x00\x00\xfe\x01\x00\x00\x07!\x07\x88\x13@\x00')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/bNumConfigurations', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/speed', 0o644, b'12\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/bMaxPacketSize0', 0o644, b'64\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/bmAttributes', 0o644, b'e0\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/busnum', 0o644, b'4\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/quirks', 0o644, b'0x0\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/bConfigurationValue', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/uevent', 0o644, b'''MAJOR=189
+MINOR=385
+DEVTYPE=usb_device
+DRIVER=usb
+PRODUCT=a5c/2110/100
+TYPE=224/1/1
+BUSNUM=004
+DEVNUM=002
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/manufacturer', 0o644, b'Broadcom Corp\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/idVendor', 0o644, b'0a5c\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/bNumInterfaces', 0o644, b' 4\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/bMaxPower', 0o644, b' 0mA\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.3', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.3/subsystem', '../../../../../../bus/usb')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.3/modalias', 0o644, b'usb:v0A5Cp2110d0100dcE0dsc01dp01icFEisc01ip00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.3/bInterfaceNumber', 0o644, b'03\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.3/bNumEndpoints', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.3/bInterfaceSubClass', 0o644, b'01\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.3/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.3/bInterfaceClass', 0o644, b'fe\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.3/uevent', 0o644, b'''DEVTYPE=usb_interface
+PRODUCT=a5c/2110/100
+TYPE=224/1/1
+INTERFACE=254/1/0
+MODALIAS=usb:v0A5Cp2110d0100dcE0dsc01dp01icFEisc01ip00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.3/bInterfaceProtocol', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.3/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.3/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/usb_endpoint/usbdev4.2_ep00', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/usb_endpoint/usbdev4.2_ep00/subsystem', '../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/usb_endpoint/usbdev4.2_ep00/device', '../../../4-1')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/usb_endpoint/usbdev4.2_ep00/interval', 0o644, b'0ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/usb_endpoint/usbdev4.2_ep00/bEndpointAddress', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/usb_endpoint/usbdev4.2_ep00/type', 0o644, b'Control\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/usb_endpoint/usbdev4.2_ep00/dev', 0o644, b'252:19\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/usb_endpoint/usbdev4.2_ep00/direction', 0o644, b'both\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/usb_endpoint/usbdev4.2_ep00/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/usb_endpoint/usbdev4.2_ep00/wMaxPacketSize', 0o644, b'0040\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/usb_endpoint/usbdev4.2_ep00/bmAttributes', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/usb_endpoint/usbdev4.2_ep00/uevent', 0o644, b'''MAJOR=252
+MINOR=19
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/usb_endpoint/usbdev4.2_ep00/bInterval', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/usb_endpoint/usbdev4.2_ep00/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/usb_endpoint/usbdev4.2_ep00/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/subsystem', '../../../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/ep_81', 'usb_endpoint/usbdev4.2_ep81')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/ep_02', 'usb_endpoint/usbdev4.2_ep02')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/ep_82', 'usb_endpoint/usbdev4.2_ep82')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/modalias', 0o644, b'usb:v0A5Cp2110d0100dcE0dsc01dp01icE0isc01ip01\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/bInterfaceNumber', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/bNumEndpoints', 0o644, b'03\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/bInterfaceSubClass', 0o644, b'01\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/bInterfaceClass', 0o644, b'e0\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/uevent', 0o644, b'''DEVTYPE=usb_interface
+PRODUCT=a5c/2110/100
+TYPE=224/1/1
+INTERFACE=224/1/1
+MODALIAS=usb:v0A5Cp2110d0100dcE0dsc01dp01icE0isc01ip01
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/bInterfaceProtocol', 0o644, b'01\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep02', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep02/subsystem', '../../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep02/device', '../../../4-1:1.0')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep02/interval', 0o644, b'0ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep02/bEndpointAddress', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep02/type', 0o644, b'Bulk\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep02/dev', 0o644, b'252:14\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep02/direction', 0o644, b'out\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep02/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep02/wMaxPacketSize', 0o644, b'0040\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep02/bmAttributes', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep02/uevent', 0o644, b'''MAJOR=252
+MINOR=14
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep02/bInterval', 0o644, b'01\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep02/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep02/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep82', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep82/subsystem', '../../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep82/device', '../../../4-1:1.0')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep82/interval', 0o644, b'0ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep82/bEndpointAddress', 0o644, b'82\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep82/type', 0o644, b'Bulk\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep82/dev', 0o644, b'252:13\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep82/direction', 0o644, b'in\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep82/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep82/wMaxPacketSize', 0o644, b'0040\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep82/bmAttributes', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep82/uevent', 0o644, b'''MAJOR=252
+MINOR=13
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep82/bInterval', 0o644, b'01\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep82/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep82/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep81', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep81/subsystem', '../../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep81/device', '../../../4-1:1.0')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep81/interval', 0o644, b'1ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep81/bEndpointAddress', 0o644, b'81\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep81/type', 0o644, b'Interrupt\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep81/dev', 0o644, b'252:12\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep81/direction', 0o644, b'in\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep81/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep81/wMaxPacketSize', 0o644, b'0010\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep81/bmAttributes', 0o644, b'03\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep81/uevent', 0o644, b'''MAJOR=252
+MINOR=12
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep81/bInterval', 0o644, b'01\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep81/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/usb_endpoint/usbdev4.2_ep81/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/power/active_duration', 0o644, b'8370651\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/power/wakeup', 0o644, b'enabled\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/power/connected_duration', 0o644, b'8370650\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/power/autosuspend', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/power/persist', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/power/level', 0o644, b'on\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/subsystem', '../../../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/ep_84', 'usb_endpoint/usbdev4.2_ep84')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/ep_04', 'usb_endpoint/usbdev4.2_ep04')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/modalias', 0o644, b'usb:v0A5Cp2110d0100dcE0dsc01dp01icFFiscFFipFF\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/bInterfaceNumber', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/bNumEndpoints', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/bInterfaceSubClass', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/bInterfaceClass', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/uevent', 0o644, b'''DEVTYPE=usb_interface
+PRODUCT=a5c/2110/100
+TYPE=224/1/1
+INTERFACE=255/255/255
+MODALIAS=usb:v0A5Cp2110d0100dcE0dsc01dp01icFFiscFFipFF
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/bInterfaceProtocol', 0o644, b'ff\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep04', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep04/subsystem', '../../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep04/device', '../../../4-1:1.2')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep04/interval', 0o644, b'0ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep04/bEndpointAddress', 0o644, b'04\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep04/type', 0o644, b'Bulk\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep04/dev', 0o644, b'252:18\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep04/direction', 0o644, b'out\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep04/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep04/wMaxPacketSize', 0o644, b'0020\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep04/bmAttributes', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep04/uevent', 0o644, b'''MAJOR=252
+MINOR=18
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep04/bInterval', 0o644, b'01\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep04/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep04/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep84', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep84/subsystem', '../../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep84/device', '../../../4-1:1.2')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep84/interval', 0o644, b'0ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep84/bEndpointAddress', 0o644, b'84\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep84/type', 0o644, b'Bulk\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep84/dev', 0o644, b'252:17\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep84/direction', 0o644, b'in\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep84/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep84/wMaxPacketSize', 0o644, b'0020\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep84/bmAttributes', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep84/uevent', 0o644, b'''MAJOR=252
+MINOR=17
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep84/bInterval', 0o644, b'01\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep84/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/usb_endpoint/usbdev4.2_ep84/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.2/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/subsystem', '../../../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/ep_83', 'usb_endpoint/usbdev4.2_ep83')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/ep_03', 'usb_endpoint/usbdev4.2_ep03')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/modalias', 0o644, b'usb:v0A5Cp2110d0100dcE0dsc01dp01icE0isc01ip01\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/bInterfaceNumber', 0o644, b'01\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/bNumEndpoints', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/bInterfaceSubClass', 0o644, b'01\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/bInterfaceClass', 0o644, b'e0\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/uevent', 0o644, b'''DEVTYPE=usb_interface
+PRODUCT=a5c/2110/100
+TYPE=224/1/1
+INTERFACE=224/1/1
+MODALIAS=usb:v0A5Cp2110d0100dcE0dsc01dp01icE0isc01ip01
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/bInterfaceProtocol', 0o644, b'01\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep03', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep03/subsystem', '../../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep03/device', '../../../4-1:1.1')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep03/interval', 0o644, b'1ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep03/bEndpointAddress', 0o644, b'03\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep03/type', 0o644, b'Isoc\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep03/dev', 0o644, b'252:16\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep03/direction', 0o644, b'out\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep03/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep03/wMaxPacketSize', 0o644, b'0000\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep03/bmAttributes', 0o644, b'01\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep03/uevent', 0o644, b'''MAJOR=252
+MINOR=16
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep03/bInterval', 0o644, b'01\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep03/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep03/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep83', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep83/subsystem', '../../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep83/device', '../../../4-1:1.1')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep83/interval', 0o644, b'1ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep83/bEndpointAddress', 0o644, b'83\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep83/type', 0o644, b'Isoc\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep83/dev', 0o644, b'252:15\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep83/direction', 0o644, b'in\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep83/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep83/wMaxPacketSize', 0o644, b'0000\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep83/bmAttributes', 0o644, b'01\n')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep83/uevent', 0o644, b'''MAJOR=252
+MINOR=15
+''')
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep83/bInterval', 0o644, b'01\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep83/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/usb_endpoint/usbdev4.2_ep83/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.3/usb4/4-1/4-1:1.1/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.2', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.2/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:0d')
+l('sys/devices/pci0000:00/0000:00:1c.2/subsystem', '../../../bus/pci')
+l('sys/devices/pci0000:00/0000:00:1c.2/driver', '../../../bus/pci/drivers/pcieport-driver')
+f('sys/devices/pci0000:00/0000:00:1c.2/local_cpulist', 0o644, b'0-7\n')
+f('sys/devices/pci0000:00/0000:00:1c.2/enable', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1c.2/modalias', 0o644, b'pci:v00008086d000027D4sv00000000sd00000000bc06sc04i00\n')
+f('sys/devices/pci0000:00/0000:00:1c.2/resource', 0o644, b'''0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000006000 0x0000000000007fff 0x0000000000000100
+0x00000000e8000000 0x00000000e9ffffff 0x0000000000000200
+0x00000000e4100000 0x00000000e41fffff 0x0000000000001201
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+''')
+f('sys/devices/pci0000:00/0000:00:1c.2/config', 0o644, b"\x86\x80\xd4'\x07\x05\x10\x00\x02\x00\x04\x06\x10\x00\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x0b\x00`p\x00\x00\x00\xe8\xf0\xe9\x11\xe4\x11\xe4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x0b\x03\x04\x00\x10\x80A\x01\xc0\x0f\x00\x00\x00\x00\x10\x00\x11L\x11\x03\x00\x00\x01\x10\xe0\xa0 \x00(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x90\x01\x00\x0c0\xe0\xfe\x89A\x00\x00\x00\x00\x00\x00\r\xa0\x00\x00\xaa\x17\x11 \x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\xc8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x11\xc0\x00\x00\x00\x00\x00\x00\xc7\x00\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x0f\x02\x00\x00\x00\x00\x00\x02\x00\x01\x18\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xff\x00\x00\x80\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x11\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x01\x00\x00\x01\x02\x03\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\x00\x00\x00\x00\x00\x01\xc0\xd1\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07`\x00`\x00\x00\x00\x00`\x02\x00\x00\x0c\x00\x06\x00\x00\x00\x00\x00[`\xc9\xc0\x00p&u\x00\x10\x00\x00\xff\x0f\x00\x00\x16\x00\x00\x14\xb5\xbcJ\xbc\x0b*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x10\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x02\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
+f('sys/devices/pci0000:00/0000:00:1c.2/local_cpus', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1c.2/subsystem_device', 0o644, b'0x0000\n')
+f('sys/devices/pci0000:00/0000:00:1c.2/vendor', 0o644, b'0x8086\n')
+f('sys/devices/pci0000:00/0000:00:1c.2/irq', 0o644, b'508\n')
+f('sys/devices/pci0000:00/0000:00:1c.2/device', 0o644, b'0x27d4\n')
+f('sys/devices/pci0000:00/0000:00:1c.2/class', 0o644, b'0x060400\n')
+f('sys/devices/pci0000:00/0000:00:1c.2/msi_bus', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1c.2/subsystem_vendor', 0o644, b'0x0000\n')
+f('sys/devices/pci0000:00/0000:00:1c.2/uevent', 0o644, b'''DRIVER=pcieport-driver
+PCI_CLASS=60400
+PCI_ID=8086:27D4
+PCI_SUBSYS_ID=0000:0000
+PCI_SLOT_NAME=0000:00:1c.2
+MODALIAS=pci:v00008086d000027D4sv00000000sd00000000bc06sc04i00
+''')
+f('sys/devices/pci0000:00/0000:00:1c.2/broken_parity_status', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1c.2/0000:00:1c.2:pcie02', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.2/0000:00:1c.2:pcie02/subsystem', '../../../../bus/pci_express')
+f('sys/devices/pci0000:00/0000:00:1c.2/0000:00:1c.2:pcie02/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1c.2/0000:00:1c.2:pcie02/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.2/0000:00:1c.2:pcie02/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.2/0000:00:1c.2:pcie00', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.2/0000:00:1c.2:pcie00/subsystem', '../../../../bus/pci_express')
+f('sys/devices/pci0000:00/0000:00:1c.2/0000:00:1c.2:pcie00/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1c.2/0000:00:1c.2:pcie00/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.2/0000:00:1c.2:pcie00/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.2/pci_bus', 0o755)
+d('sys/devices/pci0000:00/0000:00:1c.2/pci_bus/0000:04', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.2/pci_bus/0000:04/subsystem', '../../../../../class/pci_bus')
+l('sys/devices/pci0000:00/0000:00:1c.2/pci_bus/0000:04/device', '../../../0000:00:1c.2')
+f('sys/devices/pci0000:00/0000:00:1c.2/pci_bus/0000:04/cpuaffinity', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1c.2/pci_bus/0000:04/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1c.2/pci_bus/0000:04/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.2/pci_bus/0000:04/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.2/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.2/power/wakeup', 0o644, b'disabled\n')
+d('sys/devices/pci0000:00/0000:00:1c.2/0000:00:1c.2:pcie03', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.2/0000:00:1c.2:pcie03/subsystem', '../../../../bus/pci_express')
+f('sys/devices/pci0000:00/0000:00:1c.2/0000:00:1c.2:pcie03/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1c.2/0000:00:1c.2:pcie03/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.2/0000:00:1c.2:pcie03/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1b.0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1b.0/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:25')
+l('sys/devices/pci0000:00/0000:00:1b.0/subsystem', '../../../bus/pci')
+l('sys/devices/pci0000:00/0000:00:1b.0/driver', '../../../bus/pci/drivers/HDA Intel')
+f('sys/devices/pci0000:00/0000:00:1b.0/local_cpulist', 0o644, b'0-7\n')
+f('sys/devices/pci0000:00/0000:00:1b.0/enable', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1b.0/modalias', 0o644, b'pci:v00008086d000027D8sv000017AAsd00002010bc04sc03i00\n')
+f('sys/devices/pci0000:00/0000:00:1b.0/resource', 0o644, b'''0x00000000ee400000 0x00000000ee403fff 0x0000000000020204
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+''')
+f('sys/devices/pci0000:00/0000:00:1b.0/config', 0o644, b"\x86\x80\xd8'\x06\x01\x10\x00\x02\x00\x03\x04\x10\x00\x00\x00\x04\x00@\xee\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x17\x10 \x00\x00\x00\x00P\x00\x00\x00\x00\x00\x00\x00\x0b\x02\x00\x00\x03\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x01`B\xc8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05p\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x91\x00\x00\x00\x00\x00\x00\x08\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x0f\x02\x00\x00\x00\x00\x00\x02\x00\x01\x13\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x01\x00\x00\x01\x02\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\xc0\xd1\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
+f('sys/devices/pci0000:00/0000:00:1b.0/local_cpus', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1b.0/subsystem_device', 0o644, b'0x2010\n')
+f('sys/devices/pci0000:00/0000:00:1b.0/vendor', 0o644, b'0x8086\n')
+f('sys/devices/pci0000:00/0000:00:1b.0/irq', 0o644, b'17\n')
+f('sys/devices/pci0000:00/0000:00:1b.0/device', 0o644, b'0x27d8\n')
+f('sys/devices/pci0000:00/0000:00:1b.0/class', 0o644, b'0x040300\n')
+f('sys/devices/pci0000:00/0000:00:1b.0/msi_bus', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1b.0/resource0', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1b.0/subsystem_vendor', 0o644, b'0x17aa\n')
+f('sys/devices/pci0000:00/0000:00:1b.0/uevent', 0o644, b'''DRIVER=HDA Intel
+PCI_CLASS=40300
+PCI_ID=8086:27D8
+PCI_SUBSYS_ID=17AA:2010
+PCI_SLOT_NAME=0000:00:1b.0
+MODALIAS=pci:v00008086d000027D8sv000017AAsd00002010bc04sc03i00
+''')
+f('sys/devices/pci0000:00/0000:00:1b.0/broken_parity_status', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1b.0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1b.0/power/wakeup', 0o644, b'disabled\n')
+d('sys/devices/pci0000:00/0000:00:1b.0/sound', 0o755)
+d('sys/devices/pci0000:00/0000:00:1b.0/sound/card0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/subsystem', '../../../../../class/sound')
+l('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/device', '../../../0000:00:1b.0')
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/audio', 0o755)
+l('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/audio/subsystem', '../../../../../../class/sound')
+l('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/audio/device', '../../card0')
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/audio/dev', 0o644, b'14:4\n')
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/audio/uevent', 0o644, b'''MAJOR=14
+MINOR=4
+''')
+d('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/audio/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/audio/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/dsp', 0o755)
+l('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/dsp/subsystem', '../../../../../../class/sound')
+l('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/dsp/device', '../../card0')
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/dsp/dev', 0o644, b'14:3\n')
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/dsp/uevent', 0o644, b'''MAJOR=14
+MINOR=3
+''')
+d('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/dsp/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/dsp/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/mixer', 0o755)
+l('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/mixer/subsystem', '../../../../../../class/sound')
+l('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/mixer/device', '../../card0')
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/mixer/dev', 0o644, b'14:0\n')
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/mixer/uevent', 0o644, b'''MAJOR=14
+MINOR=0
+''')
+d('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/mixer/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/mixer/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D0p', 0o755)
+l('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D0p/subsystem', '../../../../../../class/sound')
+l('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D0p/device', '../../card0')
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D0p/pcm_class', 0o644, b'generic\n')
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D0p/dev', 0o644, b'116:16\n')
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D0p/uevent', 0o644, b'''MAJOR=116
+MINOR=16
+''')
+d('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D0p/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D0p/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/controlC0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/controlC0/subsystem', '../../../../../../class/sound')
+l('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/controlC0/device', '../../card0')
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/controlC0/dev', 0o644, b'116:0\n')
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/controlC0/uevent', 0o644, b'''MAJOR=116
+MINOR=0
+''')
+d('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/controlC0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/controlC0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D0c', 0o755)
+l('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D0c/subsystem', '../../../../../../class/sound')
+l('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D0c/device', '../../card0')
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D0c/pcm_class', 0o644, b'generic\n')
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D0c/dev', 0o644, b'116:24\n')
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D0c/uevent', 0o644, b'''MAJOR=116
+MINOR=24
+''')
+d('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D0c/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D0c/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/adsp', 0o755)
+l('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/adsp/subsystem', '../../../../../../class/sound')
+l('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/adsp/device', '../../card0')
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/adsp/dev', 0o644, b'14:12\n')
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/adsp/uevent', 0o644, b'''MAJOR=14
+MINOR=12
+''')
+d('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/adsp/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/adsp/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D1p', 0o755)
+l('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D1p/subsystem', '../../../../../../class/sound')
+l('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D1p/device', '../../card0')
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D1p/pcm_class', 0o644, b'generic\n')
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D1p/dev', 0o644, b'116:17\n')
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D1p/uevent', 0o644, b'''MAJOR=116
+MINOR=17
+''')
+d('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D1p/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D1p/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/pci_bus', 0o755)
+d('sys/devices/pci0000:00/pci_bus/0000:00', 0o755)
+l('sys/devices/pci0000:00/pci_bus/0000:00/subsystem', '../../../../class/pci_bus')
+l('sys/devices/pci0000:00/pci_bus/0000:00/device', '../../../pci0000:00')
+f('sys/devices/pci0000:00/pci_bus/0000:00/cpuaffinity', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/pci_bus/0000:00/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/pci_bus/0000:00/power', 0o755)
+f('sys/devices/pci0000:00/pci_bus/0000:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/power', 0o755)
+f('sys/devices/pci0000:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:21')
+l('sys/devices/pci0000:00/0000:00:1d.7/subsystem', '../../../bus/pci')
+l('sys/devices/pci0000:00/0000:00:1d.7/driver', '../../../bus/pci/drivers/ehci_hcd')
+f('sys/devices/pci0000:00/0000:00:1d.7/local_cpulist', 0o644, b'0-7\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/enable', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/modalias', 0o644, b'pci:v00008086d000027CCsv000017AAsd0000200Bbc0Csc03i20\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/resource', 0o644, b'''0x00000000ee404000 0x00000000ee4043ff 0x0000000000020200
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/config', 0o644, b"\x86\x80\xcc'\x06\x01\x90\x02\x02 \x03\x0c\x00\x00\x00\x00\x00@@\xee\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x17\x0b \x00\x00\x00\x00P\x00\x00\x00\x00\x00\x00\x00\x0b\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01X\xc2\xc9\x00\x80\x00\x00\n\x00\xa0 \x00\x00\x00\x00 \x9f\x01\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x08\x80\x00\x00\xd7?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\xff\x00\xff\x00\xff\x00 \x00\x00\x88\x00\x00\x00\x00\xdb\xb6m\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\t\x88\x85@\x00\x86\x0f\x02\x00\x06\x17\x02 ")
+f('sys/devices/pci0000:00/0000:00:1d.7/local_cpus', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/subsystem_device', 0o644, b'0x200b\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/vendor', 0o644, b'0x8086\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/irq', 0o644, b'19\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/pools', 0o644, b'''poolinfo - 0.1
+ehci_sitd 0 0 96 0
+ehci_itd 0 0 192 0
+ehci_qh 5 25 160 1
+ehci_qtd 5 42 96 1
+buffer-2048 16 32 2048 16
+buffer-512 0 0 512 0
+buffer-128 2 32 128 1
+buffer-32 2 128 32 1
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/device', 0o644, b'0x27cc\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/class', 0o644, b'0x0c0320\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/msi_bus', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1d.7/resource0', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1d.7/subsystem_vendor', 0o644, b'0x17aa\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/uevent', 0o644, b'''DRIVER=ehci_hcd
+PCI_CLASS=C0320
+PCI_ID=8086:27CC
+PCI_SUBSYS_ID=17AA:200B
+PCI_SLOT_NAME=0000:00:1d.7
+MODALIAS=pci:v00008086d000027CCsv000017AAsd0000200Bbc0Csc03i20
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/broken_parity_status', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/subsystem', '../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/driver', '../../../../bus/usb/drivers/usb')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/ep_00', 'usb_endpoint/usbdev5.1_ep00')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/version', 0o644, b' 2.00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/authorized_default', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/maxchild', 0o644, b'8\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/bDeviceClass', 0o644, b'09\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/bcdDevice', 0o644, b'0206\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/devnum', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/bDeviceProtocol', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/idProduct', 0o644, b'0002\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/product', 0o644, b'EHCI Host Controller\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/bDeviceSubClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/configuration', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/dev', 0o644, b'189:512\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/urbnum', 0o644, b'151\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/authorized', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/descriptors', 0o644, b'\x12\x01\x00\x02\t\x00\x00@k\x1d\x02\x00\x06\x02\x03\x02\x01\x01\t\x02\x19\x00\x01\x01\x00\xe0\x00\t\x04\x00\x00\x01\t\x00\x00\x00\x07\x05\x81\x03\x04\x00\x0c')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/bNumConfigurations', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/serial', 0o644, b'0000:00:1d.7\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/speed', 0o644, b'480\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/bMaxPacketSize0', 0o644, b'64\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/bmAttributes', 0o644, b'e0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/busnum', 0o644, b'5\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/quirks', 0o644, b'0x0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/bConfigurationValue', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/uevent', 0o644, b'''MAJOR=189
+MINOR=512
+DEVTYPE=usb_device
+DRIVER=usb
+PRODUCT=1d6b/2/206
+TYPE=9/0/0
+BUSNUM=005
+DEVNUM=001
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/manufacturer', 0o644, b'Linux 2.6.27-rc7-00106-g6ef190c-dirty ehci_hcd\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/idVendor', 0o644, b'1d6b\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/bNumInterfaces', 0o644, b' 1\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/bMaxPower', 0o644, b' 0mA\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/usb_endpoint/usbdev5.1_ep00', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/usb_endpoint/usbdev5.1_ep00/subsystem', '../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/usb_endpoint/usbdev5.1_ep00/device', '../../../usb5')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/usb_endpoint/usbdev5.1_ep00/interval', 0o644, b'0ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/usb_endpoint/usbdev5.1_ep00/bEndpointAddress', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/usb_endpoint/usbdev5.1_ep00/type', 0o644, b'Control\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/usb_endpoint/usbdev5.1_ep00/dev', 0o644, b'252:9\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/usb_endpoint/usbdev5.1_ep00/direction', 0o644, b'both\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/usb_endpoint/usbdev5.1_ep00/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/usb_endpoint/usbdev5.1_ep00/wMaxPacketSize', 0o644, b'0040\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/usb_endpoint/usbdev5.1_ep00/bmAttributes', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/usb_endpoint/usbdev5.1_ep00/uevent', 0o644, b'''MAJOR=252
+MINOR=9
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/usb_endpoint/usbdev5.1_ep00/bInterval', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/usb_endpoint/usbdev5.1_ep00/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/usb_endpoint/usbdev5.1_ep00/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/subsystem', '../../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/driver', '../../../../../bus/usb/drivers/usb')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/ep_00', 'usb_endpoint/usbdev5.7_ep00')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/version', 0o644, b' 2.00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/maxchild', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/bDeviceClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/bcdDevice', 0o644, b'0100\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/devnum', 0o644, b'7\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/bDeviceProtocol', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/idProduct', 0o644, b'8012\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/product', 0o644, b'Flash Disk\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/bDeviceSubClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/configuration', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/dev', 0o644, b'189:518\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/urbnum', 0o644, b'743\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/authorized', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/descriptors', 0o644, b'\x12\x01\x00\x02\x00\x00\x00@C\x10\x12\x80\x00\x01\x01\x02\x00\x01\t\x02 \x00\x01\x01\x00\x802\t\x04\x00\x00\x02\x08\x06P\x00\x07\x05\x81\x02\x00\x02\x00\x07\x05\x02\x02\x00\x02\x00')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/bNumConfigurations', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/speed', 0o644, b'480\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/bMaxPacketSize0', 0o644, b'64\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/bmAttributes', 0o644, b'80\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/busnum', 0o644, b'5\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/quirks', 0o644, b'0x0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/bConfigurationValue', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/uevent', 0o644, b'''MAJOR=189
+MINOR=518
+DEVTYPE=usb_device
+DRIVER=usb
+PRODUCT=1043/8012/100
+TYPE=0/0/0
+BUSNUM=005
+DEVNUM=007
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/manufacturer', 0o644, b'Generic\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/idVendor', 0o644, b'1043\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/bNumInterfaces', 0o644, b' 1\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/bMaxPower', 0o644, b'100mA\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/usb_endpoint/usbdev5.7_ep00', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/usb_endpoint/usbdev5.7_ep00/subsystem', '../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/usb_endpoint/usbdev5.7_ep00/device', '../../../5-1')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/usb_endpoint/usbdev5.7_ep00/interval', 0o644, b'0ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/usb_endpoint/usbdev5.7_ep00/bEndpointAddress', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/usb_endpoint/usbdev5.7_ep00/type', 0o644, b'Control\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/usb_endpoint/usbdev5.7_ep00/dev', 0o644, b'252:24\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/usb_endpoint/usbdev5.7_ep00/direction', 0o644, b'both\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/usb_endpoint/usbdev5.7_ep00/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/usb_endpoint/usbdev5.7_ep00/wMaxPacketSize', 0o644, b'0040\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/usb_endpoint/usbdev5.7_ep00/bmAttributes', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/usb_endpoint/usbdev5.7_ep00/uevent', 0o644, b'''MAJOR=252
+MINOR=24
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/usb_endpoint/usbdev5.7_ep00/bInterval', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/usb_endpoint/usbdev5.7_ep00/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/usb_endpoint/usbdev5.7_ep00/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/power/active_duration', 0o644, b'65113\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/power/wakeup', 0o644, b'\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/power/connected_duration', 0o644, b'65113\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/power/autosuspend', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/power/persist', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/power/level', 0o644, b'on\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/subsystem', '../../../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/ep_81', 'usb_endpoint/usbdev5.7_ep81')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/ep_02', 'usb_endpoint/usbdev5.7_ep02')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/driver', '../../../../../../bus/usb/drivers/usb-storage')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/modalias', 0o644, b'usb:v1043p8012d0100dc00dsc00dp00ic08isc06ip50\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/bInterfaceNumber', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/bNumEndpoints', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/bInterfaceSubClass', 0o644, b'06\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/bInterfaceClass', 0o644, b'08\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/uevent', 0o644, b'''DEVTYPE=usb_interface
+DRIVER=usb-storage
+PRODUCT=1043/8012/100
+TYPE=0/0/0
+INTERFACE=8/6/80
+MODALIAS=usb:v1043p8012d0100dc00dsc00dp00ic08isc06ip50
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/bInterfaceProtocol', 0o644, b'50\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep81', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep81/subsystem', '../../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep81/device', '../../../5-1:1.0')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep81/interval', 0o644, b'0ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep81/bEndpointAddress', 0o644, b'81\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep81/type', 0o644, b'Bulk\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep81/dev', 0o644, b'252:10\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep81/direction', 0o644, b'in\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep81/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep81/wMaxPacketSize', 0o644, b'0200\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep81/bmAttributes', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep81/uevent', 0o644, b'''MAJOR=252
+MINOR=10
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep81/bInterval', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep81/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep81/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep02', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep02/subsystem', '../../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep02/device', '../../../5-1:1.0')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep02/interval', 0o644, b'0ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep02/bEndpointAddress', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep02/type', 0o644, b'Bulk\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep02/dev', 0o644, b'252:11\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep02/direction', 0o644, b'out\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep02/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep02/wMaxPacketSize', 0o644, b'0200\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep02/bmAttributes', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep02/uevent', 0o644, b'''MAJOR=252
+MINOR=11
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep02/bInterval', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep02/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/usb_endpoint/usbdev5.7_ep02/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/subsystem', '../../../../../../../bus/scsi')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/uevent', 0o644, b'DEVTYPE=scsi_host\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/subsystem', '../../../../../../../../bus/scsi')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/uevent', 0o644, b'DEVTYPE=scsi_target\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/generic', 'scsi_generic/sg2')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/subsystem', '../../../../../../../../../bus/scsi')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/driver', '../../../../../../../../../bus/scsi/drivers/sd')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/iodone_cnt', 0o644, b'0xc3\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/device_blocked', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/max_sectors', 0o644, b'240\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/modalias', 0o644, b'scsi:t-0x00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_level', 0o644, b'3\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/queue_depth', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/rev', 0o644, b'1.00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/type', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/iocounterbits', 0o644, b'32\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/vendor', 0o644, b'Generic \n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/state', 0o644, b'running\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/queue_type', 0o644, b'none\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/iorequest_cnt', 0o644, b'0xc3\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/evt_media_change', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/model', 0o644, b'USB Flash Drive \n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/ioerr_cnt', 0o644, b'0x2\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/uevent', 0o644, b'''DEVTYPE=scsi_device
+DRIVER=sd
+MODALIAS=scsi:t-0x00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/timeout', 0o644, b'60\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_disk', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_disk/7:0:0:0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_disk/7:0:0:0/subsystem', '../../../../../../../../../../../class/scsi_disk')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_disk/7:0:0:0/device', '../../../7:0:0:0')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_disk/7:0:0:0/app_tag_own', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_disk/7:0:0:0/FUA', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_disk/7:0:0:0/cache_type', 0o644, b'write through\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_disk/7:0:0:0/protection_type', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_disk/7:0:0:0/manage_start_stop', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_disk/7:0:0:0/allow_restart', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_disk/7:0:0:0/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_disk/7:0:0:0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_disk/7:0:0:0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_generic', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_generic/sg2', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_generic/sg2/subsystem', '../../../../../../../../../../../class/scsi_generic')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_generic/sg2/device', '../../../7:0:0:0')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_generic/sg2/dev', 0o644, b'21:2\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_generic/sg2/uevent', 0o644, b'''MAJOR=21
+MINOR=2
+''')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_generic/sg2/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_generic/sg2/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/bsg', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/bsg/7:0:0:0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/bsg/7:0:0:0/subsystem', '../../../../../../../../../../../class/bsg')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/bsg/7:0:0:0/device', '../../../7:0:0:0')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/bsg/7:0:0:0/dev', 0o644, b'254:2\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/bsg/7:0:0:0/uevent', 0o644, b'''MAJOR=254
+MINOR=2
+''')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/bsg/7:0:0:0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/bsg/7:0:0:0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/subsystem', '../../../../../../../../../../../class/block')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/bdi', '../../../../../../../../../../virtual/bdi/8:16')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/device', '../../../7:0:0:0')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/capability', 0o644, b'13\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/ro', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/make-it-fail', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/size', 0o644, b'257024\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/dev', 0o644, b'8:16\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/range', 0o644, b'16\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/removable', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/stat', 0o644, b' 117 409 2103 272 0 0 0 0 0 194 272\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/uevent', 0o644, b'''MAJOR=8
+MINOR=16
+DEVTYPE=disk
+''')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/queue', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/queue/bsg', '../../../bsg/7:0:0:0')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/queue/nr_requests', 0o644, b'128\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/queue/nomerges', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/queue/scheduler', 0o644, b'noop anticipatory deadline [cfq] \n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/queue/hw_sector_size', 0o644, b'512\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/queue/max_hw_sectors_kb', 0o644, b'120\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/queue/read_ahead_kb', 0o644, b'128\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/queue/max_sectors_kb', 0o644, b'120\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/queue/iosched', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/queue/iosched/slice_async_rq', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/queue/iosched/back_seek_max', 0o644, b'16384\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/queue/iosched/slice_sync', 0o644, b'100\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/queue/iosched/slice_async', 0o644, b'40\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/queue/iosched/fifo_expire_sync', 0o644, b'125\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/queue/iosched/slice_idle', 0o644, b'8\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/queue/iosched/back_seek_penalty', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/queue/iosched/fifo_expire_async', 0o644, b'250\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/queue/iosched/quantum', 0o644, b'4\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/sdb1', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/sdb1/subsystem', '../../../../../../../../../../../../class/block')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/sdb1/start', 0o644, b'32\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/sdb1/make-it-fail', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/sdb1/size', 0o644, b'256992\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/sdb1/dev', 0o644, b'8:17\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/sdb1/stat', 0o644, b' 109 392 1903 246 0 0 0 0 0 169 246\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/sdb1/uevent', 0o644, b'''MAJOR=8
+MINOR=17
+DEVTYPE=partition
+''')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/sdb1/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/sdb1/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_device', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_device/7:0:0:0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_device/7:0:0:0/subsystem', '../../../../../../../../../../../class/scsi_device')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_device/7:0:0:0/device', '../../../7:0:0:0')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_device/7:0:0:0/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_device/7:0:0:0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/target7:0:0/7:0:0:0/scsi_device/7:0:0:0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/scsi_host', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/scsi_host/host7', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/scsi_host/host7/subsystem', '../../../../../../../../../class/scsi_host')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/scsi_host/host7/device', '../../../host7')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/scsi_host/host7/unique_id', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/scsi_host/host7/can_queue', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/scsi_host/host7/unchecked_isa_dma', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/scsi_host/host7/active_mode', 0o644, b'Initiator\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/scsi_host/host7/sg_tablesize', 0o644, b'128\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/scsi_host/host7/prot_guard_type', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/scsi_host/host7/host_busy', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/scsi_host/host7/proc_name', 0o644, b'usb-storage\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/scsi_host/host7/state', 0o644, b'running\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/scsi_host/host7/cmd_per_lun', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/scsi_host/host7/supported_mode', 0o644, b'Initiator\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/scsi_host/host7/uevent', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/scsi_host/host7/prot_capabilities', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/scsi_host/host7/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host7/scsi_host/host7/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/subsystem', '../../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/driver', '../../../../../bus/usb/drivers/usb')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/ep_00', 'usb_endpoint/usbdev5.9_ep00')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/version', 0o644, b' 2.00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/maxchild', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/bDeviceClass', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/bcdDevice', 0o644, b'0100\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/devnum', 0o644, b'9\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/bDeviceProtocol', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/idProduct', 0o644, b'007b\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/product', 0o644, b'N78\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/bDeviceSubClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/configuration', 0o644, b'Bulk transfer method configuration\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/dev', 0o644, b'189:520\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/urbnum', 0o644, b'20\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/authorized', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/descriptors', 0o644, b'''\x12\x01\x00\x02\x02\x00\x00@!\x04{\x00\x00\x01\x01\x02\x03\x01\t\x02\xab\x01\x0e\x01\x04\xc02\t\x04\x00\x00\x01\x02\x02\x01\x06\x05$\x00\x00\x01\x04$\x02\x0f\x05$\x06\x00\x01\x07\x05\x81\x03@\x00\x08\t\x04\x01\x00\x02
+\x00\x00\x07\x07\x05\x82\x02\x00\x02\xff\x07\x05\x01\x02\x00\x02\xff\t\x04\x02\x00\x01\x02\x02\xff\x08\x05$\x00\x00\x01\x04$\x02\x0f\x05$\x06\x02\x03\x07\x05\x83\x03@\x00\x08\t\x04\x03\x00\x02
+\x00\x00\t\x07\x05\x84\x02\x00\x02\xff\x07\x05\x02\x02\x00\x02\xff\t\x04\x04\x00\x00\x02\x08\x00\x00\x05$\x00\x10\x01\x05$\x11\x00\x01\r$\x06\x04\x05\x06\x07\x08\t
+\x0b\x0c\r\t\x04\x05\x00\x00\x02\x0b\x00
+\x05$\x00\x10\x01\x05$\x15\x00\x01\x05$\x06\x05\x06\t\x04\x06\x00\x00
+\x00\x00\x00\t\x04\x06\x01\x02
+\x00\x00\x00\x07\x05\x85\x02\x00\x02\xff\x07\x05\x03\x02\x00\x02\xff\t\x04\x07\x00\x00\x02\x0b\x00\x0b\x05$\x00\x10\x01\x05$\x15\x00\x01\x05$\x06\x07\x08\t\x04\x08\x00\x00
+\x00\x00\x00\t\x04\x08\x01\x02
+\x00\x00\x00\x07\x05\x86\x02\x00\x02\xff\x07\x05\x04\x02\x00\x02\xff\t\x04\t\x00\x00\x02\x08\x01\x00\x05$\x00\x10\x01\x05$\x08\x00\x01\x06$\x06\t
+\x0b\t\x04
+\x00\x00\x02\xfe\x00\x00\x05$\x00\x10\x01\x05$\xab\x05\x15\x05$\x06
+\x0b\t\x04\x0b\x00\x00
+\x00\x00\x00\t\x04\x0b\x01\x02
+\x00\x00\x00\x04$\xfd\x01\x07\x05\x05\x02\x00\x02\xff\x07\x05\x87\x02\x00\x02\xff\t\x04\x0c\x00\x00\x02\xfd\x00\x0c\x05$\x00\x10\x01\x05$\xfc\x00\x01\x05$\x06\x0c\r\x04$\xfd\x00\t\x04\r\x00\x00
+\x00\x00\x00\t\x04\r\x01\x02
+\x00\x00\x00\x07\x05\x88\x03\x00\x02\x06\x07\x05\x06\x02\x00\x02\xff\t\x04\r\x02\x02
+\x00\x00\x00\x07\x05\x88\x02\x00\x02\xff\x07\x05\x06\x02\x00\x02\xff''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/bNumConfigurations', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/serial', 0o644, b'354172020305000\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/speed', 0o644, b'480\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/bMaxPacketSize0', 0o644, b'64\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/bmAttributes', 0o644, b'c0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/busnum', 0o644, b'5\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/quirks', 0o644, b'0x0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/bConfigurationValue', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/uevent', 0o644, b'''MAJOR=189
+MINOR=520
+DEVTYPE=usb_device
+DRIVER=usb
+PRODUCT=421/7b/100
+TYPE=2/0/0
+BUSNUM=005
+DEVNUM=009
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/manufacturer', 0o644, b'Nokia\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/idVendor', 0o644, b'0421\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/bNumInterfaces', 0o644, b'14\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/bMaxPower', 0o644, b'100mA\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.4', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.4/subsystem', '../../../../../../bus/usb')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.4/modalias', 0o644, b'usb:v0421p007Bd0100dc02dsc00dp00ic02isc08ip00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.4/bInterfaceNumber', 0o644, b'04\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.4/bNumEndpoints', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.4/bInterfaceSubClass', 0o644, b'08\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.4/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.4/bInterfaceClass', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.4/uevent', 0o644, b'''DEVTYPE=usb_interface
+PRODUCT=421/7b/100
+TYPE=2/0/0
+INTERFACE=2/8/0
+MODALIAS=usb:v0421p007Bd0100dc02dsc00dp00ic02isc08ip00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.4/bInterfaceProtocol', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.4/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.4/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/usb_endpoint/usbdev5.9_ep00', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/usb_endpoint/usbdev5.9_ep00/subsystem', '../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/usb_endpoint/usbdev5.9_ep00/device', '../../../5-2')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/usb_endpoint/usbdev5.9_ep00/interval', 0o644, b'0ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/usb_endpoint/usbdev5.9_ep00/bEndpointAddress', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/usb_endpoint/usbdev5.9_ep00/type', 0o644, b'Control\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/usb_endpoint/usbdev5.9_ep00/dev', 0o644, b'252:33\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/usb_endpoint/usbdev5.9_ep00/direction', 0o644, b'both\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/usb_endpoint/usbdev5.9_ep00/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/usb_endpoint/usbdev5.9_ep00/wMaxPacketSize', 0o644, b'0040\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/usb_endpoint/usbdev5.9_ep00/bmAttributes', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/usb_endpoint/usbdev5.9_ep00/uevent', 0o644, b'''MAJOR=252
+MINOR=33
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/usb_endpoint/usbdev5.9_ep00/bInterval', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/usb_endpoint/usbdev5.9_ep00/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/usb_endpoint/usbdev5.9_ep00/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/subsystem', '../../../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/ep_83', 'usb_endpoint/usbdev5.9_ep83')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/modalias', 0o644, b'usb:v0421p007Bd0100dc02dsc00dp00ic02isc02ipFF\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/bInterfaceNumber', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/bNumEndpoints', 0o644, b'01\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/interface', 0o644, b'CDC Comms Interface\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/bInterfaceSubClass', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/bInterfaceClass', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/uevent', 0o644, b'''DEVTYPE=usb_interface
+PRODUCT=421/7b/100
+TYPE=2/0/0
+INTERFACE=2/2/255
+MODALIAS=usb:v0421p007Bd0100dc02dsc00dp00ic02isc02ipFF
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/bInterfaceProtocol', 0o644, b'ff\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/usb_endpoint/usbdev5.9_ep83', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/usb_endpoint/usbdev5.9_ep83/subsystem', '../../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/usb_endpoint/usbdev5.9_ep83/device', '../../../5-2:1.2')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/usb_endpoint/usbdev5.9_ep83/interval', 0o644, b'16ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/usb_endpoint/usbdev5.9_ep83/bEndpointAddress', 0o644, b'83\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/usb_endpoint/usbdev5.9_ep83/type', 0o644, b'Interrupt\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/usb_endpoint/usbdev5.9_ep83/dev', 0o644, b'252:30\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/usb_endpoint/usbdev5.9_ep83/direction', 0o644, b'in\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/usb_endpoint/usbdev5.9_ep83/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/usb_endpoint/usbdev5.9_ep83/wMaxPacketSize', 0o644, b'0040\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/usb_endpoint/usbdev5.9_ep83/bmAttributes', 0o644, b'03\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/usb_endpoint/usbdev5.9_ep83/uevent', 0o644, b'''MAJOR=252
+MINOR=30
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/usb_endpoint/usbdev5.9_ep83/bInterval', 0o644, b'08\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/usb_endpoint/usbdev5.9_ep83/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/usb_endpoint/usbdev5.9_ep83/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.2/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/subsystem', '../../../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/ep_01', 'usb_endpoint/usbdev5.9_ep01')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/ep_82', 'usb_endpoint/usbdev5.9_ep82')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/driver', '../../../../../../bus/usb/drivers/cdc_acm')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/modalias', 0o644, b'usb:v0421p007Bd0100dc02dsc00dp00ic0Aisc00ip00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/bInterfaceNumber', 0o644, b'01\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/bNumEndpoints', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/interface', 0o644, b'CDC Data Interface\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/bInterfaceSubClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/bInterfaceClass', 0o644, b'0a\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/uevent', 0o644, b'''DEVTYPE=usb_interface
+DRIVER=cdc_acm
+PRODUCT=421/7b/100
+TYPE=2/0/0
+INTERFACE=10/0/0
+MODALIAS=usb:v0421p007Bd0100dc02dsc00dp00ic0Aisc00ip00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/bInterfaceProtocol', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep01', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep01/subsystem', '../../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep01/device', '../../../5-2:1.1')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep01/interval', 0o644, b'31875us\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep01/bEndpointAddress', 0o644, b'01\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep01/type', 0o644, b'Bulk\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep01/dev', 0o644, b'252:29\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep01/direction', 0o644, b'out\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep01/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep01/wMaxPacketSize', 0o644, b'0200\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep01/bmAttributes', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep01/uevent', 0o644, b'''MAJOR=252
+MINOR=29
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep01/bInterval', 0o644, b'ff\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep01/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep01/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep82', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep82/subsystem', '../../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep82/device', '../../../5-2:1.1')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep82/interval', 0o644, b'0ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep82/bEndpointAddress', 0o644, b'82\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep82/type', 0o644, b'Bulk\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep82/dev', 0o644, b'252:28\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep82/direction', 0o644, b'in\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep82/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep82/wMaxPacketSize', 0o644, b'0200\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep82/bmAttributes', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep82/uevent', 0o644, b'''MAJOR=252
+MINOR=28
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep82/bInterval', 0o644, b'ff\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep82/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/usb_endpoint/usbdev5.9_ep82/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.1/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.10', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.10/subsystem', '../../../../../../bus/usb')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.10/modalias', 0o644, b'usb:v0421p007Bd0100dc02dsc00dp00ic02iscFEip00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.10/bInterfaceNumber', 0o644, b'0a\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.10/bNumEndpoints', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.10/bInterfaceSubClass', 0o644, b'fe\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.10/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.10/bInterfaceClass', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.10/uevent', 0o644, b'''DEVTYPE=usb_interface
+PRODUCT=421/7b/100
+TYPE=2/0/0
+INTERFACE=2/254/0
+MODALIAS=usb:v0421p007Bd0100dc02dsc00dp00ic02iscFEip00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.10/bInterfaceProtocol', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.10/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.10/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.7', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.7/subsystem', '../../../../../../bus/usb')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.7/modalias', 0o644, b'usb:v0421p007Bd0100dc02dsc00dp00ic02isc0Bip00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.7/bInterfaceNumber', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.7/bNumEndpoints', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.7/interface', 0o644, b'PC Suite Services\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.7/bInterfaceSubClass', 0o644, b'0b\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.7/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.7/bInterfaceClass', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.7/uevent', 0o644, b'''DEVTYPE=usb_interface
+PRODUCT=421/7b/100
+TYPE=2/0/0
+INTERFACE=2/11/0
+MODALIAS=usb:v0421p007Bd0100dc02dsc00dp00ic02isc0Bip00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.7/bInterfaceProtocol', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.7/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.7/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/subsystem', '../../../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/ep_81', 'usb_endpoint/usbdev5.9_ep81')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/driver', '../../../../../../bus/usb/drivers/cdc_acm')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/modalias', 0o644, b'usb:v0421p007Bd0100dc02dsc00dp00ic02isc02ip01\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/bInterfaceNumber', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/bmCapabilities', 0o644, b'15')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/bNumEndpoints', 0o644, b'01\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/interface', 0o644, b'CDC Comms Interface\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/bInterfaceSubClass', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/bInterfaceClass', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/uevent', 0o644, b'''DEVTYPE=usb_interface
+DRIVER=cdc_acm
+PRODUCT=421/7b/100
+TYPE=2/0/0
+INTERFACE=2/2/1
+MODALIAS=usb:v0421p007Bd0100dc02dsc00dp00ic02isc02ip01
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/bInterfaceProtocol', 0o644, b'01\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/usb_endpoint/usbdev5.9_ep81', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/usb_endpoint/usbdev5.9_ep81/subsystem', '../../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/usb_endpoint/usbdev5.9_ep81/device', '../../../5-2:1.0')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/usb_endpoint/usbdev5.9_ep81/interval', 0o644, b'16ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/usb_endpoint/usbdev5.9_ep81/bEndpointAddress', 0o644, b'81\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/usb_endpoint/usbdev5.9_ep81/type', 0o644, b'Interrupt\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/usb_endpoint/usbdev5.9_ep81/dev', 0o644, b'252:27\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/usb_endpoint/usbdev5.9_ep81/direction', 0o644, b'in\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/usb_endpoint/usbdev5.9_ep81/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/usb_endpoint/usbdev5.9_ep81/wMaxPacketSize', 0o644, b'0040\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/usb_endpoint/usbdev5.9_ep81/bmAttributes', 0o644, b'03\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/usb_endpoint/usbdev5.9_ep81/uevent', 0o644, b'''MAJOR=252
+MINOR=27
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/usb_endpoint/usbdev5.9_ep81/bInterval', 0o644, b'08\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/usb_endpoint/usbdev5.9_ep81/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/usb_endpoint/usbdev5.9_ep81/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0/subsystem', '../../../../../../../../class/tty')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0/device', '../../../5-2:1.0')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0/dev', 0o644, b'166:0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0/uevent', 0o644, b'''MAJOR=166
+MINOR=0
+DEVNAME=ttyACM0
+''')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.9', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.9/subsystem', '../../../../../../bus/usb')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.9/modalias', 0o644, b'usb:v0421p007Bd0100dc02dsc00dp00ic02isc08ip01\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.9/bInterfaceNumber', 0o644, b'09\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.9/bNumEndpoints', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.9/bInterfaceSubClass', 0o644, b'08\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.9/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.9/bInterfaceClass', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.9/uevent', 0o644, b'''DEVTYPE=usb_interface
+PRODUCT=421/7b/100
+TYPE=2/0/0
+INTERFACE=2/8/1
+MODALIAS=usb:v0421p007Bd0100dc02dsc00dp00ic02isc08ip01
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.9/bInterfaceProtocol', 0o644, b'01\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.9/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.9/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.8', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.8/subsystem', '../../../../../../bus/usb')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.8/modalias', 0o644, b'usb:v0421p007Bd0100dc02dsc00dp00ic0Aisc00ip00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.8/bInterfaceNumber', 0o644, b'08\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.8/bNumEndpoints', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.8/bInterfaceSubClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.8/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.8/bInterfaceClass', 0o644, b'0a\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.8/uevent', 0o644, b'''DEVTYPE=usb_interface
+PRODUCT=421/7b/100
+TYPE=2/0/0
+INTERFACE=10/0/0
+MODALIAS=usb:v0421p007Bd0100dc02dsc00dp00ic0Aisc00ip00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.8/bInterfaceProtocol', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.8/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.8/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/power/active_duration', 0o644, b'20902\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/power/wakeup', 0o644, b'\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/power/connected_duration', 0o644, b'20901\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/power/autosuspend', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/power/persist', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/power/level', 0o644, b'on\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.13', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.13/subsystem', '../../../../../../bus/usb')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.13/modalias', 0o644, b'usb:v0421p007Bd0100dc02dsc00dp00ic0Aisc00ip00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.13/bInterfaceNumber', 0o644, b'0d\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.13/bNumEndpoints', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.13/bInterfaceSubClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.13/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.13/bInterfaceClass', 0o644, b'0a\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.13/uevent', 0o644, b'''DEVTYPE=usb_interface
+PRODUCT=421/7b/100
+TYPE=2/0/0
+INTERFACE=10/0/0
+MODALIAS=usb:v0421p007Bd0100dc02dsc00dp00ic0Aisc00ip00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.13/bInterfaceProtocol', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.13/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.13/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.5', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.5/subsystem', '../../../../../../bus/usb')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.5/modalias', 0o644, b'usb:v0421p007Bd0100dc02dsc00dp00ic02isc0Bip00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.5/bInterfaceNumber', 0o644, b'05\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.5/bNumEndpoints', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.5/interface', 0o644, b'SYNCML-SYNC\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.5/bInterfaceSubClass', 0o644, b'0b\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.5/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.5/bInterfaceClass', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.5/uevent', 0o644, b'''DEVTYPE=usb_interface
+PRODUCT=421/7b/100
+TYPE=2/0/0
+INTERFACE=2/11/0
+MODALIAS=usb:v0421p007Bd0100dc02dsc00dp00ic02isc0Bip00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.5/bInterfaceProtocol', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.5/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.5/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.11', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.11/subsystem', '../../../../../../bus/usb')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.11/modalias', 0o644, b'usb:v0421p007Bd0100dc02dsc00dp00ic0Aisc00ip00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.11/bInterfaceNumber', 0o644, b'0b\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.11/bNumEndpoints', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.11/bInterfaceSubClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.11/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.11/bInterfaceClass', 0o644, b'0a\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.11/uevent', 0o644, b'''DEVTYPE=usb_interface
+PRODUCT=421/7b/100
+TYPE=2/0/0
+INTERFACE=10/0/0
+MODALIAS=usb:v0421p007Bd0100dc02dsc00dp00ic0Aisc00ip00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.11/bInterfaceProtocol', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.11/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.11/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.12', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.12/subsystem', '../../../../../../bus/usb')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.12/modalias', 0o644, b'usb:v0421p007Bd0100dc02dsc00dp00ic02iscFDip00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.12/bInterfaceNumber', 0o644, b'0c\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.12/bNumEndpoints', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.12/interface', 0o644, b'LCIF_Alt0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.12/bInterfaceSubClass', 0o644, b'fd\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.12/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.12/bInterfaceClass', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.12/uevent', 0o644, b'''DEVTYPE=usb_interface
+PRODUCT=421/7b/100
+TYPE=2/0/0
+INTERFACE=2/253/0
+MODALIAS=usb:v0421p007Bd0100dc02dsc00dp00ic02iscFDip00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.12/bInterfaceProtocol', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.12/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.12/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/subsystem', '../../../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/ep_02', 'usb_endpoint/usbdev5.9_ep02')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/ep_84', 'usb_endpoint/usbdev5.9_ep84')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/modalias', 0o644, b'usb:v0421p007Bd0100dc02dsc00dp00ic0Aisc00ip00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/bInterfaceNumber', 0o644, b'03\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/bNumEndpoints', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/interface', 0o644, b'CDC Data Interface\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/bInterfaceSubClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/bInterfaceClass', 0o644, b'0a\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/uevent', 0o644, b'''DEVTYPE=usb_interface
+PRODUCT=421/7b/100
+TYPE=2/0/0
+INTERFACE=10/0/0
+MODALIAS=usb:v0421p007Bd0100dc02dsc00dp00ic0Aisc00ip00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/bInterfaceProtocol', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep84', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep84/subsystem', '../../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep84/device', '../../../5-2:1.3')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep84/interval', 0o644, b'0ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep84/bEndpointAddress', 0o644, b'84\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep84/type', 0o644, b'Bulk\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep84/dev', 0o644, b'252:31\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep84/direction', 0o644, b'in\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep84/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep84/wMaxPacketSize', 0o644, b'0200\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep84/bmAttributes', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep84/uevent', 0o644, b'''MAJOR=252
+MINOR=31
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep84/bInterval', 0o644, b'ff\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep84/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep84/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep02', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep02/subsystem', '../../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep02/device', '../../../5-2:1.3')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep02/interval', 0o644, b'31875us\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep02/bEndpointAddress', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep02/type', 0o644, b'Bulk\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep02/dev', 0o644, b'252:32\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep02/direction', 0o644, b'out\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep02/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep02/wMaxPacketSize', 0o644, b'0200\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep02/bmAttributes', 0o644, b'02\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep02/uevent', 0o644, b'''MAJOR=252
+MINOR=32
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep02/bInterval', 0o644, b'ff\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep02/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/usb_endpoint/usbdev5.9_ep02/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.3/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.6', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.6/subsystem', '../../../../../../bus/usb')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.6/modalias', 0o644, b'usb:v0421p007Bd0100dc02dsc00dp00ic0Aisc00ip00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.6/bInterfaceNumber', 0o644, b'06\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.6/bNumEndpoints', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.6/bInterfaceSubClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.6/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.6/bInterfaceClass', 0o644, b'0a\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.6/uevent', 0o644, b'''DEVTYPE=usb_interface
+PRODUCT=421/7b/100
+TYPE=2/0/0
+INTERFACE=10/0/0
+MODALIAS=usb:v0421p007Bd0100dc02dsc00dp00ic0Aisc00ip00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.6/bInterfaceProtocol', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.6/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.6/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/power/active_duration', 0o644, b'547102\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/power/wakeup', 0o644, b'enabled\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/power/connected_duration', 0o644, b'8371932\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/power/autosuspend', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/power/level', 0o644, b'auto\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/subsystem', '../../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/ep_81', 'usb_endpoint/usbdev5.1_ep81')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/driver', '../../../../../bus/usb/drivers/hub')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/modalias', 0o644, b'usb:v1D6Bp0002d0206dc09dsc00dp00ic09isc00ip00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/bInterfaceNumber', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/bNumEndpoints', 0o644, b'01\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/bInterfaceSubClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/bInterfaceClass', 0o644, b'09\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/uevent', 0o644, b'''DEVTYPE=usb_interface
+DRIVER=hub
+PRODUCT=1d6b/2/206
+TYPE=9/0/0
+INTERFACE=9/0/0
+MODALIAS=usb:v1D6Bp0002d0206dc09dsc00dp00ic09isc00ip00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/bInterfaceProtocol', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/usb_endpoint/usbdev5.1_ep81', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/usb_endpoint/usbdev5.1_ep81/subsystem', '../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/usb_endpoint/usbdev5.1_ep81/device', '../../../5-0:1.0')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/usb_endpoint/usbdev5.1_ep81/interval', 0o644, b'256ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/usb_endpoint/usbdev5.1_ep81/bEndpointAddress', 0o644, b'81\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/usb_endpoint/usbdev5.1_ep81/type', 0o644, b'Interrupt\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/usb_endpoint/usbdev5.1_ep81/dev', 0o644, b'252:8\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/usb_endpoint/usbdev5.1_ep81/direction', 0o644, b'in\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/usb_endpoint/usbdev5.1_ep81/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/usb_endpoint/usbdev5.1_ep81/wMaxPacketSize', 0o644, b'0004\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/usb_endpoint/usbdev5.1_ep81/bmAttributes', 0o644, b'03\n')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/usb_endpoint/usbdev5.1_ep81/uevent', 0o644, b'''MAJOR=252
+MINOR=8
+''')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/usb_endpoint/usbdev5.1_ep81/bInterval', 0o644, b'0c\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/usb_endpoint/usbdev5.1_ep81/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/usb_endpoint/usbdev5.1_ep81/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb5/5-0:1.0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/power/wakeup', 0o644, b'disabled\n')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb_host', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.7/usb_host/usb_host5', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.7/usb_host/usb_host5/subsystem', '../../../../../class/usb_host')
+l('sys/devices/pci0000:00/0000:00:1d.7/usb_host/usb_host5/device', '../../../0000:00:1d.7')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb_host/usb_host5/companion', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1d.7/usb_host/usb_host5/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1d.7/usb_host/usb_host5/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.7/usb_host/usb_host5/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.1', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.1/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:0c')
+l('sys/devices/pci0000:00/0000:00:1c.1/subsystem', '../../../bus/pci')
+l('sys/devices/pci0000:00/0000:00:1c.1/driver', '../../../bus/pci/drivers/pcieport-driver')
+f('sys/devices/pci0000:00/0000:00:1c.1/local_cpulist', 0o644, b'0-7\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/enable', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/modalias', 0o644, b'pci:v00008086d000027D2sv00000000sd00000000bc06sc04i00\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/resource', 0o644, b'''0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000004000 0x0000000000005fff 0x0000000000000100
+0x00000000ec000000 0x00000000edffffff 0x0000000000000200
+0x00000000e4000000 0x00000000e40fffff 0x0000000000001201
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+''')
+f('sys/devices/pci0000:00/0000:00:1c.1/config', 0o644, b"\x86\x80\xd2'\x07\x05\x10\x00\x02\x00\x04\x06\x10\x00\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x03\x00@P\x00\x00\x00\xec\xf0\xed\x01\xe4\x01\xe4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x0b\x02\x04\x00\x10\x80A\x01\xc0\x0f\x00\x00\x00\x00\x11\x00\x11,\x11\x02B\x00\x110\xe0\xa0\x18\x00\x00\x00H\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x90\x01\x00\x0c0\xe0\xfe\x81A\x00\x00\x00\x00\x00\x00\r\xa0\x00\x00\xaa\x17\x11 \x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\xc8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x11\x00\x00\x00\x00\x00\x00\x0f\xc7\x80\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x0f\x02\x00\x00\x00\x00\x00\x02\x00\x01\x18\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x80\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x06\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x01\x00\x00\x01\x02\x02\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\x00\x00\x00\x00\x00\x01\xc0\xd1\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07`\x00`\x00\x00\x00\x00`\x02\x00\x00\x0c\x00\x06\x00\x00\x00\x001[`\xc9\xc0\x00p&u\xa2\x178\x00\xa1\x07G\x02\x16\x00\x00\x14\xb5\xbcJ\xbc\x0b*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x0c\xb4\x00\xc4\x0c\xb6\x00A\x08z\x00Y\x00\x1b\x00[\x00\x1d\x00\x01\x00\xba\x00\xe3\x0f\xd3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x02\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
+f('sys/devices/pci0000:00/0000:00:1c.1/local_cpus', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/subsystem_device', 0o644, b'0x0000\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/vendor', 0o644, b'0x8086\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/irq', 0o644, b'509\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/device', 0o644, b'0x27d2\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/class', 0o644, b'0x060400\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/msi_bus', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/subsystem_vendor', 0o644, b'0x0000\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/uevent', 0o644, b'''DRIVER=pcieport-driver
+PCI_CLASS=60400
+PCI_ID=8086:27D2
+PCI_SUBSYS_ID=0000:0000
+PCI_SLOT_NAME=0000:00:1c.1
+MODALIAS=pci:v00008086d000027D2sv00000000sd00000000bc06sc04i00
+''')
+f('sys/devices/pci0000:00/0000:00:1c.1/broken_parity_status', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1c.1/pci_bus', 0o755)
+d('sys/devices/pci0000:00/0000:00:1c.1/pci_bus/0000:03', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.1/pci_bus/0000:03/subsystem', '../../../../../class/pci_bus')
+l('sys/devices/pci0000:00/0000:00:1c.1/pci_bus/0000:03/device', '../../../0000:00:1c.1')
+f('sys/devices/pci0000:00/0000:00:1c.1/pci_bus/0000:03/cpuaffinity', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/pci_bus/0000:03/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1c.1/pci_bus/0000:03/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.1/pci_bus/0000:03/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.1/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.1/power/wakeup', 0o644, b'disabled\n')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:00:1c.1:pcie02', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.1/0000:00:1c.1:pcie02/subsystem', '../../../../bus/pci_express')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:00:1c.1:pcie02/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:00:1c.1:pcie02/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:00:1c.1:pcie02/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:00:1c.1:pcie03', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.1/0000:00:1c.1:pcie03/subsystem', '../../../../bus/pci_express')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:00:1c.1:pcie03/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:00:1c.1:pcie03/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:00:1c.1:pcie03/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/subsystem', '../../../../bus/pci')
+l('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/driver', '../../../../bus/pci/drivers/iwl3945')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/local_cpulist', 0o644, b'0-7\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/enable', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/rs_window', 0o644, b''' 54Mbs: 00000000000000000000000000000000000000000000000000000000000000
+ 48Mbs: 00000000000000000000000000000000000000000000000000000000000000
+ 36Mbs: 00000000000000000000000000000000000000000000000000000000000000
+ 24Mbs: 00000000000000000000000000000000000000000000000000000000000000
+ 18Mbs: 00000000000000000000000000000000000000000000000000000000000000
+ 12Mbs: 00000000000000000000000000000000000000000000000000000000000000
+ 11Mbs: 00000000000000000000000000000000000000000000000000000000000000
+ 9Mbs: 00000000000000000000000000000000000000000000000000000000000000
+ 6Mbs: 00000000000000000000000000000000000000000000000000000000000000
+ 5Mbs: 00000000000000000000000000000000000000000000000000000000000000
+ 2Mbs: 00000000000000000000000000000000000000000000000000000000000000
+ 1Mbs: 00000000000000000000000000000000000000000000000000000000000000
+
+Average rate: 0Mbs
+''')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/modalias', 0o644, b'pci:v00008086d00004227sv00008086sd00001011bc02sc80i00\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/resource', 0o644, b'''0x00000000edf00000 0x00000000edf00fff 0x0000000000020200
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+''')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/statistics', 0o644, b'''02 00 01 00 a4 c0 02 00 c6 27 01 00 80 16 01 00 .........\'......
+e9 0c 00 00 00 00 00 00 00 00 00 00 69 05 00 00 ............i...
+de 98 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+00 00 00 00 00 00 00 00 bd 01 00 00 00 00 00 00 ................
+fd 68 08 00 ae d3 06 00 78 65 04 00 b8 2b 00 00 .h......xe...+..
+00 00 00 00 00 00 00 00 7e 42 02 00 4f 95 01 00 ........~B..O...
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+00 00 00 00 da 01 00 00 00 00 00 00 00 00 00 00 ................
+00 00 00 00 d8 dc 00 00 59 10 01 00 00 00 00 00 ........Y.......
+df 0c 00 00 16 00 00 00 00 00 00 00 00 00 00 00 ................
+88 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 ................
+00 00 00 00 72 ff ff ff 00 00 00 00 00 00 00 00 ....r...........
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+00 00 00 00 01 00 00 00 bb 45 98 35 1c 91 e7 f1 .........E.5....
+4c 19 00 00 c2 0c 00 00 e7 ed 00 00 1c 4c 00 00 L............L..
+''')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/config', 0o644, b'\x86\x80\'B\x06\x05\x10\x00\x02\x00\x80\x02\x10\x00\x00\x00\x00\x00\xf0\xed\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x80\x11\x10\x00\x00\x00\x00\xc8\x00\x00\x00\x00\x00\x00\x00\x0b\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xd0"H\x00\x00\x00\r\x05\xe0\x81\x00\x0c\x10\xe0\xfe\x00\x00\x00\x00\xd1A\x00\x00\x10\x00\x11\x00\xc0\x0e\x00\x00\x10\x08\n\x00\x11\x1c\x07\x00B\x01\x11\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x14\x00\x00\x10\x00\x00\x00\x00\x00\x11 \x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x01\x00\x00\x04\x0f\x1a\x00\x00\x00\x01\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x01\x00\xd1\xaeu\xff\xff\xd2\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/filter_flags', 0o644, b'0x0024\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/retry_rate', 0o644, b'1')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/local_cpus', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/channels', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/subsystem_device', 0o644, b'0x1011\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/vendor', 0o644, b'0x8086\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/tx_power', 0o644, b'16\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/irq', 0o644, b'504\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/antenna', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/device', 0o644, b'0x4227\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/class', 0o644, b'0x028000\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/power_level', 0o644, b'6 (AC) OFF\n\x00')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/msi_bus', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/flags', 0o644, b'0x8015\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/resource0', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/temperature', 0o644, b'-142\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/measurement', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/subsystem_vendor', 0o644, b'0x8086\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/uevent', 0o644, b'''DRIVER=iwl3945
+PCI_CLASS=28000
+PCI_ID=8086:4227
+PCI_SUBSYS_ID=8086:1011
+PCI_SLOT_NAME=0000:03:00.0
+MODALIAS=pci:v00008086d00004227sv00008086sd00001011bc02sc80i00
+''')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/status', 0o644, b'0x000002e4\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/broken_parity_status', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/ieee80211', 0o755)
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/ieee80211/phy0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/ieee80211/phy0/subsystem', '../../../../../../class/ieee80211')
+l('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/ieee80211/phy0/device', '../../../0000:03:00.0')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/ieee80211/phy0/index', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/ieee80211/phy0/uevent', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/ieee80211/phy0/macaddress', 0o644, b'00:19:d2:75:ae:d1\n')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/ieee80211/phy0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/ieee80211/phy0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/power/wakeup', 0o644, b'disabled\n')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net', 0o755)
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/subsystem', '../../../../../../class/net')
+l('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/device', '../../../0000:03:00.0')
+l('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/phy80211', '../../ieee80211/phy0')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/ifindex', 0o644, b'3\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/features', 0o644, b'0x0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/iflink', 0o644, b'3\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/dormant', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/dev_id', 0o644, b'0x0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/type', 0o644, b'801\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/operstate', 0o644, b'unknown\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/carrier', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/link_mode', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/tx_queue_len', 0o644, b'1000\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/flags', 0o644, b'0x1003\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/addr_len', 0o644, b'6\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/address', 0o644, b'00:19:d2:75:ae:ff\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/uevent', 0o644, b'''INTERFACE=wmaster0
+IFINDEX=3
+''')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/mtu', 0o644, b'1500\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/broadcast', 0o644, b'ff:ff:ff:ff:ff:ff\n')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/tx_aborted_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/rx_crc_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/rx_bytes', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/rx_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/tx_packets', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/tx_carrier_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/tx_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/rx_dropped', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/tx_fifo_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/rx_length_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/tx_dropped', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/rx_fifo_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/rx_missed_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/tx_window_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/collisions', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/rx_frame_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/rx_packets', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/rx_compressed', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/tx_compressed', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/multicast', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/rx_over_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/tx_bytes', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/statistics/tx_heartbeat_errors', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wmaster0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/subsystem', '../../../../../../class/net')
+l('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/device', '../../../0000:03:00.0')
+l('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/phy80211', '../../ieee80211/phy0')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/ifindex', 0o644, b'4\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/features', 0o644, b'0x0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/iflink', 0o644, b'4\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/dormant', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/dev_id', 0o644, b'0x0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/type', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/operstate', 0o644, b'up\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/carrier', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/link_mode', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/tx_queue_len', 0o644, b'1000\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/flags', 0o644, b'0x1003\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/addr_len', 0o644, b'6\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/address', 0o644, b'00:19:d2:75:ae:ff\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/uevent', 0o644, b'''INTERFACE=wlan0
+IFINDEX=4
+''')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/mtu', 0o644, b'1500\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/broadcast', 0o644, b'ff:ff:ff:ff:ff:ff\n')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/tx_aborted_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/rx_crc_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/rx_bytes', 0o644, b'289996\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/rx_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/tx_packets', 0o644, b'1029\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/tx_carrier_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/tx_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/rx_dropped', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/tx_fifo_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/rx_length_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/tx_dropped', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/rx_fifo_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/rx_missed_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/tx_window_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/collisions', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/rx_frame_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/rx_packets', 0o644, b'788\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/rx_compressed', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/tx_compressed', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/multicast', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/rx_over_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/tx_bytes', 0o644, b'530013\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/statistics/tx_heartbeat_errors', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/wireless', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/wireless/beacon', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/wireless/link', 0o644, b'77\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/wireless/nwid', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/wireless/retries', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/wireless/fragment', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/wireless/misc', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/wireless/crypt', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/wireless/noise', 0o644, b'178\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/wireless/level', 0o644, b'199\n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0/wireless/status', 0o644, b'0x0\n')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds', 0o755)
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:TX', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:TX/subsystem', '../../../../../../class/leds')
+l('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:TX/device', '../../../0000:03:00.0')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:TX/trigger', 0o644, b'none AC-online BAT0-charging-or-full BAT0-charging BAT0-full rfkill0 phy0rx [phy0tx] phy0assoc phy0radio \n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:TX/brightness', 0o644, b'0\n\x00')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:TX/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:TX/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:TX/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:assoc', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:assoc/subsystem', '../../../../../../class/leds')
+l('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:assoc/device', '../../../0000:03:00.0')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:assoc/trigger', 0o644, b'none AC-online BAT0-charging-or-full BAT0-charging BAT0-full rfkill0 phy0rx phy0tx [phy0assoc] phy0radio \n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:assoc/brightness', 0o644, b'255\n\x00')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:assoc/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:assoc/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:assoc/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:radio', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:radio/subsystem', '../../../../../../class/leds')
+l('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:radio/device', '../../../0000:03:00.0')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:radio/trigger', 0o644, b'none AC-online BAT0-charging-or-full BAT0-charging BAT0-full rfkill0 phy0rx phy0tx phy0assoc [phy0radio] \n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:radio/brightness', 0o644, b'255\n\x00')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:radio/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:radio/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:radio/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:RX', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:RX/subsystem', '../../../../../../class/leds')
+l('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:RX/device', '../../../0000:03:00.0')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:RX/trigger', 0o644, b'none AC-online BAT0-charging-or-full BAT0-charging BAT0-full rfkill0 [phy0rx] phy0tx phy0assoc phy0radio \n')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:RX/brightness', 0o644, b'0\n\x00')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:RX/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:RX/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/leds/iwl-phy0:RX/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:00:1c.1:pcie00', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.1/0000:00:1c.1:pcie00/subsystem', '../../../../bus/pci_express')
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:00:1c.1:pcie00/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1c.1/0000:00:1c.1:pcie00/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.1/0000:00:1c.1:pcie00/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:00.0', 0o755)
+l('sys/devices/pci0000:00/0000:00:00.0/subsystem', '../../../bus/pci')
+f('sys/devices/pci0000:00/0000:00:00.0/local_cpulist', 0o644, b'0-7\n')
+f('sys/devices/pci0000:00/0000:00:00.0/enable', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:00.0/modalias', 0o644, b'pci:v00008086d000027A0sv000017AAsd00002015bc06sc00i00\n')
+f('sys/devices/pci0000:00/0000:00:00.0/resource', 0o644, b'''0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+''')
+f('sys/devices/pci0000:00/0000:00:00.0/config', 0o644, b"\x86\x80\xa0'\x06\x01\x90 \x03\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x17\x15 \x00\x00\x00\x00\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x90\xd1\xfe\x01@\xd1\xfe\x05\x00\x00\xf0\x01\x80\xd1\xfe\x00\x00\x02\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x11\x11\x000\x11\x11\x00\xff\x03\x00\x00\x80\x1a9\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\t\x00\tQJ\x00J\xb0\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x0f\x05\x00\x10\x00\x00\x00")
+f('sys/devices/pci0000:00/0000:00:00.0/local_cpus', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:00.0/subsystem_device', 0o644, b'0x2015\n')
+f('sys/devices/pci0000:00/0000:00:00.0/vendor', 0o644, b'0x8086\n')
+f('sys/devices/pci0000:00/0000:00:00.0/irq', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:00.0/device', 0o644, b'0x27a0\n')
+f('sys/devices/pci0000:00/0000:00:00.0/class', 0o644, b'0x060000\n')
+f('sys/devices/pci0000:00/0000:00:00.0/msi_bus', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:00.0/subsystem_vendor', 0o644, b'0x17aa\n')
+f('sys/devices/pci0000:00/0000:00:00.0/uevent', 0o644, b'''PCI_CLASS=60000
+PCI_ID=8086:27A0
+PCI_SUBSYS_ID=17AA:2015
+PCI_SLOT_NAME=0000:00:00.0
+MODALIAS=pci:v00008086d000027A0sv000017AAsd00002015bc06sc00i00
+''')
+f('sys/devices/pci0000:00/0000:00:00.0/broken_parity_status', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:00.0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:00.0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.3', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.3/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:0f')
+l('sys/devices/pci0000:00/0000:00:1c.3/subsystem', '../../../bus/pci')
+l('sys/devices/pci0000:00/0000:00:1c.3/driver', '../../../bus/pci/drivers/pcieport-driver')
+f('sys/devices/pci0000:00/0000:00:1c.3/local_cpulist', 0o644, b'0-7\n')
+f('sys/devices/pci0000:00/0000:00:1c.3/enable', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1c.3/modalias', 0o644, b'pci:v00008086d000027D6sv00000000sd00000000bc06sc04i00\n')
+f('sys/devices/pci0000:00/0000:00:1c.3/resource', 0o644, b'''0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000008000 0x0000000000009fff 0x0000000000000100
+0x00000000ea000000 0x00000000ebffffff 0x0000000000000200
+0x00000000e4200000 0x00000000e42fffff 0x0000000000001201
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+''')
+f('sys/devices/pci0000:00/0000:00:1c.3/config', 0o644, b"\x86\x80\xd6'\x07\x05\x10\x00\x02\x00\x04\x06\x10\x00\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x13\x00\x80\x90\x00\x00\x00\xea\xf0\xeb!\xe4!\xe4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x0b\x04\x04\x00\x10\x80A\x01\xc0\x0f\x00\x00\x00\x00\x10\x00\x11L\x11\x04\x00\x00\x01\x10\xe0\xa0(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x90\x01\x00\x0c0\xe0\xfe\x91A\x00\x00\x00\x00\x00\x00\r\xa0\x00\x00\xaa\x17\x11 \x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\xc8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x11\x00\x00\x00\x00\x00\x00\x00\xc7\x00\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x0f\x02\x00\x00\x00\x00\x00\x02\x00\x01\x18\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xff\x00\x00\x80\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x01\x00\x00\x01\x02\x04\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\x00\x00\x00\x00\x00\x01\xc0\xd1\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07`\x00`\x00\x00\x00\x00`\x02\x00\x00\x0c\x00\x06\x00\x00\x00\x00\x00[`\xc9\xc0\x00p&u\x00\x10\x00\x00\xff\x0f\x00\x00\x16\x00\x00\x14\xb5\xbcJ\xbc\x0b*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x02\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
+f('sys/devices/pci0000:00/0000:00:1c.3/local_cpus', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1c.3/subsystem_device', 0o644, b'0x0000\n')
+f('sys/devices/pci0000:00/0000:00:1c.3/vendor', 0o644, b'0x8086\n')
+f('sys/devices/pci0000:00/0000:00:1c.3/irq', 0o644, b'507\n')
+f('sys/devices/pci0000:00/0000:00:1c.3/device', 0o644, b'0x27d6\n')
+f('sys/devices/pci0000:00/0000:00:1c.3/class', 0o644, b'0x060400\n')
+f('sys/devices/pci0000:00/0000:00:1c.3/msi_bus', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1c.3/subsystem_vendor', 0o644, b'0x0000\n')
+f('sys/devices/pci0000:00/0000:00:1c.3/uevent', 0o644, b'''DRIVER=pcieport-driver
+PCI_CLASS=60400
+PCI_ID=8086:27D6
+PCI_SUBSYS_ID=0000:0000
+PCI_SLOT_NAME=0000:00:1c.3
+MODALIAS=pci:v00008086d000027D6sv00000000sd00000000bc06sc04i00
+''')
+f('sys/devices/pci0000:00/0000:00:1c.3/broken_parity_status', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1c.3/pci_bus', 0o755)
+d('sys/devices/pci0000:00/0000:00:1c.3/pci_bus/0000:0c', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.3/pci_bus/0000:0c/subsystem', '../../../../../class/pci_bus')
+l('sys/devices/pci0000:00/0000:00:1c.3/pci_bus/0000:0c/device', '../../../0000:00:1c.3')
+f('sys/devices/pci0000:00/0000:00:1c.3/pci_bus/0000:0c/cpuaffinity', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1c.3/pci_bus/0000:0c/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1c.3/pci_bus/0000:0c/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.3/pci_bus/0000:0c/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.3/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.3/power/wakeup', 0o644, b'disabled\n')
+d('sys/devices/pci0000:00/0000:00:1c.3/0000:00:1c.3:pcie02', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.3/0000:00:1c.3:pcie02/subsystem', '../../../../bus/pci_express')
+f('sys/devices/pci0000:00/0000:00:1c.3/0000:00:1c.3:pcie02/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1c.3/0000:00:1c.3:pcie02/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.3/0000:00:1c.3:pcie02/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.3/0000:00:1c.3:pcie03', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.3/0000:00:1c.3:pcie03/subsystem', '../../../../bus/pci_express')
+f('sys/devices/pci0000:00/0000:00:1c.3/0000:00:1c.3:pcie03/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1c.3/0000:00:1c.3:pcie03/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.3/0000:00:1c.3:pcie03/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.3/0000:00:1c.3:pcie00', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.3/0000:00:1c.3:pcie00/subsystem', '../../../../bus/pci_express')
+f('sys/devices/pci0000:00/0000:00:1c.3/0000:00:1c.3:pcie00/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1c.3/0000:00:1c.3:pcie00/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.3/0000:00:1c.3:pcie00/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.0/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:01')
+l('sys/devices/pci0000:00/0000:00:1f.0/subsystem', '../../../bus/pci')
+f('sys/devices/pci0000:00/0000:00:1f.0/local_cpulist', 0o644, b'0-7\n')
+f('sys/devices/pci0000:00/0000:00:1f.0/enable', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.0/modalias', 0o644, b'pci:v00008086d000027B9sv000017AAsd00002009bc06sc01i00\n')
+f('sys/devices/pci0000:00/0000:00:1f.0/resource', 0o644, b'''0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+''')
+f('sys/devices/pci0000:00/0000:00:1f.0/config', 0o644, b'''\x86\x80\xb9\'\x07\x00\x10\x02\x02\x00\x01\x06\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x17\t \x00\x00\x00\x00\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x10\x00\x00\x80\x00\x00\x00\x81\x11\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8b\x8b\x8b\x8b\x92\x00\x00\x00\x8b\x8b\x8b\x8b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00
+\x1f\x01\x16|\x00\xe1\x15\x0c\x00\x81\x16\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\x06\x02\x00\x00\x00\x00\x00\x13\x1c
+\x00\x00\x03\x00\x00\x00\x00\xf0\x00\x00\x00\x00\x00\x00\x00\x12
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D\x12\x11\x00gE\x00\x00\xc0\xff\x00\x00\x01\x00\x00\x00\t\x00\x0c\x10\xb4\x02$\x17\x00\x00\x00\x00\x00\x00\x00\x00\x01\xc0\xd1\xfe\x00\x00\x00\x00\x86\x0f\x02\x00\x00\x00\x00\x00''')
+f('sys/devices/pci0000:00/0000:00:1f.0/local_cpus', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1f.0/subsystem_device', 0o644, b'0x2009\n')
+f('sys/devices/pci0000:00/0000:00:1f.0/vendor', 0o644, b'0x8086\n')
+f('sys/devices/pci0000:00/0000:00:1f.0/irq', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.0/device', 0o644, b'0x27b9\n')
+f('sys/devices/pci0000:00/0000:00:1f.0/class', 0o644, b'0x060100\n')
+f('sys/devices/pci0000:00/0000:00:1f.0/msi_bus', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.0/subsystem_vendor', 0o644, b'0x17aa\n')
+f('sys/devices/pci0000:00/0000:00:1f.0/uevent', 0o644, b'''PCI_CLASS=60100
+PCI_ID=8086:27B9
+PCI_SUBSYS_ID=17AA:2009
+PCI_SLOT_NAME=0000:00:1f.0
+MODALIAS=pci:v00008086d000027B9sv000017AAsd00002009bc06sc01i00
+''')
+f('sys/devices/pci0000:00/0000:00:1f.0/broken_parity_status', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1f.0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.0/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:0b')
+l('sys/devices/pci0000:00/0000:00:1c.0/subsystem', '../../../bus/pci')
+l('sys/devices/pci0000:00/0000:00:1c.0/driver', '../../../bus/pci/drivers/pcieport-driver')
+f('sys/devices/pci0000:00/0000:00:1c.0/local_cpulist', 0o644, b'0-7\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/enable', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/modalias', 0o644, b'pci:v00008086d000027D0sv00000000sd00000000bc06sc04i00\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/resource', 0o644, b'''0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000003000 0x0000000000003fff 0x0000000000000100
+0x00000000ee000000 0x00000000ee0fffff 0x0000000000000200
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+''')
+f('sys/devices/pci0000:00/0000:00:1c.0/config', 0o644, b"\x86\x80\xd0'\x07\x05\x10\x00\x02\x00\x04\x06\x10\x00\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x02\x0000\x00\x00\x00\xee\x00\xee\xf1\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x0b\x01\x04\x00\x10\x80A\x01\xc0\x0f\x00\x00\x00\x00\x11\x00\x11,\x11\x01B\x00\x110\xe0\xa0\x10\x00(\x00@\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x90\x01\x00\x0c0\xe0\xfeyA\x00\x00\x00\x00\x00\x00\r\xa0\x00\x00\xaa\x17\x11 \x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\xc8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x11\xc0\x00\x00\x00\x00\x00\x0f\xc7\x00\x06\x07\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x0f\x02\x00\x00\x00\x00\x00\x02\x00\x01\x18\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x80\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x11\x00\x06\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x01\x00\x00\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\x00\x00\x00\x00\x00\x01\xc0\xd1\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07`\x00`\x00\x00\x00\x00`\x02\x00\x00\x0c\x00\x06\x00\x00\x00\x00\x08[`\xc9\xc0\x00p&u:\x188\x009\x08\x9e\x0e\x16\x00\x00\x14\xb5\xbcJ\xbc\x0b*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xec\t\xec\x00\xfc\t\xee\x00c\x00W\x00i\x00J\x00k\x00L\x00\x01\x00\x05\x00\x10\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x02\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
+f('sys/devices/pci0000:00/0000:00:1c.0/local_cpus', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/subsystem_device', 0o644, b'0x0000\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/vendor', 0o644, b'0x8086\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/irq', 0o644, b'510\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/device', 0o644, b'0x27d0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/class', 0o644, b'0x060400\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/msi_bus', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/subsystem_vendor', 0o644, b'0x0000\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/uevent', 0o644, b'''DRIVER=pcieport-driver
+PCI_CLASS=60400
+PCI_ID=8086:27D0
+PCI_SUBSYS_ID=0000:0000
+PCI_SLOT_NAME=0000:00:1c.0
+MODALIAS=pci:v00008086d000027D0sv00000000sd00000000bc06sc04i00
+''')
+f('sys/devices/pci0000:00/0000:00:1c.0/broken_parity_status', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1c.0/0000:00:1c.0:pcie03', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.0/0000:00:1c.0:pcie03/subsystem', '../../../../bus/pci_express')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:00:1c.0:pcie03/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1c.0/0000:00:1c.0:pcie03/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:00:1c.0:pcie03/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.0/pci_bus', 0o755)
+d('sys/devices/pci0000:00/0000:00:1c.0/pci_bus/0000:02', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.0/pci_bus/0000:02/subsystem', '../../../../../class/pci_bus')
+l('sys/devices/pci0000:00/0000:00:1c.0/pci_bus/0000:02/device', '../../../0000:00:1c.0')
+f('sys/devices/pci0000:00/0000:00:1c.0/pci_bus/0000:02/cpuaffinity', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/pci_bus/0000:02/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1c.0/pci_bus/0000:02/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.0/pci_bus/0000:02/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.0/power/wakeup', 0o644, b'disabled\n')
+d('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/subsystem', '../../../../bus/pci')
+l('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/driver', '../../../../bus/pci/drivers/e1000e')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/local_cpulist', 0o644, b'0-7\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/enable', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/modalias', 0o644, b'pci:v00008086d0000109Asv000017AAsd00002001bc02sc00i00\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/resource', 0o644, b'''0x00000000ee000000 0x00000000ee01ffff 0x0000000000020200
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000003000 0x000000000000301f 0x0000000000020101
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+''')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/config', 0o644, b'\x86\x80\x9a\x10\x07\x05\x10\x00\x00\x00\x00\x02\x10\x00\x00\x00\x00\x00\x00\xee\x00\x00\x00\x00\x010\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x17\x01 \x00\x00\x00\x00\xc8\x00\x00\x00\x00\x00\x00\x00\x0b\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xd0"\xc8\x00 \x00\x0f\x05\xe0\x81\x00\x0c\x10\xe0\xfe\x00\x00\x00\x00\xc9A\x00\x00\x10\x00\x01\x00\xc1\x0c\x00\x00\x10(\x1a\x00\x11\x1c\x07\x00@\x01\x11\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x14\x00\x00\x10\x00\x00\x00\x00\x00\x11 \x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x01\x00\x00\x04\x0f\x03\x00\x00\x00\x01\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x01\x00\xc7\x8d\xe2\xff\xffA\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/resource2', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/local_cpus', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/subsystem_device', 0o644, b'0x2001\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/vendor', 0o644, b'0x8086\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/irq', 0o644, b'505\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/device', 0o644, b'0x109a\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/class', 0o644, b'0x020000\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/msi_bus', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/resource0', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/subsystem_vendor', 0o644, b'0x17aa\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/uevent', 0o644, b'''DRIVER=e1000e
+PCI_CLASS=20000
+PCI_ID=8086:109A
+PCI_SUBSYS_ID=17AA:2001
+PCI_SLOT_NAME=0000:02:00.0
+MODALIAS=pci:v00008086d0000109Asv000017AAsd00002001bc02sc00i00
+''')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/broken_parity_status', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/power/wakeup', 0o644, b'disabled\n')
+d('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net', 0o755)
+d('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/subsystem', '../../../../../../class/net')
+l('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/device', '../../../0000:02:00.0')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/ifindex', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/features', 0o644, b'0x111ba9\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/iflink', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/dormant', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/dev_id', 0o644, b'0x0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/type', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/operstate', 0o644, b'down\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/carrier', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/link_mode', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/tx_queue_len', 0o644, b'1000\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/flags', 0o644, b'0x1003\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/addr_len', 0o644, b'6\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/address', 0o644, b'00:16:41:e2:8d:ff\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/uevent', 0o644, b'''INTERFACE=eth0
+IFINDEX=2
+''')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/mtu', 0o644, b'1500\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/broadcast', 0o644, b'ff:ff:ff:ff:ff:ff\n')
+d('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/tx_aborted_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/rx_crc_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/rx_bytes', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/rx_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/tx_packets', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/tx_carrier_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/tx_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/rx_dropped', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/tx_fifo_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/rx_length_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/tx_dropped', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/rx_fifo_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/rx_missed_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/tx_window_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/collisions', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/rx_frame_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/rx_packets', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/rx_compressed', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/tx_compressed', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/multicast', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/rx_over_errors', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/tx_bytes', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/statistics/tx_heartbeat_errors', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.0/0000:00:1c.0:pcie00', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.0/0000:00:1c.0:pcie00/subsystem', '../../../../bus/pci_express')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:00:1c.0:pcie00/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1c.0/0000:00:1c.0:pcie00/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:00:1c.0:pcie00/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1c.0/0000:00:1c.0:pcie02', 0o755)
+l('sys/devices/pci0000:00/0000:00:1c.0/0000:00:1c.0:pcie02/subsystem', '../../../../bus/pci_express')
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:00:1c.0:pcie02/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1c.0/0000:00:1c.0:pcie02/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1c.0/0000:00:1c.0:pcie02/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.3', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.3/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:18')
+l('sys/devices/pci0000:00/0000:00:1f.3/subsystem', '../../../bus/pci')
+f('sys/devices/pci0000:00/0000:00:1f.3/local_cpulist', 0o644, b'0-7\n')
+f('sys/devices/pci0000:00/0000:00:1f.3/enable', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.3/modalias', 0o644, b'pci:v00008086d000027DAsv000017AAsd0000200Fbc0Csc05i00\n')
+f('sys/devices/pci0000:00/0000:00:1f.3/resource', 0o644, b'''0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x00000000000018e0 0x00000000000018ff 0x0000000000020101
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+''')
+f('sys/devices/pci0000:00/0000:00:1f.3/config', 0o644, b"\x86\x80\xda'\x01\x01\x80\x02\x02\x00\x05\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x17\x0f \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x0f\x02\x00\x00\x00\x00\x00")
+f('sys/devices/pci0000:00/0000:00:1f.3/local_cpus', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1f.3/subsystem_device', 0o644, b'0x200f\n')
+f('sys/devices/pci0000:00/0000:00:1f.3/vendor', 0o644, b'0x8086\n')
+f('sys/devices/pci0000:00/0000:00:1f.3/irq', 0o644, b'11\n')
+f('sys/devices/pci0000:00/0000:00:1f.3/device', 0o644, b'0x27da\n')
+f('sys/devices/pci0000:00/0000:00:1f.3/class', 0o644, b'0x0c0500\n')
+f('sys/devices/pci0000:00/0000:00:1f.3/msi_bus', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.3/subsystem_vendor', 0o644, b'0x17aa\n')
+f('sys/devices/pci0000:00/0000:00:1f.3/uevent', 0o644, b'''PCI_CLASS=C0500
+PCI_ID=8086:27DA
+PCI_SUBSYS_ID=17AA:200F
+PCI_SLOT_NAME=0000:00:1f.3
+MODALIAS=pci:v00008086d000027DAsv000017AAsd0000200Fbc0Csc05i00
+''')
+f('sys/devices/pci0000:00/0000:00:1f.3/resource4', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.3/broken_parity_status', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1f.3/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.3/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.0/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:19')
+l('sys/devices/pci0000:00/0000:00:1d.0/subsystem', '../../../bus/pci')
+l('sys/devices/pci0000:00/0000:00:1d.0/driver', '../../../bus/pci/drivers/uhci_hcd')
+f('sys/devices/pci0000:00/0000:00:1d.0/local_cpulist', 0o644, b'0-7\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/enable', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/modalias', 0o644, b'pci:v00008086d000027C8sv000017AAsd0000200Abc0Csc03i00\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/resource', 0o644, b'''0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000001800 0x000000000000181f 0x0000000000020101
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+''')
+f('sys/devices/pci0000:00/0000:00:1d.0/config', 0o644, b"\x86\x80\xc8'\x05\x00\x80\x02\x02\x00\x03\x0c\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x17\n \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x0f\x02\x00\x00\x00\x00\x00")
+f('sys/devices/pci0000:00/0000:00:1d.0/local_cpus', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/subsystem_device', 0o644, b'0x200a\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/vendor', 0o644, b'0x8086\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/irq', 0o644, b'16\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/pools', 0o644, b'''poolinfo - 0.1
+uhci_qh 11 32 128 1
+uhci_td 1 64 64 1
+buffer-2048 0 0 2048 0
+buffer-512 0 0 512 0
+buffer-128 0 0 128 0
+buffer-32 1 128 32 1
+''')
+f('sys/devices/pci0000:00/0000:00:1d.0/device', 0o644, b'0x27c8\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/class', 0o644, b'0x0c0300\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/msi_bus', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1d.0/subsystem_vendor', 0o644, b'0x17aa\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/uevent', 0o644, b'''DRIVER=uhci_hcd
+PCI_CLASS=C0300
+PCI_ID=8086:27C8
+PCI_SUBSYS_ID=17AA:200A
+PCI_SLOT_NAME=0000:00:1d.0
+MODALIAS=pci:v00008086d000027C8sv000017AAsd0000200Abc0Csc03i00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.0/resource4', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1d.0/broken_parity_status', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1d.0/usb1', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.0/usb1/subsystem', '../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.0/usb1/driver', '../../../../bus/usb/drivers/usb')
+l('sys/devices/pci0000:00/0000:00:1d.0/usb1/ep_00', 'usb_endpoint/usbdev1.1_ep00')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/version', 0o644, b' 1.10\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/authorized_default', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/maxchild', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/bDeviceClass', 0o644, b'09\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/bcdDevice', 0o644, b'0206\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/devnum', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/bDeviceProtocol', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/idProduct', 0o644, b'0001\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/product', 0o644, b'UHCI Host Controller\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/bDeviceSubClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/configuration', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/dev', 0o644, b'189:0\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/urbnum', 0o644, b'16\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/authorized', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/descriptors', 0o644, b'\x12\x01\x10\x01\t\x00\x00@k\x1d\x01\x00\x06\x02\x03\x02\x01\x01\t\x02\x19\x00\x01\x01\x00\xe0\x00\t\x04\x00\x00\x01\t\x00\x00\x00\x07\x05\x81\x03\x02\x00\xff')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/bNumConfigurations', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/serial', 0o644, b'0000:00:1d.0\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/speed', 0o644, b'12\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/bMaxPacketSize0', 0o644, b'64\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/bmAttributes', 0o644, b'e0\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/busnum', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/quirks', 0o644, b'0x0\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/bConfigurationValue', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/uevent', 0o644, b'''MAJOR=189
+MINOR=0
+DEVTYPE=usb_device
+DRIVER=usb
+PRODUCT=1d6b/1/206
+TYPE=9/0/0
+BUSNUM=001
+DEVNUM=001
+''')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/manufacturer', 0o644, b'Linux 2.6.27-rc7-00106-g6ef190c-dirty uhci_hcd\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/idVendor', 0o644, b'1d6b\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/bNumInterfaces', 0o644, b' 1\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/bMaxPower', 0o644, b' 0mA\n')
+d('sys/devices/pci0000:00/0000:00:1d.0/usb1/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.0/usb1/usb_endpoint/usbdev1.1_ep00', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.0/usb1/usb_endpoint/usbdev1.1_ep00/subsystem', '../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.0/usb1/usb_endpoint/usbdev1.1_ep00/device', '../../../usb1')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/usb_endpoint/usbdev1.1_ep00/interval', 0o644, b'0ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/usb_endpoint/usbdev1.1_ep00/bEndpointAddress', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/usb_endpoint/usbdev1.1_ep00/type', 0o644, b'Control\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/usb_endpoint/usbdev1.1_ep00/dev', 0o644, b'252:1\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/usb_endpoint/usbdev1.1_ep00/direction', 0o644, b'both\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/usb_endpoint/usbdev1.1_ep00/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/usb_endpoint/usbdev1.1_ep00/wMaxPacketSize', 0o644, b'0040\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/usb_endpoint/usbdev1.1_ep00/bmAttributes', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/usb_endpoint/usbdev1.1_ep00/uevent', 0o644, b'''MAJOR=252
+MINOR=1
+''')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/usb_endpoint/usbdev1.1_ep00/bInterval', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.0/usb1/usb_endpoint/usbdev1.1_ep00/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/usb_endpoint/usbdev1.1_ep00/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/subsystem', '../../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/ep_81', 'usb_endpoint/usbdev1.1_ep81')
+l('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/driver', '../../../../../bus/usb/drivers/hub')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/modalias', 0o644, b'usb:v1D6Bp0001d0206dc09dsc00dp00ic09isc00ip00\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/bInterfaceNumber', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/bNumEndpoints', 0o644, b'01\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/bInterfaceSubClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/bInterfaceClass', 0o644, b'09\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/uevent', 0o644, b'''DEVTYPE=usb_interface
+DRIVER=hub
+PRODUCT=1d6b/1/206
+TYPE=9/0/0
+INTERFACE=9/0/0
+MODALIAS=usb:v1D6Bp0001d0206dc09dsc00dp00ic09isc00ip00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/bInterfaceProtocol', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/usb_endpoint/usbdev1.1_ep81', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/usb_endpoint/usbdev1.1_ep81/subsystem', '../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/usb_endpoint/usbdev1.1_ep81/device', '../../../1-0:1.0')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/usb_endpoint/usbdev1.1_ep81/interval', 0o644, b'255ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/usb_endpoint/usbdev1.1_ep81/bEndpointAddress', 0o644, b'81\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/usb_endpoint/usbdev1.1_ep81/type', 0o644, b'Interrupt\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/usb_endpoint/usbdev1.1_ep81/dev', 0o644, b'252:0\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/usb_endpoint/usbdev1.1_ep81/direction', 0o644, b'in\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/usb_endpoint/usbdev1.1_ep81/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/usb_endpoint/usbdev1.1_ep81/wMaxPacketSize', 0o644, b'0002\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/usb_endpoint/usbdev1.1_ep81/bmAttributes', 0o644, b'03\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/usb_endpoint/usbdev1.1_ep81/uevent', 0o644, b'''MAJOR=252
+MINOR=0
+''')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/usb_endpoint/usbdev1.1_ep81/bInterval', 0o644, b'ff\n')
+d('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/usb_endpoint/usbdev1.1_ep81/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/usb_endpoint/usbdev1.1_ep81/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/1-0:1.0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.0/usb1/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/power/active_duration', 0o644, b'2532\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/power/wakeup', 0o644, b'enabled\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/power/connected_duration', 0o644, b'8372376\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/power/autosuspend', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb1/power/level', 0o644, b'auto\n')
+d('sys/devices/pci0000:00/0000:00:1d.0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.0/power/wakeup', 0o644, b'disabled\n')
+d('sys/devices/pci0000:00/0000:00:1d.0/usb_host', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.0/usb_host/usb_host1', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.0/usb_host/usb_host1/subsystem', '../../../../../class/usb_host')
+l('sys/devices/pci0000:00/0000:00:1d.0/usb_host/usb_host1/device', '../../../0000:00:1d.0')
+f('sys/devices/pci0000:00/0000:00:1d.0/usb_host/usb_host1/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1d.0/usb_host/usb_host1/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.0/usb_host/usb_host1/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.2', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:16')
+l('sys/devices/pci0000:00/0000:00:1f.2/subsystem', '../../../bus/pci')
+l('sys/devices/pci0000:00/0000:00:1f.2/driver', '../../../bus/pci/drivers/ahci')
+f('sys/devices/pci0000:00/0000:00:1f.2/local_cpulist', 0o644, b'0-7\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/resource3', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.2/enable', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/modalias', 0o644, b'pci:v00008086d000027C5sv000017AAsd0000200Dbc01sc06i01\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/resource', 0o644, b'''0x00000000000018c8 0x00000000000018cf 0x0000000000020101
+0x00000000000018ac 0x00000000000018af 0x0000000000020101
+0x00000000000018c0 0x00000000000018c7 0x0000000000020101
+0x00000000000018a8 0x00000000000018ab 0x0000000000020101
+0x00000000000018b0 0x00000000000018bf 0x0000000000020101
+0x00000000ee404400 0x00000000ee4047ff 0x0000000000020200
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+''')
+f('sys/devices/pci0000:00/0000:00:1f.2/config', 0o644, b"\x86\x80\xc5'\x07\x04\xb0\x02\x02\x01\x06\x01\x00\x00\x00\x00\xc9\x18\x00\x00\xad\x18\x00\x00\xc1\x18\x00\x00\xa9\x18\x00\x00\xb1\x18\x00\x00\x00D@\xee\x00\x00\x00\x00\xaa\x17\r \x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x0b\x02\x00\x00\x07\xa3\x00\x80\x00\x00\x00\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05p\x01\x00\x0c0\xe0\xfe\x99A\x00\x00\x00\x00\x00\x00@\x00\x11\x10\x80\x01\x00J\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x0f\x02\x00\x00\x00\x00\x00")
+f('sys/devices/pci0000:00/0000:00:1f.2/resource1', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.2/resource2', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.2/local_cpus', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/subsystem_device', 0o644, b'0x200d\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/vendor', 0o644, b'0x8086\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/irq', 0o644, b'506\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/device', 0o644, b'0x27c5\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/class', 0o644, b'0x010601\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/resource5', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.2/msi_bus', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.2/resource0', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.2/subsystem_vendor', 0o644, b'0x17aa\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/uevent', 0o644, b'''DRIVER=ahci
+PCI_CLASS=10601
+PCI_ID=8086:27C5
+PCI_SUBSYS_ID=17AA:200D
+PCI_SLOT_NAME=0000:00:1f.2
+MODALIAS=pci:v00008086d000027C5sv000017AAsd0000200Dbc01sc06i01
+''')
+f('sys/devices/pci0000:00/0000:00:1f.2/resource4', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.2/broken_parity_status', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/subsystem', '../../../../bus/scsi')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/uevent', 0o644, b'DEVTYPE=scsi_host\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/subsystem', '../../../../../bus/scsi')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/uevent', 0o644, b'DEVTYPE=scsi_target\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/generic', 'scsi_generic/sg0')
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/subsystem', '../../../../../../bus/scsi')
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/driver', '../../../../../../bus/scsi/drivers/sd')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/iodone_cnt', 0o644, b'0x6877\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/device_blocked', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/modalias', 0o644, b'scsi:t-0x00\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_level', 0o644, b'6\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/queue_depth', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/rev', 0o644, b'4.06\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/type', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/sw_activity', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/whitespace_test', 0o644, b'WHITE SPACE \n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/iocounterbits', 0o644, b'32\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/vendor', 0o644, b'ATA \n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/state', 0o644, b'running\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/queue_type', 0o644, b'none\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/iorequest_cnt', 0o644, b'0x6877\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/evt_media_change', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/model', 0o644, b'ST910021AS \n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/ioerr_cnt', 0o644, b'0x6\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/uevent', 0o644, b'''DEVTYPE=scsi_device
+DRIVER=sd
+MODALIAS=scsi:t-0x00
+''')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/timeout', 0o644, b'60\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_disk', 0o755)
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0/subsystem', '../../../../../../../../class/scsi_disk')
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0/device', '../../../0:0:0:0')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0/app_tag_own', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0/FUA', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0/cache_type', 0o644, b'write back\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0/protection_type', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0/manage_start_stop', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0/allow_restart', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_generic', 0o755)
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_generic/sg0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_generic/sg0/subsystem', '../../../../../../../../class/scsi_generic')
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_generic/sg0/device', '../../../0:0:0:0')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_generic/sg0/dev', 0o644, b'21:0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_generic/sg0/uevent', 0o644, b'''MAJOR=21
+MINOR=0
+''')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_generic/sg0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_generic/sg0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/bsg', 0o755)
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0/subsystem', '../../../../../../../../class/bsg')
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0/device', '../../../0:0:0:0')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0/dev', 0o644, b'254:0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0/uevent', 0o644, b'''MAJOR=254
+MINOR=0
+''')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block', 0o755)
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/subsystem', '../../../../../../../../class/block')
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/bdi', '../../../../../../../virtual/bdi/8:0')
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/device', '../../../0:0:0:0')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/capability', 0o644, b'12\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/ro', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/make-it-fail', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/test:colon+plus', 0o644, b'colon\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/size', 0o644, b'195371568\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/dev', 0o644, b'8:0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/range', 0o644, b'16\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/removable', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/stat', 0o644, b' 12939 5801 590192 194190 13755 63323 617056 2678026 0 114408 2872209\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/uevent', 0o644, b'''MAJOR=8
+MINOR=0
+DEVTYPE=disk
+DEVNAME=sda
+''')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/test_empty_file', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/queue', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/queue/bsg', '../../../bsg/0:0:0:0')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/queue/nr_requests', 0o644, b'128\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/queue/nomerges', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/queue/scheduler', 0o644, b'noop anticipatory deadline [cfq] \n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/queue/hw_sector_size', 0o644, b'512\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/queue/max_hw_sectors_kb', 0o644, b'32767\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/queue/read_ahead_kb', 0o644, b'128\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/queue/max_sectors_kb', 0o644, b'512\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/queue/iosched', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/queue/iosched/slice_async_rq', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/queue/iosched/back_seek_max', 0o644, b'16384\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/queue/iosched/slice_sync', 0o644, b'100\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/queue/iosched/slice_async', 0o644, b'40\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/queue/iosched/fifo_expire_sync', 0o644, b'125\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/queue/iosched/slice_idle', 0o644, b'8\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/queue/iosched/back_seek_penalty', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/queue/iosched/fifo_expire_async', 0o644, b'250\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/queue/iosched/quantum', 0o644, b'4\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10/subsystem', '../../../../../../../../../class/block')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10/start', 0o644, b'190820133\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10/make-it-fail', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10/size', 0o644, b'4546332\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10/dev', 0o644, b'8:10\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10/stat', 0o644, b' 42 43 384 417 0 0 0 0 0 286 417\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10/uevent', 0o644, b'''MAJOR=8
+MINOR=10
+DEVTYPE=partition
+''')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9/subsystem', '../../../../../../../../../class/block')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9/start', 0o644, b'143942463\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9/make-it-fail', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9/size', 0o644, b'46877607\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9/dev', 0o644, b'8:9\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9/stat', 0o644, b' 70 322 896 800 3 0 40 240 0 945 1039\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9/uevent', 0o644, b'''MAJOR=8
+MINOR=9
+DEVTYPE=partition
+''')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9/holders', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9/holders/md0', '../../../../../../../../../virtual/block/md0')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7/subsystem', '../../../../../../../../../class/block')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7/start', 0o644, b'104872383\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7/make-it-fail', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7/size', 0o644, b'19534977\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7/dev', 0o644, b'8:7\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7/stat', 0o644, b' 35 263 298 419 0 0 0 0 0 298 419\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7/uevent', 0o644, b'''MAJOR=8
+MINOR=7
+DEVTYPE=partition
+''')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1/subsystem', '../../../../../../../../../class/block')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1/start', 0o644, b'63\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1/make-it-fail', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1/size', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1/dev', 0o644, b'8:1\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1/stat', 0o644, b' 2 0 4 36 0 0 0 0 0 36 36\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1/uevent', 0o644, b'''MAJOR=8
+MINOR=1
+DEVTYPE=partition
+DEVNAME=sda1
+''')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8/subsystem', '../../../../../../../../../class/block')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8/start', 0o644, b'124407423\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8/make-it-fail', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8/size', 0o644, b'19534977\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8/dev', 0o644, b'8:8\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8/stat', 0o644, b' 34 264 298 498 0 0 0 0 0 368 498\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8/uevent', 0o644, b'''MAJOR=8
+MINOR=8
+DEVTYPE=partition
+''')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5/subsystem', '../../../../../../../../../class/block')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5/start', 0o644, b'126\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5/make-it-fail', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5/size', 0o644, b'62926479\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5/dev', 0o644, b'8:5\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5/stat', 0o644, b' 11087 4819 566626 169007 2951 4548 59992 129572 0 65249 298573\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5/uevent', 0o644, b'''MAJOR=8
+MINOR=5
+DEVTYPE=partition
+DEVNAME=sda5
+''')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6/subsystem', '../../../../../../../../../class/block')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6/start', 0o644, b'62926668\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6/make-it-fail', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6/size', 0o644, b'41945652\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6/dev', 0o644, b'8:6\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6/stat', 0o644, b' 1648 67 21334 22824 10801 58775 557024 2548214 0 51231 2571037\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6/uevent', 0o644, b'''MAJOR=8
+MINOR=6
+DEVTYPE=partition
+''')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_device', 0o755)
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_device/0:0:0:0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_device/0:0:0:0/subsystem', '../../../../../../../../class/scsi_device')
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_device/0:0:0:0/device', '../../../0:0:0:0')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_device/0:0:0:0/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_device/0:0:0:0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/scsi_device/0:0:0:0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host', 0o755)
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0/subsystem', '../../../../../../class/scsi_host')
+l('sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0/device', '../../../host0')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0/unique_id', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0/can_queue', 0o644, b'31\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0/unchecked_isa_dma', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0/active_mode', 0o644, b'Initiator\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0/sg_tablesize', 0o644, b'168\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0/prot_guard_type', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0/link_power_management_policy', 0o644, b'medium_power\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0/host_busy', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0/proc_name', 0o644, b'ahci\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0/state', 0o644, b'running\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0/cmd_per_lun', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0/em_message', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0/em_message_type', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0/supported_mode', 0o644, b'Initiator\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0/uevent', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0/prot_capabilities', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/power/wakeup', 0o644, b'disabled\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host1', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host1/subsystem', '../../../../bus/scsi')
+f('sys/devices/pci0000:00/0000:00:1f.2/host1/uevent', 0o644, b'DEVTYPE=scsi_host\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host1/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host1/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host', 0o755)
+d('sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1/subsystem', '../../../../../../class/scsi_host')
+l('sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1/device', '../../../host1')
+f('sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1/unique_id', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1/can_queue', 0o644, b'31\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1/unchecked_isa_dma', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1/active_mode', 0o644, b'Initiator\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1/sg_tablesize', 0o644, b'168\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1/prot_guard_type', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1/link_power_management_policy', 0o644, b'max_performance\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1/host_busy', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1/proc_name', 0o644, b'ahci\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1/state', 0o644, b'running\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1/cmd_per_lun', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1/em_message', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1/em_message_type', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1/supported_mode', 0o644, b'Initiator\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1/uevent', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1/prot_capabilities', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host2', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host2/subsystem', '../../../../bus/scsi')
+f('sys/devices/pci0000:00/0000:00:1f.2/host2/uevent', 0o644, b'DEVTYPE=scsi_host\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host2/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host2/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host', 0o755)
+d('sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2/subsystem', '../../../../../../class/scsi_host')
+l('sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2/device', '../../../host2')
+f('sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2/unique_id', 0o644, b'3\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2/can_queue', 0o644, b'31\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2/unchecked_isa_dma', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2/active_mode', 0o644, b'Initiator\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2/sg_tablesize', 0o644, b'168\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2/prot_guard_type', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2/link_power_management_policy', 0o644, b'max_performance\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2/host_busy', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2/proc_name', 0o644, b'ahci\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2/state', 0o644, b'running\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2/cmd_per_lun', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2/em_message', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2/em_message_type', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2/supported_mode', 0o644, b'Initiator\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2/uevent', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2/prot_capabilities', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host3', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host3/subsystem', '../../../../bus/scsi')
+f('sys/devices/pci0000:00/0000:00:1f.2/host3/uevent', 0o644, b'DEVTYPE=scsi_host\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host3/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host3/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host', 0o755)
+d('sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/subsystem', '../../../../../../class/scsi_host')
+l('sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/device', '../../../host3')
+f('sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/unique_id', 0o644, b'4\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/can_queue', 0o644, b'31\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/unchecked_isa_dma', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/active_mode', 0o644, b'Initiator\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/sg_tablesize', 0o644, b'168\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/prot_guard_type', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/link_power_management_policy', 0o644, b'max_performance\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/host_busy', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/proc_name', 0o644, b'ahci\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/state', 0o644, b'running\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/cmd_per_lun', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/em_message', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/em_message_type', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/supported_mode', 0o644, b'Initiator\n')
+f('sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/uevent', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/prot_capabilities', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.2', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.2/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:1d')
+l('sys/devices/pci0000:00/0000:00:1d.2/subsystem', '../../../bus/pci')
+l('sys/devices/pci0000:00/0000:00:1d.2/driver', '../../../bus/pci/drivers/uhci_hcd')
+f('sys/devices/pci0000:00/0000:00:1d.2/local_cpulist', 0o644, b'0-7\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/enable', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/modalias', 0o644, b'pci:v00008086d000027CAsv000017AAsd0000200Abc0Csc03i00\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/resource', 0o644, b'''0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000001840 0x000000000000185f 0x0000000000020101
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+''')
+f('sys/devices/pci0000:00/0000:00:1d.2/config', 0o644, b"\x86\x80\xca'\x05\x00\x80\x02\x02\x00\x03\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00A\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x17\n \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x0f\x02\x00\x00\x00\x00\x00")
+f('sys/devices/pci0000:00/0000:00:1d.2/local_cpus', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/subsystem_device', 0o644, b'0x200a\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/vendor', 0o644, b'0x8086\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/irq', 0o644, b'18\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/pools', 0o644, b'''poolinfo - 0.1
+uhci_qh 13 32 128 1
+uhci_td 4 64 64 1
+buffer-2048 0 0 2048 0
+buffer-512 0 0 512 0
+buffer-128 3 32 128 1
+buffer-32 2 128 32 1
+''')
+f('sys/devices/pci0000:00/0000:00:1d.2/device', 0o644, b'0x27ca\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/class', 0o644, b'0x0c0300\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/msi_bus', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1d.2/subsystem_vendor', 0o644, b'0x17aa\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/uevent', 0o644, b'''DRIVER=uhci_hcd
+PCI_CLASS=C0300
+PCI_ID=8086:27CA
+PCI_SUBSYS_ID=17AA:200A
+PCI_SLOT_NAME=0000:00:1d.2
+MODALIAS=pci:v00008086d000027CAsv000017AAsd0000200Abc0Csc03i00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.2/resource4', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1d.2/broken_parity_status', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.2/power/wakeup', 0o644, b'disabled\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb_host', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.2/usb_host/usb_host3', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.2/usb_host/usb_host3/subsystem', '../../../../../class/usb_host')
+l('sys/devices/pci0000:00/0000:00:1d.2/usb_host/usb_host3/device', '../../../0000:00:1d.2')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb_host/usb_host3/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb_host/usb_host3/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.2/usb_host/usb_host3/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/subsystem', '../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/driver', '../../../../bus/usb/drivers/usb')
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/ep_00', 'usb_endpoint/usbdev3.1_ep00')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/version', 0o644, b' 1.10\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/authorized_default', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/maxchild', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/bDeviceClass', 0o644, b'09\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/bcdDevice', 0o644, b'0206\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/devnum', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/bDeviceProtocol', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/idProduct', 0o644, b'0001\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/product', 0o644, b'UHCI Host Controller\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/bDeviceSubClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/configuration', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/dev', 0o644, b'189:256\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/urbnum', 0o644, b'68\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/authorized', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/descriptors', 0o644, b'\x12\x01\x10\x01\t\x00\x00@k\x1d\x01\x00\x06\x02\x03\x02\x01\x01\t\x02\x19\x00\x01\x01\x00\xe0\x00\t\x04\x00\x00\x01\t\x00\x00\x00\x07\x05\x81\x03\x02\x00\xff')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/bNumConfigurations', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/serial', 0o644, b'0000:00:1d.2\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/speed', 0o644, b'12\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/bMaxPacketSize0', 0o644, b'64\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/bmAttributes', 0o644, b'e0\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/busnum', 0o644, b'3\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/quirks', 0o644, b'0x0\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/bConfigurationValue', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/uevent', 0o644, b'''MAJOR=189
+MINOR=256
+DEVTYPE=usb_device
+DRIVER=usb
+PRODUCT=1d6b/1/206
+TYPE=9/0/0
+BUSNUM=003
+DEVNUM=001
+''')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/manufacturer', 0o644, b'Linux 2.6.27-rc7-00106-g6ef190c-dirty uhci_hcd\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/idVendor', 0o644, b'1d6b\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/bNumInterfaces', 0o644, b' 1\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/bMaxPower', 0o644, b' 0mA\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/usb_endpoint/usbdev3.1_ep00', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/usb_endpoint/usbdev3.1_ep00/subsystem', '../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/usb_endpoint/usbdev3.1_ep00/device', '../../../usb3')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/usb_endpoint/usbdev3.1_ep00/interval', 0o644, b'0ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/usb_endpoint/usbdev3.1_ep00/bEndpointAddress', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/usb_endpoint/usbdev3.1_ep00/type', 0o644, b'Control\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/usb_endpoint/usbdev3.1_ep00/dev', 0o644, b'252:5\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/usb_endpoint/usbdev3.1_ep00/direction', 0o644, b'both\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/usb_endpoint/usbdev3.1_ep00/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/usb_endpoint/usbdev3.1_ep00/wMaxPacketSize', 0o644, b'0040\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/usb_endpoint/usbdev3.1_ep00/bmAttributes', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/usb_endpoint/usbdev3.1_ep00/uevent', 0o644, b'''MAJOR=252
+MINOR=5
+''')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/usb_endpoint/usbdev3.1_ep00/bInterval', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/usb_endpoint/usbdev3.1_ep00/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/usb_endpoint/usbdev3.1_ep00/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/subsystem', '../../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/ep_81', 'usb_endpoint/usbdev3.1_ep81')
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/driver', '../../../../../bus/usb/drivers/hub')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/modalias', 0o644, b'usb:v1D6Bp0001d0206dc09dsc00dp00ic09isc00ip00\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/bInterfaceNumber', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/bNumEndpoints', 0o644, b'01\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/bInterfaceSubClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/bInterfaceClass', 0o644, b'09\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/uevent', 0o644, b'''DEVTYPE=usb_interface
+DRIVER=hub
+PRODUCT=1d6b/1/206
+TYPE=9/0/0
+INTERFACE=9/0/0
+MODALIAS=usb:v1D6Bp0001d0206dc09dsc00dp00ic09isc00ip00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/bInterfaceProtocol', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/usb_endpoint/usbdev3.1_ep81', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/usb_endpoint/usbdev3.1_ep81/subsystem', '../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/usb_endpoint/usbdev3.1_ep81/device', '../../../3-0:1.0')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/usb_endpoint/usbdev3.1_ep81/interval', 0o644, b'255ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/usb_endpoint/usbdev3.1_ep81/bEndpointAddress', 0o644, b'81\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/usb_endpoint/usbdev3.1_ep81/type', 0o644, b'Interrupt\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/usb_endpoint/usbdev3.1_ep81/dev', 0o644, b'252:4\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/usb_endpoint/usbdev3.1_ep81/direction', 0o644, b'in\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/usb_endpoint/usbdev3.1_ep81/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/usb_endpoint/usbdev3.1_ep81/wMaxPacketSize', 0o644, b'0002\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/usb_endpoint/usbdev3.1_ep81/bmAttributes', 0o644, b'03\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/usb_endpoint/usbdev3.1_ep81/uevent', 0o644, b'''MAJOR=252
+MINOR=4
+''')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/usb_endpoint/usbdev3.1_ep81/bInterval', 0o644, b'ff\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/usb_endpoint/usbdev3.1_ep81/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/usb_endpoint/usbdev3.1_ep81/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-0:1.0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/power/active_duration', 0o644, b'603809\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/power/wakeup', 0o644, b'enabled\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/power/connected_duration', 0o644, b'8372166\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/power/autosuspend', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/power/level', 0o644, b'auto\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/subsystem', '../../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/driver', '../../../../../bus/usb/drivers/usb')
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/ep_00', 'usb_endpoint/usbdev3.4_ep00')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/version', 0o644, b' 2.00\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/maxchild', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/bDeviceClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/bcdDevice', 0o644, b'2000\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/devnum', 0o644, b'4\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/bDeviceProtocol', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/idProduct', 0o644, b'c03e\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/product', 0o644, b'USB-PS/2 Optical Mouse\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/bDeviceSubClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/configuration', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/dev', 0o644, b'189:259\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/urbnum', 0o644, b'12\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/authorized', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/descriptors', 0o644, b'\x12\x01\x00\x02\x00\x00\x00\x08m\x04>\xc0\x00 \x01\x02\x00\x01\t\x02"\x00\x01\x01\x00\xa01\t\x04\x00\x00\x01\x03\x01\x02\x00\t!\x10\x01\x00\x01"2\x00\x07\x05\x81\x03\x04\x00\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/bNumConfigurations', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/speed', 0o644, b'1.5\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/bMaxPacketSize0', 0o644, b'8\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/bmAttributes', 0o644, b'a0\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/busnum', 0o644, b'3\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/quirks', 0o644, b'0x0\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/bConfigurationValue', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/uevent', 0o644, b'''MAJOR=189
+MINOR=259
+DEVTYPE=usb_device
+DRIVER=usb
+PRODUCT=46d/c03e/2000
+TYPE=0/0/0
+BUSNUM=003
+DEVNUM=004
+''')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/manufacturer', 0o644, b'Logitech\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/idVendor', 0o644, b'046d\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/bNumInterfaces', 0o644, b' 1\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/bMaxPower', 0o644, b' 98mA\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/usb_endpoint/usbdev3.4_ep00', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/usb_endpoint/usbdev3.4_ep00/subsystem', '../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/usb_endpoint/usbdev3.4_ep00/device', '../../../3-1')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/usb_endpoint/usbdev3.4_ep00/interval', 0o644, b'0ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/usb_endpoint/usbdev3.4_ep00/bEndpointAddress', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/usb_endpoint/usbdev3.4_ep00/type', 0o644, b'Control\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/usb_endpoint/usbdev3.4_ep00/dev', 0o644, b'252:26\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/usb_endpoint/usbdev3.4_ep00/direction', 0o644, b'both\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/usb_endpoint/usbdev3.4_ep00/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/usb_endpoint/usbdev3.4_ep00/wMaxPacketSize', 0o644, b'0008\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/usb_endpoint/usbdev3.4_ep00/bmAttributes', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/usb_endpoint/usbdev3.4_ep00/uevent', 0o644, b'''MAJOR=252
+MINOR=26
+''')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/usb_endpoint/usbdev3.4_ep00/bInterval', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/usb_endpoint/usbdev3.4_ep00/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/usb_endpoint/usbdev3.4_ep00/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/power/active_duration', 0o644, b'51384\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/power/wakeup', 0o644, b'enabled\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/power/connected_duration', 0o644, b'51383\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/power/autosuspend', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/power/persist', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/power/level', 0o644, b'on\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/subsystem', '../../../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/ep_81', 'usb_endpoint/usbdev3.4_ep81')
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/driver', '../../../../../../bus/usb/drivers/usbhid')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/modalias', 0o644, b'usb:v046DpC03Ed2000dc00dsc00dp00ic03isc01ip02\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/bInterfaceNumber', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/bNumEndpoints', 0o644, b'01\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/bInterfaceSubClass', 0o644, b'01\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/bInterfaceClass', 0o644, b'03\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/uevent', 0o644, b'''DEVTYPE=usb_interface
+DRIVER=usbhid
+PRODUCT=46d/c03e/2000
+TYPE=0/0/0
+INTERFACE=3/1/2
+MODALIAS=usb:v046DpC03Ed2000dc00dsc00dp00ic03isc01ip02
+''')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/bInterfaceProtocol', 0o644, b'02\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/usb_endpoint/usbdev3.4_ep81', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/usb_endpoint/usbdev3.4_ep81/subsystem', '../../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/usb_endpoint/usbdev3.4_ep81/device', '../../../3-1:1.0')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/usb_endpoint/usbdev3.4_ep81/interval', 0o644, b'10ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/usb_endpoint/usbdev3.4_ep81/bEndpointAddress', 0o644, b'81\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/usb_endpoint/usbdev3.4_ep81/type', 0o644, b'Interrupt\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/usb_endpoint/usbdev3.4_ep81/dev', 0o644, b'252:25\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/usb_endpoint/usbdev3.4_ep81/direction', 0o644, b'in\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/usb_endpoint/usbdev3.4_ep81/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/usb_endpoint/usbdev3.4_ep81/wMaxPacketSize', 0o644, b'0004\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/usb_endpoint/usbdev3.4_ep81/bmAttributes', 0o644, b'03\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/usb_endpoint/usbdev3.4_ep81/uevent', 0o644, b'''MAJOR=252
+MINOR=25
+''')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/usb_endpoint/usbdev3.4_ep81/bInterval', 0o644, b'0a\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/usb_endpoint/usbdev3.4_ep81/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/usb_endpoint/usbdev3.4_ep81/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/subsystem', '../../../../../../../../class/input')
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/device', '../../../3-1:1.0')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/uniq', 0o644, b'\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/phys', 0o644, b'usb-0000:00:1d.2-1/input0\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/modalias', 0o644, b'input:b0003v046DpC03Ee0110-e0,1,2,4,k110,111,112,r0,1,8,am4,lsfw\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/name', 0o644, b'Logitech USB-PS/2 Optical Mouse\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/uevent', 0o644, b'''PRODUCT=3/46d/c03e/110
+NAME="Logitech USB-PS/2 Optical Mouse"
+PHYS="usb-0000:00:1d.2-1/input0"
+UNIQ=""
+EV==17
+KEY==70000 0 0 0 0
+REL==103
+MSC==10
+MODALIAS=input:b0003v046DpC03Ee0110-e0,1,2,4,k110,111,112,r0,1,8,am4,lsfw
+''')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/mouse1', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/mouse1/subsystem', '../../../../../../../../../class/input')
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/mouse1/device', '../../input8')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/mouse1/dev', 0o644, b'13:33\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/mouse1/uevent', 0o644, b'''MAJOR=13
+MINOR=33
+''')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/mouse1/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/mouse1/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/id', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/id/version', 0o644, b'0110\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/id/product', 0o644, b'c03e\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/id/vendor', 0o644, b'046d\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/id/bustype', 0o644, b'0003\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/event7', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/event7/subsystem', '../../../../../../../../../class/input')
+l('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/event7/device', '../../input8')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/event7/dev', 0o644, b'13:71\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/event7/uevent', 0o644, b'''MAJOR=13
+MINOR=71
+''')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/event7/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/event7/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/capabilities', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/capabilities/msc', 0o644, b'10\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/capabilities/abs', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/capabilities/snd', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/capabilities/ff', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/capabilities/key', 0o644, b'70000 0 0 0 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/capabilities/rel', 0o644, b'103\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/capabilities/sw', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/capabilities/ev', 0o644, b'17\n')
+f('sys/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input8/capabilities/led', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:01.0', 0o755)
+l('sys/devices/pci0000:00/0000:00:01.0/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:06')
+l('sys/devices/pci0000:00/0000:00:01.0/subsystem', '../../../bus/pci')
+l('sys/devices/pci0000:00/0000:00:01.0/driver', '../../../bus/pci/drivers/pcieport-driver')
+f('sys/devices/pci0000:00/0000:00:01.0/local_cpulist', 0o644, b'0-7\n')
+f('sys/devices/pci0000:00/0000:00:01.0/enable', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:01.0/modalias', 0o644, b'pci:v00008086d000027A1sv00000000sd00000000bc06sc04i00\n')
+f('sys/devices/pci0000:00/0000:00:01.0/resource', 0o644, b'''0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000002000 0x0000000000002fff 0x0000000000000100
+0x00000000ee100000 0x00000000ee1fffff 0x0000000000000200
+0x00000000d0000000 0x00000000dfffffff 0x0000000000001201
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+''')
+f('sys/devices/pci0000:00/0000:00:01.0/config', 0o644, b'\x86\x80\xa1\'\x07\x05\x10\x00\x03\x00\x04\x06\x10\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00 \x00\x00\x10\xee\x10\xee\x01\xd0\xf1\xdf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\x00\x00\x00\x00\x00\x00\x00\x0b\x01\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x01\x90\x02\xc8\x00\x00\x00\x00\r\x80\x00\x00\xaa\x17\x14 \x05\xa0\x01\x00\x0c0\xe0\xfeqA\x00\x00\x00\x00\x00\x00\x10\x00A\x01\x00\x00\x00\x00\x00\x00\x01\x00\x01M\x01\x02\x03\x00\x01\x11\x80%\x08\x00\xc0\x01H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x0f\x00\x00\x00\x00\x86\x0f\x05\x00\x00\x00\x00\x80\x02\x00\x01\x14\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x80\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x01\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x01\x00\x00\x01\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x90\xd1\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x06\x00\x01\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x7f \x08\xf4\x0c\x00\x00\xb04 \x00\x00\x00\x00\x003\x0f\x00\x00\xff\xff\x03\x00\xd0\x0f\xf1\x05\xd1\x0f\xd1\x0f\x08\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00\r/B\x00\x0c\x00\x00\x14\xb5\xbcJ\xbc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x0b\xe0\x00Q\x0b\xfe\x00 \x00\x08\x00\x85\x03\xf1\x00\x87\x03\xf3\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x04\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x14\x08\x88\x00\x00\x00\x00\x00\x00\x00\x00"wD\xb23\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x06`\x00 \x00\x00`\x02\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x06b\x00 \x00\x00`\x02\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\n\x06`\x00 \x00\x00`\x02\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\r\x06b\x00 \x00\x00`\x02\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x06`\x00 \x00\x00`\x02\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x06b\x00 \x00\x00`\x02\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x003\x06`\x00 \x00\x00`\x02\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x004\x06b\x00 \x00\x00`\x02\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x06`\x00 \x00\x00`\x02\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x002\x06b\x00 \x00\x00`\x02\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x004\x06`\x00 \x00\x00`\x02\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x002\x06b\x00 \x00\x00`\x02\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00;\x06`\x00 \x00\x00`\x02\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x003\x06b\x00 \x00\x00`\x02\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x009\x06`\x00 \x00\x00`\x02\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00:\x06b\x00 \x00\x00`\x02\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x007')
+f('sys/devices/pci0000:00/0000:00:01.0/local_cpus', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:01.0/subsystem_device', 0o644, b'0x0000\n')
+f('sys/devices/pci0000:00/0000:00:01.0/vendor', 0o644, b'0x8086\n')
+f('sys/devices/pci0000:00/0000:00:01.0/irq', 0o644, b'511\n')
+f('sys/devices/pci0000:00/0000:00:01.0/device', 0o644, b'0x27a1\n')
+f('sys/devices/pci0000:00/0000:00:01.0/class', 0o644, b'0x060400\n')
+f('sys/devices/pci0000:00/0000:00:01.0/msi_bus', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:01.0/subsystem_vendor', 0o644, b'0x0000\n')
+f('sys/devices/pci0000:00/0000:00:01.0/uevent', 0o644, b'''DRIVER=pcieport-driver
+PCI_CLASS=60400
+PCI_ID=8086:27A1
+PCI_SUBSYS_ID=0000:0000
+PCI_SLOT_NAME=0000:00:01.0
+MODALIAS=pci:v00008086d000027A1sv00000000sd00000000bc06sc04i00
+''')
+f('sys/devices/pci0000:00/0000:00:01.0/broken_parity_status', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:01.0/pci_bus', 0o755)
+d('sys/devices/pci0000:00/0000:00:01.0/pci_bus/0000:01', 0o755)
+l('sys/devices/pci0000:00/0000:00:01.0/pci_bus/0000:01/subsystem', '../../../../../class/pci_bus')
+l('sys/devices/pci0000:00/0000:00:01.0/pci_bus/0000:01/device', '../../../0000:00:01.0')
+f('sys/devices/pci0000:00/0000:00:01.0/pci_bus/0000:01/cpuaffinity', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:01.0/pci_bus/0000:01/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:01.0/pci_bus/0000:01/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:01.0/pci_bus/0000:01/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:01.0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:01.0/power/wakeup', 0o644, b'disabled\n')
+d('sys/devices/pci0000:00/0000:00:01.0/0000:00:01.0:pcie03', 0o755)
+l('sys/devices/pci0000:00/0000:00:01.0/0000:00:01.0:pcie03/subsystem', '../../../../bus/pci_express')
+f('sys/devices/pci0000:00/0000:00:01.0/0000:00:01.0:pcie03/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:01.0/0000:00:01.0:pcie03/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:01.0/0000:00:01.0:pcie03/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0', 0o755)
+l('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/firmware_node', '../../../LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07')
+l('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/subsystem', '../../../../bus/pci')
+f('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/local_cpulist', 0o644, b'0-7\n')
+f('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/enable', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/modalias', 0o644, b'pci:v00001002d000071D4sv000017AAsd000020A4bc03sc00i00\n')
+f('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/resource', 0o644, b'''0x00000000d0000000 0x00000000dfffffff 0x0000000000021208
+0x0000000000002000 0x00000000000020ff 0x0000000000020101
+0x00000000ee100000 0x00000000ee10ffff 0x0000000000020200
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x00000000ee120000 0x00000000ee13ffff 0x0000000000027202
+''')
+f('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/config', 0o644, b'\x02\x10\xd4q\x07\x01\x10\x00\x00\x00\x00\x03\x10\x00\x00\x00\x08\x00\x00\xd0\x01 \x00\x00\x00\x00\x10\xee\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x17\xa4 \x00\x00\x00\x00P\x00\x00\x00\x00\x00\x00\x00\x0b\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x17\xa4 \x01X\x02\x06\x00\x00\x00\x00\x10\x80\x11\x00\xa0\x0f,\x01\x10\x08\x00\x00\x01\r\x00\x00C\x00\x01\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11 \x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00@\x03\x00\x00\x00$\x8f\x0b\x00\xff\xff\x07e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
+f('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/resource1', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/resource2', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/local_cpus', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/subsystem_device', 0o644, b'0x20a4\n')
+f('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/vendor', 0o644, b'0x1002\n')
+f('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/irq', 0o644, b'11\n')
+f('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/device', 0o644, b'0x71d4\n')
+f('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/class', 0o644, b'0x030000\n')
+f('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/rom', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/msi_bus', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/resource0', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/subsystem_vendor', 0o644, b'0x17aa\n')
+f('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/uevent', 0o644, b'''PCI_CLASS=30000
+PCI_ID=1002:71D4
+PCI_SUBSYS_ID=17AA:20A4
+PCI_SLOT_NAME=0000:01:00.0
+MODALIAS=pci:v00001002d000071D4sv000017AAsd000020A4bc03sc00i00
+''')
+f('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/resource0_wc', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/broken_parity_status', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:01.0/0000:00:01.0:pcie00', 0o755)
+l('sys/devices/pci0000:00/0000:00:01.0/0000:00:01.0:pcie00/subsystem', '../../../../bus/pci_express')
+f('sys/devices/pci0000:00/0000:00:01.0/0000:00:01.0:pcie00/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:01.0/0000:00:01.0:pcie00/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:01.0/0000:00:01.0:pcie00/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.1', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.1/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:13')
+l('sys/devices/pci0000:00/0000:00:1f.1/subsystem', '../../../bus/pci')
+l('sys/devices/pci0000:00/0000:00:1f.1/driver', '../../../bus/pci/drivers/ata_piix')
+f('sys/devices/pci0000:00/0000:00:1f.1/local_cpulist', 0o644, b'0-7\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/resource3', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.1/enable', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/modalias', 0o644, b'pci:v00008086d000027DFsv000017AAsd0000200Cbc01sc01i8a\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/resource', 0o644, b'''0x00000000000001f0 0x00000000000001f7 0x0000000000000110
+0x00000000000003f6 0x00000000000003f6 0x0000000000000110
+0x0000000000000170 0x0000000000000177 0x0000000000000110
+0x0000000000000376 0x0000000000000376 0x0000000000000110
+0x0000000000001880 0x000000000000188f 0x0000000000020101
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+''')
+f('sys/devices/pci0000:00/0000:00:1f.1/config', 0o644, b"\x86\x80\xdf'\x05\x00\x80\x02\x02\x8a\x01\x01\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x81\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x17\x0c \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\x03\x00\x00\x03\xe3\x00@\x00\x00\x00\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x0f\x02\x00\x00\x00\x00\x00")
+f('sys/devices/pci0000:00/0000:00:1f.1/resource1', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.1/resource2', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.1/local_cpus', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/subsystem_device', 0o644, b'0x200c\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/vendor', 0o644, b'0x8086\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/irq', 0o644, b'16\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/device', 0o644, b'0x27df\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/class', 0o644, b'0x01018a\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/msi_bus', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.1/resource0', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.1/subsystem_vendor', 0o644, b'0x17aa\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/uevent', 0o644, b'''DRIVER=ata_piix
+PCI_CLASS=1018A
+PCI_ID=8086:27DF
+PCI_SUBSYS_ID=17AA:200C
+PCI_SLOT_NAME=0000:00:1f.1
+MODALIAS=pci:v00008086d000027DFsv000017AAsd0000200Cbc01sc01i8a
+''')
+f('sys/devices/pci0000:00/0000:00:1f.1/resource4', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.1/broken_parity_status', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1f.1/host5', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.1/host5/subsystem', '../../../../bus/scsi')
+f('sys/devices/pci0000:00/0000:00:1f.1/host5/uevent', 0o644, b'DEVTYPE=scsi_host\n')
+d('sys/devices/pci0000:00/0000:00:1f.1/host5/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.1/host5/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.1/host5/scsi_host', 0o755)
+d('sys/devices/pci0000:00/0000:00:1f.1/host5/scsi_host/host5', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.1/host5/scsi_host/host5/subsystem', '../../../../../../class/scsi_host')
+l('sys/devices/pci0000:00/0000:00:1f.1/host5/scsi_host/host5/device', '../../../host5')
+f('sys/devices/pci0000:00/0000:00:1f.1/host5/scsi_host/host5/unique_id', 0o644, b'6\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host5/scsi_host/host5/can_queue', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host5/scsi_host/host5/unchecked_isa_dma', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host5/scsi_host/host5/active_mode', 0o644, b'Initiator\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host5/scsi_host/host5/sg_tablesize', 0o644, b'128\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host5/scsi_host/host5/prot_guard_type', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host5/scsi_host/host5/host_busy', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host5/scsi_host/host5/proc_name', 0o644, b'ata_piix\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host5/scsi_host/host5/state', 0o644, b'running\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host5/scsi_host/host5/cmd_per_lun', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host5/scsi_host/host5/supported_mode', 0o644, b'Initiator\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host5/scsi_host/host5/uevent', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.1/host5/scsi_host/host5/prot_capabilities', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1f.1/host5/scsi_host/host5/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.1/host5/scsi_host/host5/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.1/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.1/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.1/host4', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.1/host4/subsystem', '../../../../bus/scsi')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/uevent', 0o644, b'DEVTYPE=scsi_host\n')
+d('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/subsystem', '../../../../../bus/scsi')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/uevent', 0o644, b'DEVTYPE=scsi_target\n')
+d('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/generic', 'scsi_generic/sg1')
+l('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/subsystem', '../../../../../../bus/scsi')
+l('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/driver', '../../../../../../bus/scsi/drivers/sr')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/iodone_cnt', 0o644, b'0x20b3\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/device_blocked', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/modalias', 0o644, b'scsi:t-0x05\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/scsi_level', 0o644, b'6\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/queue_depth', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/rev', 0o644, b'RB01\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/type', 0o644, b'5\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/iocounterbits', 0o644, b'32\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/vendor', 0o644, b'MATSHITA\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/state', 0o644, b'running\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/queue_type', 0o644, b'none\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/iorequest_cnt', 0o644, b'0x82a9\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/evt_media_change', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/model', 0o644, b'DVD-RAM UJ-842 \n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/ioerr_cnt', 0o644, b'0x0\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/uevent', 0o644, b'''DEVTYPE=scsi_device
+DRIVER=sr
+MODALIAS=scsi:t-0x05
+''')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/timeout', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/scsi_generic', 0o755)
+d('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/scsi_generic/sg1', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/scsi_generic/sg1/subsystem', '../../../../../../../../class/scsi_generic')
+l('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/scsi_generic/sg1/device', '../../../4:0:0:0')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/scsi_generic/sg1/dev', 0o644, b'21:1\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/scsi_generic/sg1/uevent', 0o644, b'''MAJOR=21
+MINOR=1
+''')
+d('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/scsi_generic/sg1/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/scsi_generic/sg1/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/bsg', 0o755)
+d('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/bsg/4:0:0:0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/bsg/4:0:0:0/subsystem', '../../../../../../../../class/bsg')
+l('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/bsg/4:0:0:0/device', '../../../4:0:0:0')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/bsg/4:0:0:0/dev', 0o644, b'254:1\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/bsg/4:0:0:0/uevent', 0o644, b'''MAJOR=254
+MINOR=1
+''')
+d('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/bsg/4:0:0:0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/bsg/4:0:0:0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block', 0o755)
+d('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/subsystem', '../../../../../../../../class/block')
+l('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/bdi', '../../../../../../../virtual/bdi/11:0')
+l('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/device', '../../../4:0:0:0')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/capability', 0o644, b'19\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/ro', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/make-it-fail', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/size', 0o644, b'2097151\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/dev', 0o644, b'11:0\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/range', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/removable', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/stat', 0o644, b' 0 0 0 0 0 0 0 0 0 0 0\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/uevent', 0o644, b'''MAJOR=11
+MINOR=0
+DEVTYPE=disk
+''')
+d('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/queue', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/queue/nr_requests', 0o644, b'128\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/queue/nomerges', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/queue/scheduler', 0o644, b'noop anticipatory deadline [cfq] \n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/queue/hw_sector_size', 0o644, b'512\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/queue/max_hw_sectors_kb', 0o644, b'128\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/queue/read_ahead_kb', 0o644, b'128\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/queue/max_sectors_kb', 0o644, b'128\n')
+d('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/queue/iosched', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/queue/iosched/slice_async_rq', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/queue/iosched/back_seek_max', 0o644, b'16384\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/queue/iosched/slice_sync', 0o644, b'100\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/queue/iosched/slice_async', 0o644, b'40\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/queue/iosched/fifo_expire_sync', 0o644, b'125\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/queue/iosched/slice_idle', 0o644, b'8\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/queue/iosched/back_seek_penalty', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/queue/iosched/fifo_expire_async', 0o644, b'250\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/queue/iosched/quantum', 0o644, b'4\n')
+d('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/block/sr0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/scsi_device', 0o755)
+d('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/scsi_device/4:0:0:0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/scsi_device/4:0:0:0/subsystem', '../../../../../../../../class/scsi_device')
+l('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/scsi_device/4:0:0:0/device', '../../../4:0:0:0')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/scsi_device/4:0:0:0/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/scsi_device/4:0:0:0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0/scsi_device/4:0:0:0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.1/host4/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1f.1/host4/scsi_host', 0o755)
+d('sys/devices/pci0000:00/0000:00:1f.1/host4/scsi_host/host4', 0o755)
+l('sys/devices/pci0000:00/0000:00:1f.1/host4/scsi_host/host4/subsystem', '../../../../../../class/scsi_host')
+l('sys/devices/pci0000:00/0000:00:1f.1/host4/scsi_host/host4/device', '../../../host4')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/scsi_host/host4/unique_id', 0o644, b'5\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/scsi_host/host4/can_queue', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/scsi_host/host4/unchecked_isa_dma', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/scsi_host/host4/active_mode', 0o644, b'Initiator\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/scsi_host/host4/sg_tablesize', 0o644, b'128\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/scsi_host/host4/prot_guard_type', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/scsi_host/host4/host_busy', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/scsi_host/host4/proc_name', 0o644, b'ata_piix\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/scsi_host/host4/state', 0o644, b'running\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/scsi_host/host4/cmd_per_lun', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/scsi_host/host4/supported_mode', 0o644, b'Initiator\n')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/scsi_host/host4/uevent', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/scsi_host/host4/prot_capabilities', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1f.1/host4/scsi_host/host4/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1f.1/host4/scsi_host/host4/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1e.0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1e.0/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:11')
+l('sys/devices/pci0000:00/0000:00:1e.0/subsystem', '../../../bus/pci')
+f('sys/devices/pci0000:00/0000:00:1e.0/local_cpulist', 0o644, b'0-7\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/enable', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/modalias', 0o644, b'pci:v00008086d00002448sv00000000sd00000000bc06sc04i01\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/resource', 0o644, b'''0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x000000000000a000 0x000000000000dfff 0x0000000000000100
+0x00000000e4300000 0x00000000e7ffffff 0x0000000000000200
+0x00000000e0000000 0x00000000e3ffffff 0x0000000000001201
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+''')
+f('sys/devices/pci0000:00/0000:00:1e.0/config', 0o644, b'\x86\x80H$\x07\x00\x10\x00\xe2\x01\x04\x06\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x18 \xa0\xd0\x80"0\xe4\xf0\xe7\x01\xe0\xf1\xe3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\x00\x00\x00\x00\x00\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\r\x00\x00\x00\xaa\x17\x13 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x0f\x02\x00\x00\x00\x00\x00')
+f('sys/devices/pci0000:00/0000:00:1e.0/local_cpus', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/subsystem_device', 0o644, b'0x0000\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/vendor', 0o644, b'0x8086\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/irq', 0o644, b'0\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/device', 0o644, b'0x2448\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/class', 0o644, b'0x060401\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/msi_bus', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/subsystem_vendor', 0o644, b'0x0000\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/uevent', 0o644, b'''PCI_CLASS=60401
+PCI_ID=8086:2448
+PCI_SUBSYS_ID=0000:0000
+PCI_SLOT_NAME=0000:00:1e.0
+MODALIAS=pci:v00008086d00002448sv00000000sd00000000bc06sc04i01
+''')
+f('sys/devices/pci0000:00/0000:00:1e.0/broken_parity_status', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1e.0/pci_bus', 0o755)
+d('sys/devices/pci0000:00/0000:00:1e.0/pci_bus/0000:15', 0o755)
+l('sys/devices/pci0000:00/0000:00:1e.0/pci_bus/0000:15/subsystem', '../../../../../class/pci_bus')
+l('sys/devices/pci0000:00/0000:00:1e.0/pci_bus/0000:15/device', '../../../0000:00:1e.0')
+f('sys/devices/pci0000:00/0000:00:1e.0/pci_bus/0000:15/cpuaffinity', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/pci_bus/0000:15/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1e.0/pci_bus/0000:15/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1e.0/pci_bus/0000:15/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1e.0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1e.0/power/wakeup', 0o644, b'disabled\n')
+d('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/firmware_node', '../../../LNXSYSTM:00/device:00/PNP0A08:00/device:11/device:12')
+l('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/subsystem', '../../../../bus/pci')
+l('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/driver', '../../../../bus/pci/drivers/yenta_cardbus')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/local_cpulist', 0o644, b'0-7\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/enable', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/modalias', 0o644, b'pci:v0000104Cd0000AC56sv000017AAsd00002012bc06sc07i00\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/resource', 0o644, b'''0x00000000e4300000 0x00000000e4300fff 0x0000000000020200
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x000000000000a000 0x000000000000a0ff 0x0000000000020100
+0x000000000000a400 0x000000000000a4ff 0x0000000000020100
+0x00000000e0000000 0x00000000e3ffffff 0x0000000000021200
+0x0000000088000000 0x000000008bffffff 0x0000000000020200
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+''')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/config', 0o644, b'L\x10V\xac\x07\x00\x10\x02\x00\x00\x07\x06\x10\xa8\x02\x00\x00\x000\xe4\xa0\x00\x00\x02\x15\x16\x17\xb0\x00\x00\x00\xe0\x00\xf0\xff\xe3\x00\x00\x00\x88\x00\xf0\xff\x8b\x00\xa0\x00\x00\xfc\xa0\x00\x00\x00\xa4\x00\x00\xfc\xa4\x00\x00\x0b\x01\xc0\x05\xaa\x17\x12 \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xd0D\x08\x00\x00\x00\x00\x00\x00\x00\x00\x02\x10\xd0\x01\xc0\x02d@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x12\xfe\x00\x00\xc0\x00\x07\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/yenta_registers', 0o644, b'''CB registers:
+00: 00000000 00000006 30000087 00000000
+10: 00000400 00000000 00000000 00000000
+20: 00000000
+
+ExCA registers:
+00: 84 01 00 50 00 08 00 00 - 00 00 01 00 00 00 01 00
+10: 00 00 00 00 00 00 c0 00 - 00 00 00 00 00 00 00 00
+20: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
+30: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
+40: 00 00 00 00 00
+''')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/local_cpus', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/subsystem_device', 0o644, b'0x2012\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/vendor', 0o644, b'0x104c\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/irq', 0o644, b'16\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/device', 0o644, b'0xac56\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/class', 0o644, b'0x060700\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/msi_bus', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/resource0', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/subsystem_vendor', 0o644, b'0x17aa\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/uevent', 0o644, b'''DRIVER=yenta_cardbus
+PCI_CLASS=60700
+PCI_ID=104C:AC56
+PCI_SUBSYS_ID=17AA:2012
+PCI_SLOT_NAME=0000:15:00.0
+MODALIAS=pci:v0000104Cd0000AC56sv000017AAsd00002012bc06sc07i00
+''')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/broken_parity_status', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pci_bus', 0o755)
+d('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pci_bus/0000:16', 0o755)
+l('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pci_bus/0000:16/subsystem', '../../../../../../class/pci_bus')
+l('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pci_bus/0000:16/device', '../../../0000:15:00.0')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pci_bus/0000:16/cpuaffinity', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pci_bus/0000:16/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pci_bus/0000:16/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pci_bus/0000:16/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/power/wakeup', 0o644, b'disabled\n')
+d('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pcmcia_socket', 0o755)
+d('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pcmcia_socket/pcmcia_socket0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pcmcia_socket/pcmcia_socket0/subsystem', '../../../../../../class/pcmcia_socket')
+l('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pcmcia_socket/pcmcia_socket0/device', '../../../0000:15:00.0')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pcmcia_socket/pcmcia_socket0/card_vpp', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pcmcia_socket/pcmcia_socket0/available_resources_mem', 0o644, b'''0x000c0000 - 0x000fffff
+0x60000000 - 0x60ffffff
+0xa0000000 - 0xa0ffffff
+0xe0000000 - 0xe3ffffff
+0xe4300000 - 0xe7ffffff
+''')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pcmcia_socket/pcmcia_socket0/available_resources_io', 0o644, b'''0x00000100 - 0x000003af
+0x000003e0 - 0x000004ff
+0x00000820 - 0x000008ff
+0x00000a00 - 0x00000aff
+0x00000c00 - 0x00000cf7
+0x0000a000 - 0x0000dfff
+''')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pcmcia_socket/pcmcia_socket0/card_voltage', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pcmcia_socket/pcmcia_socket0/cis', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pcmcia_socket/pcmcia_socket0/available_resources_setup_done', 0o644, b'yes\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pcmcia_socket/pcmcia_socket0/card_irq_mask', 0o644, b'0x0cf8\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pcmcia_socket/pcmcia_socket0/card_pm_state', 0o644, b'on\n')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pcmcia_socket/pcmcia_socket0/card_vcc', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pcmcia_socket/pcmcia_socket0/card_type', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pcmcia_socket/pcmcia_socket0/uevent', 0o644, b'SOCKET_NO=0\n')
+d('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pcmcia_socket/pcmcia_socket0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/pcmcia_socket/pcmcia_socket0/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.1', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.1/firmware_node', '../../LNXSYSTM:00/device:00/PNP0A08:00/device:1a')
+l('sys/devices/pci0000:00/0000:00:1d.1/subsystem', '../../../bus/pci')
+l('sys/devices/pci0000:00/0000:00:1d.1/driver', '../../../bus/pci/drivers/uhci_hcd')
+f('sys/devices/pci0000:00/0000:00:1d.1/local_cpulist', 0o644, b'0-7\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/enable', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/modalias', 0o644, b'pci:v00008086d000027C9sv000017AAsd0000200Abc0Csc03i00\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/resource', 0o644, b'''0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000001820 0x000000000000183f 0x0000000000020101
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+''')
+f('sys/devices/pci0000:00/0000:00:1d.1/config', 0o644, b"\x86\x80\xc9'\x05\x00\x80\x02\x02\x00\x03\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x17\n \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x0f\x02\x00\x00\x00\x00\x00")
+f('sys/devices/pci0000:00/0000:00:1d.1/local_cpus', 0o644, b'ff\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/subsystem_device', 0o644, b'0x200a\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/vendor', 0o644, b'0x8086\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/irq', 0o644, b'17\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/pools', 0o644, b'''poolinfo - 0.1
+uhci_qh 11 32 128 1
+uhci_td 1 64 64 1
+buffer-2048 0 0 2048 0
+buffer-512 0 0 512 0
+buffer-128 0 0 128 0
+buffer-32 1 128 32 1
+''')
+f('sys/devices/pci0000:00/0000:00:1d.1/device', 0o644, b'0x27c9\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/class', 0o644, b'0x0c0300\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/msi_bus', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1d.1/subsystem_vendor', 0o644, b'0x17aa\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/uevent', 0o644, b'''DRIVER=uhci_hcd
+PCI_CLASS=C0300
+PCI_ID=8086:27C9
+PCI_SUBSYS_ID=17AA:200A
+PCI_SLOT_NAME=0000:00:1d.1
+MODALIAS=pci:v00008086d000027C9sv000017AAsd0000200Abc0Csc03i00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.1/resource4', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1d.1/broken_parity_status', 0o644, b'0\n')
+d('sys/devices/pci0000:00/0000:00:1d.1/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.1/power/wakeup', 0o644, b'disabled\n')
+d('sys/devices/pci0000:00/0000:00:1d.1/usb_host', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.1/usb_host/usb_host2', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.1/usb_host/usb_host2/subsystem', '../../../../../class/usb_host')
+l('sys/devices/pci0000:00/0000:00:1d.1/usb_host/usb_host2/device', '../../../0000:00:1d.1')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb_host/usb_host2/uevent', 0o644, b'')
+d('sys/devices/pci0000:00/0000:00:1d.1/usb_host/usb_host2/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.1/usb_host/usb_host2/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.1/usb2', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.1/usb2/subsystem', '../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.1/usb2/driver', '../../../../bus/usb/drivers/usb')
+l('sys/devices/pci0000:00/0000:00:1d.1/usb2/ep_00', 'usb_endpoint/usbdev2.1_ep00')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/version', 0o644, b' 1.10\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/authorized_default', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/maxchild', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/bDeviceClass', 0o644, b'09\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/bcdDevice', 0o644, b'0206\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/devnum', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/bDeviceProtocol', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/idProduct', 0o644, b'0001\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/product', 0o644, b'UHCI Host Controller\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/bDeviceSubClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/configuration', 0o644, b'')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/dev', 0o644, b'189:128\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/urbnum', 0o644, b'16\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/authorized', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/descriptors', 0o644, b'\x12\x01\x10\x01\t\x00\x00@k\x1d\x01\x00\x06\x02\x03\x02\x01\x01\t\x02\x19\x00\x01\x01\x00\xe0\x00\t\x04\x00\x00\x01\t\x00\x00\x00\x07\x05\x81\x03\x02\x00\xff')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/bNumConfigurations', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/serial', 0o644, b'0000:00:1d.1\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/speed', 0o644, b'12\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/bMaxPacketSize0', 0o644, b'64\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/bmAttributes', 0o644, b'e0\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/busnum', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/quirks', 0o644, b'0x0\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/bConfigurationValue', 0o644, b'1\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/uevent', 0o644, b'''MAJOR=189
+MINOR=128
+DEVTYPE=usb_device
+DRIVER=usb
+PRODUCT=1d6b/1/206
+TYPE=9/0/0
+BUSNUM=002
+DEVNUM=001
+''')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/manufacturer', 0o644, b'Linux 2.6.27-rc7-00106-g6ef190c-dirty uhci_hcd\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/idVendor', 0o644, b'1d6b\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/bNumInterfaces', 0o644, b' 1\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/bMaxPower', 0o644, b' 0mA\n')
+d('sys/devices/pci0000:00/0000:00:1d.1/usb2/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.1/usb2/usb_endpoint/usbdev2.1_ep00', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.1/usb2/usb_endpoint/usbdev2.1_ep00/subsystem', '../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.1/usb2/usb_endpoint/usbdev2.1_ep00/device', '../../../usb2')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/usb_endpoint/usbdev2.1_ep00/interval', 0o644, b'0ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/usb_endpoint/usbdev2.1_ep00/bEndpointAddress', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/usb_endpoint/usbdev2.1_ep00/type', 0o644, b'Control\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/usb_endpoint/usbdev2.1_ep00/dev', 0o644, b'252:3\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/usb_endpoint/usbdev2.1_ep00/direction', 0o644, b'both\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/usb_endpoint/usbdev2.1_ep00/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/usb_endpoint/usbdev2.1_ep00/wMaxPacketSize', 0o644, b'0040\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/usb_endpoint/usbdev2.1_ep00/bmAttributes', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/usb_endpoint/usbdev2.1_ep00/uevent', 0o644, b'''MAJOR=252
+MINOR=3
+''')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/usb_endpoint/usbdev2.1_ep00/bInterval', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.1/usb2/usb_endpoint/usbdev2.1_ep00/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/usb_endpoint/usbdev2.1_ep00/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.1/usb2/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/power/active_duration', 0o644, b'2363\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/power/wakeup', 0o644, b'enabled\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/power/connected_duration', 0o644, b'8372254\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/power/autosuspend', 0o644, b'2\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/power/level', 0o644, b'auto\n')
+d('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/subsystem', '../../../../../bus/usb')
+l('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/ep_81', 'usb_endpoint/usbdev2.1_ep81')
+l('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/driver', '../../../../../bus/usb/drivers/hub')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/modalias', 0o644, b'usb:v1D6Bp0001d0206dc09dsc00dp00ic09isc00ip00\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/bInterfaceNumber', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/bNumEndpoints', 0o644, b'01\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/bInterfaceSubClass', 0o644, b'00\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/bAlternateSetting', 0o644, b' 0\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/bInterfaceClass', 0o644, b'09\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/uevent', 0o644, b'''DEVTYPE=usb_interface
+DRIVER=hub
+PRODUCT=1d6b/1/206
+TYPE=9/0/0
+INTERFACE=9/0/0
+MODALIAS=usb:v1D6Bp0001d0206dc09dsc00dp00ic09isc00ip00
+''')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/bInterfaceProtocol', 0o644, b'00\n')
+d('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/usb_endpoint', 0o755)
+d('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/usb_endpoint/usbdev2.1_ep81', 0o755)
+l('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/usb_endpoint/usbdev2.1_ep81/subsystem', '../../../../../../../class/usb_endpoint')
+l('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/usb_endpoint/usbdev2.1_ep81/device', '../../../2-0:1.0')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/usb_endpoint/usbdev2.1_ep81/interval', 0o644, b'255ms\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/usb_endpoint/usbdev2.1_ep81/bEndpointAddress', 0o644, b'81\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/usb_endpoint/usbdev2.1_ep81/type', 0o644, b'Interrupt\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/usb_endpoint/usbdev2.1_ep81/dev', 0o644, b'252:2\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/usb_endpoint/usbdev2.1_ep81/direction', 0o644, b'in\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/usb_endpoint/usbdev2.1_ep81/bLength', 0o644, b'07\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/usb_endpoint/usbdev2.1_ep81/wMaxPacketSize', 0o644, b'0002\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/usb_endpoint/usbdev2.1_ep81/bmAttributes', 0o644, b'03\n')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/usb_endpoint/usbdev2.1_ep81/uevent', 0o644, b'''MAJOR=252
+MINOR=2
+''')
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/usb_endpoint/usbdev2.1_ep81/bInterval', 0o644, b'ff\n')
+d('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/usb_endpoint/usbdev2.1_ep81/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/usb_endpoint/usbdev2.1_ep81/power/wakeup', 0o644, b'\n')
+d('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/power', 0o755)
+f('sys/devices/pci0000:00/0000:00:1d.1/usb2/2-0:1.0/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual', 0o755)
+d('sys/devices/virtual/vc', 0o755)
+d('sys/devices/virtual/vc/vcsa3', 0o755)
+l('sys/devices/virtual/vc/vcsa3/subsystem', '../../../../class/vc')
+f('sys/devices/virtual/vc/vcsa3/dev', 0o644, b'7:131\n')
+f('sys/devices/virtual/vc/vcsa3/uevent', 0o644, b'''MAJOR=7
+MINOR=131
+''')
+d('sys/devices/virtual/vc/vcsa3/power', 0o755)
+f('sys/devices/virtual/vc/vcsa3/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/vc/vcsa6', 0o755)
+l('sys/devices/virtual/vc/vcsa6/subsystem', '../../../../class/vc')
+f('sys/devices/virtual/vc/vcsa6/dev', 0o644, b'7:134\n')
+f('sys/devices/virtual/vc/vcsa6/uevent', 0o644, b'''MAJOR=7
+MINOR=134
+''')
+d('sys/devices/virtual/vc/vcsa6/power', 0o755)
+f('sys/devices/virtual/vc/vcsa6/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/vc/vcsa2', 0o755)
+l('sys/devices/virtual/vc/vcsa2/subsystem', '../../../../class/vc')
+f('sys/devices/virtual/vc/vcsa2/dev', 0o644, b'7:130\n')
+f('sys/devices/virtual/vc/vcsa2/uevent', 0o644, b'''MAJOR=7
+MINOR=130
+''')
+d('sys/devices/virtual/vc/vcsa2/power', 0o755)
+f('sys/devices/virtual/vc/vcsa2/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/vc/vcsa', 0o755)
+l('sys/devices/virtual/vc/vcsa/subsystem', '../../../../class/vc')
+f('sys/devices/virtual/vc/vcsa/dev', 0o644, b'7:128\n')
+f('sys/devices/virtual/vc/vcsa/uevent', 0o644, b'''MAJOR=7
+MINOR=128
+''')
+d('sys/devices/virtual/vc/vcsa/power', 0o755)
+f('sys/devices/virtual/vc/vcsa/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/vc/vcs2', 0o755)
+l('sys/devices/virtual/vc/vcs2/subsystem', '../../../../class/vc')
+f('sys/devices/virtual/vc/vcs2/dev', 0o644, b'7:2\n')
+f('sys/devices/virtual/vc/vcs2/uevent', 0o644, b'''MAJOR=7
+MINOR=2
+''')
+d('sys/devices/virtual/vc/vcs2/power', 0o755)
+f('sys/devices/virtual/vc/vcs2/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/vc/vcs7', 0o755)
+l('sys/devices/virtual/vc/vcs7/subsystem', '../../../../class/vc')
+f('sys/devices/virtual/vc/vcs7/dev', 0o644, b'7:7\n')
+f('sys/devices/virtual/vc/vcs7/uevent', 0o644, b'''MAJOR=7
+MINOR=7
+''')
+d('sys/devices/virtual/vc/vcs7/power', 0o755)
+f('sys/devices/virtual/vc/vcs7/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/vc/vcsa5', 0o755)
+l('sys/devices/virtual/vc/vcsa5/subsystem', '../../../../class/vc')
+f('sys/devices/virtual/vc/vcsa5/dev', 0o644, b'7:133\n')
+f('sys/devices/virtual/vc/vcsa5/uevent', 0o644, b'''MAJOR=7
+MINOR=133
+''')
+d('sys/devices/virtual/vc/vcsa5/power', 0o755)
+f('sys/devices/virtual/vc/vcsa5/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/vc/vcsa10', 0o755)
+l('sys/devices/virtual/vc/vcsa10/subsystem', '../../../../class/vc')
+f('sys/devices/virtual/vc/vcsa10/dev', 0o644, b'7:138\n')
+f('sys/devices/virtual/vc/vcsa10/uevent', 0o644, b'''MAJOR=7
+MINOR=138
+''')
+d('sys/devices/virtual/vc/vcsa10/power', 0o755)
+f('sys/devices/virtual/vc/vcsa10/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/vc/vcs10', 0o755)
+l('sys/devices/virtual/vc/vcs10/subsystem', '../../../../class/vc')
+f('sys/devices/virtual/vc/vcs10/dev', 0o644, b'7:10\n')
+f('sys/devices/virtual/vc/vcs10/uevent', 0o644, b'''MAJOR=7
+MINOR=10
+''')
+d('sys/devices/virtual/vc/vcs10/power', 0o755)
+f('sys/devices/virtual/vc/vcs10/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/vc/vcsa1', 0o755)
+l('sys/devices/virtual/vc/vcsa1/subsystem', '../../../../class/vc')
+f('sys/devices/virtual/vc/vcsa1/dev', 0o644, b'7:129\n')
+f('sys/devices/virtual/vc/vcsa1/uevent', 0o644, b'''MAJOR=7
+MINOR=129
+''')
+d('sys/devices/virtual/vc/vcsa1/power', 0o755)
+f('sys/devices/virtual/vc/vcsa1/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/vc/vcsa4', 0o755)
+l('sys/devices/virtual/vc/vcsa4/subsystem', '../../../../class/vc')
+f('sys/devices/virtual/vc/vcsa4/dev', 0o644, b'7:132\n')
+f('sys/devices/virtual/vc/vcsa4/uevent', 0o644, b'''MAJOR=7
+MINOR=132
+''')
+d('sys/devices/virtual/vc/vcsa4/power', 0o755)
+f('sys/devices/virtual/vc/vcsa4/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/vc/vcs', 0o755)
+l('sys/devices/virtual/vc/vcs/subsystem', '../../../../class/vc')
+f('sys/devices/virtual/vc/vcs/dev', 0o644, b'7:0\n')
+f('sys/devices/virtual/vc/vcs/uevent', 0o644, b'''MAJOR=7
+MINOR=0
+''')
+d('sys/devices/virtual/vc/vcs/power', 0o755)
+f('sys/devices/virtual/vc/vcs/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/vc/vcs1', 0o755)
+l('sys/devices/virtual/vc/vcs1/subsystem', '../../../../class/vc')
+f('sys/devices/virtual/vc/vcs1/dev', 0o644, b'7:1\n')
+f('sys/devices/virtual/vc/vcs1/uevent', 0o644, b'''MAJOR=7
+MINOR=1
+''')
+d('sys/devices/virtual/vc/vcs1/power', 0o755)
+f('sys/devices/virtual/vc/vcs1/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/vc/vcs4', 0o755)
+l('sys/devices/virtual/vc/vcs4/subsystem', '../../../../class/vc')
+f('sys/devices/virtual/vc/vcs4/dev', 0o644, b'7:4\n')
+f('sys/devices/virtual/vc/vcs4/uevent', 0o644, b'''MAJOR=7
+MINOR=4
+''')
+d('sys/devices/virtual/vc/vcs4/power', 0o755)
+f('sys/devices/virtual/vc/vcs4/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/vc/vcsa7', 0o755)
+l('sys/devices/virtual/vc/vcsa7/subsystem', '../../../../class/vc')
+f('sys/devices/virtual/vc/vcsa7/dev', 0o644, b'7:135\n')
+f('sys/devices/virtual/vc/vcsa7/uevent', 0o644, b'''MAJOR=7
+MINOR=135
+''')
+d('sys/devices/virtual/vc/vcsa7/power', 0o755)
+f('sys/devices/virtual/vc/vcsa7/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/vc/vcs6', 0o755)
+l('sys/devices/virtual/vc/vcs6/subsystem', '../../../../class/vc')
+f('sys/devices/virtual/vc/vcs6/dev', 0o644, b'7:6\n')
+f('sys/devices/virtual/vc/vcs6/uevent', 0o644, b'''MAJOR=7
+MINOR=6
+''')
+d('sys/devices/virtual/vc/vcs6/power', 0o755)
+f('sys/devices/virtual/vc/vcs6/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/vc/vcs3', 0o755)
+l('sys/devices/virtual/vc/vcs3/subsystem', '../../../../class/vc')
+f('sys/devices/virtual/vc/vcs3/dev', 0o644, b'7:3\n')
+f('sys/devices/virtual/vc/vcs3/uevent', 0o644, b'''MAJOR=7
+MINOR=3
+''')
+d('sys/devices/virtual/vc/vcs3/power', 0o755)
+f('sys/devices/virtual/vc/vcs3/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/vc/vcs5', 0o755)
+l('sys/devices/virtual/vc/vcs5/subsystem', '../../../../class/vc')
+f('sys/devices/virtual/vc/vcs5/dev', 0o644, b'7:5\n')
+f('sys/devices/virtual/vc/vcs5/uevent', 0o644, b'''MAJOR=7
+MINOR=5
+''')
+d('sys/devices/virtual/vc/vcs5/power', 0o755)
+f('sys/devices/virtual/vc/vcs5/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/mem', 0o755)
+d('sys/devices/virtual/mem/zero', 0o755)
+l('sys/devices/virtual/mem/zero/subsystem', '../../../../class/mem')
+f('sys/devices/virtual/mem/zero/dev', 0o644, b'1:5\n')
+f('sys/devices/virtual/mem/zero/uevent', 0o644, b'''MAJOR=1
+MINOR=5
+''')
+d('sys/devices/virtual/mem/zero/power', 0o755)
+f('sys/devices/virtual/mem/zero/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/mem/kmsg', 0o755)
+l('sys/devices/virtual/mem/kmsg/subsystem', '../../../../class/mem')
+f('sys/devices/virtual/mem/kmsg/dev', 0o644, b'1:11\n')
+f('sys/devices/virtual/mem/kmsg/uevent', 0o644, b'''MAJOR=1
+MINOR=11
+''')
+d('sys/devices/virtual/mem/kmsg/power', 0o755)
+f('sys/devices/virtual/mem/kmsg/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/mem/mem', 0o755)
+l('sys/devices/virtual/mem/mem/subsystem', '../../../../class/mem')
+f('sys/devices/virtual/mem/mem/dev', 0o644, b'1:1\n')
+f('sys/devices/virtual/mem/mem/uevent', 0o644, b'''MAJOR=1
+MINOR=1
+''')
+d('sys/devices/virtual/mem/mem/power', 0o755)
+f('sys/devices/virtual/mem/mem/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/mem/urandom', 0o755)
+l('sys/devices/virtual/mem/urandom/subsystem', '../../../../class/mem')
+f('sys/devices/virtual/mem/urandom/dev', 0o644, b'1:9\n')
+f('sys/devices/virtual/mem/urandom/uevent', 0o644, b'''MAJOR=1
+MINOR=9
+''')
+d('sys/devices/virtual/mem/urandom/power', 0o755)
+f('sys/devices/virtual/mem/urandom/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/mem/port', 0o755)
+l('sys/devices/virtual/mem/port/subsystem', '../../../../class/mem')
+f('sys/devices/virtual/mem/port/dev', 0o644, b'1:4\n')
+f('sys/devices/virtual/mem/port/uevent', 0o644, b'''MAJOR=1
+MINOR=4
+''')
+d('sys/devices/virtual/mem/port/power', 0o755)
+f('sys/devices/virtual/mem/port/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/mem/null', 0o755)
+l('sys/devices/virtual/mem/null/subsystem', '../../../../class/mem')
+f('sys/devices/virtual/mem/null/dev', 0o644, b'1:3\n')
+f('sys/devices/virtual/mem/null/uevent', 0o644, b'''MAJOR=1
+MINOR=3
+''')
+d('sys/devices/virtual/mem/null/power', 0o755)
+f('sys/devices/virtual/mem/null/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/mem/kmem', 0o755)
+l('sys/devices/virtual/mem/kmem/subsystem', '../../../../class/mem')
+f('sys/devices/virtual/mem/kmem/dev', 0o644, b'1:2\n')
+f('sys/devices/virtual/mem/kmem/uevent', 0o644, b'''MAJOR=1
+MINOR=2
+''')
+d('sys/devices/virtual/mem/kmem/power', 0o755)
+f('sys/devices/virtual/mem/kmem/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/mem/full', 0o755)
+l('sys/devices/virtual/mem/full/subsystem', '../../../../class/mem')
+f('sys/devices/virtual/mem/full/dev', 0o644, b'1:7\n')
+f('sys/devices/virtual/mem/full/uevent', 0o644, b'''MAJOR=1
+MINOR=7
+''')
+d('sys/devices/virtual/mem/full/power', 0o755)
+f('sys/devices/virtual/mem/full/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/mem/random', 0o755)
+l('sys/devices/virtual/mem/random/subsystem', '../../../../class/mem')
+f('sys/devices/virtual/mem/random/dev', 0o644, b'1:8\n')
+f('sys/devices/virtual/mem/random/uevent', 0o644, b'''MAJOR=1
+MINOR=8
+''')
+d('sys/devices/virtual/mem/random/power', 0o755)
+f('sys/devices/virtual/mem/random/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/net', 0o755)
+d('sys/devices/virtual/net/lo', 0o755)
+l('sys/devices/virtual/net/lo/subsystem', '../../../../class/net')
+f('sys/devices/virtual/net/lo/ifindex', 0o644, b'1\n')
+f('sys/devices/virtual/net/lo/features', 0o644, b'0x13865\n')
+f('sys/devices/virtual/net/lo/iflink', 0o644, b'1\n')
+f('sys/devices/virtual/net/lo/dormant', 0o644, b'0\n')
+f('sys/devices/virtual/net/lo/dev_id', 0o644, b'0x0\n')
+f('sys/devices/virtual/net/lo/type', 0o644, b'772\n')
+f('sys/devices/virtual/net/lo/operstate', 0o644, b'unknown\n')
+f('sys/devices/virtual/net/lo/carrier', 0o644, b'1\n')
+f('sys/devices/virtual/net/lo/link_mode', 0o644, b'0\n')
+f('sys/devices/virtual/net/lo/tx_queue_len', 0o644, b'0\n')
+f('sys/devices/virtual/net/lo/flags', 0o644, b'0x9\n')
+f('sys/devices/virtual/net/lo/addr_len', 0o644, b'6\n')
+f('sys/devices/virtual/net/lo/address', 0o644, b'00:00:00:00:00:00\n')
+f('sys/devices/virtual/net/lo/uevent', 0o644, b'''INTERFACE=lo
+IFINDEX=1
+''')
+f('sys/devices/virtual/net/lo/mtu', 0o644, b'16436\n')
+f('sys/devices/virtual/net/lo/broadcast', 0o644, b'00:00:00:00:00:00\n')
+d('sys/devices/virtual/net/lo/statistics', 0o755)
+f('sys/devices/virtual/net/lo/statistics/tx_aborted_errors', 0o644, b'0\n')
+f('sys/devices/virtual/net/lo/statistics/rx_crc_errors', 0o644, b'0\n')
+f('sys/devices/virtual/net/lo/statistics/rx_bytes', 0o644, b'3380\n')
+f('sys/devices/virtual/net/lo/statistics/rx_errors', 0o644, b'0\n')
+f('sys/devices/virtual/net/lo/statistics/tx_packets', 0o644, b'46\n')
+f('sys/devices/virtual/net/lo/statistics/tx_carrier_errors', 0o644, b'0\n')
+f('sys/devices/virtual/net/lo/statistics/tx_errors', 0o644, b'0\n')
+f('sys/devices/virtual/net/lo/statistics/rx_dropped', 0o644, b'0\n')
+f('sys/devices/virtual/net/lo/statistics/tx_fifo_errors', 0o644, b'0\n')
+f('sys/devices/virtual/net/lo/statistics/rx_length_errors', 0o644, b'0\n')
+f('sys/devices/virtual/net/lo/statistics/tx_dropped', 0o644, b'0\n')
+f('sys/devices/virtual/net/lo/statistics/rx_fifo_errors', 0o644, b'0\n')
+f('sys/devices/virtual/net/lo/statistics/rx_missed_errors', 0o644, b'0\n')
+f('sys/devices/virtual/net/lo/statistics/tx_window_errors', 0o644, b'0\n')
+f('sys/devices/virtual/net/lo/statistics/collisions', 0o644, b'0\n')
+f('sys/devices/virtual/net/lo/statistics/rx_frame_errors', 0o644, b'0\n')
+f('sys/devices/virtual/net/lo/statistics/rx_packets', 0o644, b'46\n')
+f('sys/devices/virtual/net/lo/statistics/rx_compressed', 0o644, b'0\n')
+f('sys/devices/virtual/net/lo/statistics/tx_compressed', 0o644, b'0\n')
+f('sys/devices/virtual/net/lo/statistics/multicast', 0o644, b'0\n')
+f('sys/devices/virtual/net/lo/statistics/rx_over_errors', 0o644, b'0\n')
+f('sys/devices/virtual/net/lo/statistics/tx_bytes', 0o644, b'3380\n')
+f('sys/devices/virtual/net/lo/statistics/tx_heartbeat_errors', 0o644, b'0\n')
+d('sys/devices/virtual/net/lo/power', 0o755)
+f('sys/devices/virtual/net/lo/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/dmi', 0o755)
+d('sys/devices/virtual/dmi/id', 0o755)
+l('sys/devices/virtual/dmi/id/subsystem', '../../../../class/dmi')
+f('sys/devices/virtual/dmi/id/product_name', 0o644, b'8741C4G\n')
+f('sys/devices/virtual/dmi/id/modalias', 0o644, b'dmi:bvnLENOVO:bvr7IET31WW(1.12):bd09/19/2007:svnLENOVO:pn8741C4G:pvrThinkPadT60p:rvnLENOVO:rn8741C4G:rvrNotAvailable:cvnLENOVO:ct10:cvrNotAvailable:\n')
+f('sys/devices/virtual/dmi/id/chassis_serial', 0o644, b'Not Available\n')
+f('sys/devices/virtual/dmi/id/board_version', 0o644, b'Not Available\n')
+f('sys/devices/virtual/dmi/id/board_serial', 0o644, b'VF0UV72C10X\n')
+f('sys/devices/virtual/dmi/id/chassis_type', 0o644, b'10\n')
+f('sys/devices/virtual/dmi/id/chassis_asset_tag', 0o644, b'No Asset Information\n')
+f('sys/devices/virtual/dmi/id/product_uuid', 0o644, b'82161681-492E-11CB-BCCA-A7FDE26F414B\n')
+f('sys/devices/virtual/dmi/id/board_name', 0o644, b'8741C4G\n')
+f('sys/devices/virtual/dmi/id/board_asset_tag', 0o644, b'\n')
+f('sys/devices/virtual/dmi/id/bios_date', 0o644, b'09/19/2007\n')
+f('sys/devices/virtual/dmi/id/bios_version', 0o644, b'7IET31WW (1.12 )\n')
+f('sys/devices/virtual/dmi/id/product_serial', 0o644, b'L3AK195\n')
+f('sys/devices/virtual/dmi/id/chassis_version', 0o644, b'Not Available\n')
+f('sys/devices/virtual/dmi/id/chassis_vendor', 0o644, b'LENOVO\n')
+f('sys/devices/virtual/dmi/id/product_version', 0o644, b'ThinkPad T60p\n')
+f('sys/devices/virtual/dmi/id/board_vendor', 0o644, b'LENOVO\n')
+f('sys/devices/virtual/dmi/id/uevent', 0o644, b'MODALIAS=dmi:bvnLENOVO:bvr7IET31WW(1.12):bd09/19/2007:svnLENOVO:pn8741C4G:pvrThinkPadT60p:rvnLENOVO:rn8741C4G:rvrNotAvailable:cvnLENOVO:ct10:cvrNotAvailable:\n')
+f('sys/devices/virtual/dmi/id/sys_vendor', 0o644, b'LENOVO\n')
+f('sys/devices/virtual/dmi/id/bios_vendor', 0o644, b'LENOVO\n')
+d('sys/devices/virtual/dmi/id/power', 0o755)
+f('sys/devices/virtual/dmi/id/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/bdi', 0o755)
+d('sys/devices/virtual/bdi/7:1', 0o755)
+l('sys/devices/virtual/bdi/7:1/subsystem', '../../../../class/bdi')
+f('sys/devices/virtual/bdi/7:1/read_ahead_kb', 0o644, b'0\n')
+f('sys/devices/virtual/bdi/7:1/uevent', 0o644, b'')
+f('sys/devices/virtual/bdi/7:1/max_ratio', 0o644, b'100\n')
+f('sys/devices/virtual/bdi/7:1/min_ratio', 0o644, b'0\n')
+d('sys/devices/virtual/bdi/7:1/power', 0o755)
+f('sys/devices/virtual/bdi/7:1/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/bdi/7:0', 0o755)
+l('sys/devices/virtual/bdi/7:0/subsystem', '../../../../class/bdi')
+f('sys/devices/virtual/bdi/7:0/read_ahead_kb', 0o644, b'0\n')
+f('sys/devices/virtual/bdi/7:0/uevent', 0o644, b'')
+f('sys/devices/virtual/bdi/7:0/max_ratio', 0o644, b'100\n')
+f('sys/devices/virtual/bdi/7:0/min_ratio', 0o644, b'0\n')
+d('sys/devices/virtual/bdi/7:0/power', 0o755)
+f('sys/devices/virtual/bdi/7:0/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/bdi/7:2', 0o755)
+l('sys/devices/virtual/bdi/7:2/subsystem', '../../../../class/bdi')
+f('sys/devices/virtual/bdi/7:2/read_ahead_kb', 0o644, b'0\n')
+f('sys/devices/virtual/bdi/7:2/uevent', 0o644, b'')
+f('sys/devices/virtual/bdi/7:2/max_ratio', 0o644, b'100\n')
+f('sys/devices/virtual/bdi/7:2/min_ratio', 0o644, b'0\n')
+d('sys/devices/virtual/bdi/7:2/power', 0o755)
+f('sys/devices/virtual/bdi/7:2/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/bdi/7:4', 0o755)
+l('sys/devices/virtual/bdi/7:4/subsystem', '../../../../class/bdi')
+f('sys/devices/virtual/bdi/7:4/read_ahead_kb', 0o644, b'0\n')
+f('sys/devices/virtual/bdi/7:4/uevent', 0o644, b'')
+f('sys/devices/virtual/bdi/7:4/max_ratio', 0o644, b'100\n')
+f('sys/devices/virtual/bdi/7:4/min_ratio', 0o644, b'0\n')
+d('sys/devices/virtual/bdi/7:4/power', 0o755)
+f('sys/devices/virtual/bdi/7:4/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/bdi/7:3', 0o755)
+l('sys/devices/virtual/bdi/7:3/subsystem', '../../../../class/bdi')
+f('sys/devices/virtual/bdi/7:3/read_ahead_kb', 0o644, b'0\n')
+f('sys/devices/virtual/bdi/7:3/uevent', 0o644, b'')
+f('sys/devices/virtual/bdi/7:3/max_ratio', 0o644, b'100\n')
+f('sys/devices/virtual/bdi/7:3/min_ratio', 0o644, b'0\n')
+d('sys/devices/virtual/bdi/7:3/power', 0o755)
+f('sys/devices/virtual/bdi/7:3/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/bdi/11:0', 0o755)
+l('sys/devices/virtual/bdi/11:0/subsystem', '../../../../class/bdi')
+f('sys/devices/virtual/bdi/11:0/read_ahead_kb', 0o644, b'128\n')
+f('sys/devices/virtual/bdi/11:0/uevent', 0o644, b'')
+f('sys/devices/virtual/bdi/11:0/max_ratio', 0o644, b'100\n')
+f('sys/devices/virtual/bdi/11:0/min_ratio', 0o644, b'0\n')
+d('sys/devices/virtual/bdi/11:0/power', 0o755)
+f('sys/devices/virtual/bdi/11:0/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/bdi/7:5', 0o755)
+l('sys/devices/virtual/bdi/7:5/subsystem', '../../../../class/bdi')
+f('sys/devices/virtual/bdi/7:5/read_ahead_kb', 0o644, b'0\n')
+f('sys/devices/virtual/bdi/7:5/uevent', 0o644, b'')
+f('sys/devices/virtual/bdi/7:5/max_ratio', 0o644, b'100\n')
+f('sys/devices/virtual/bdi/7:5/min_ratio', 0o644, b'0\n')
+d('sys/devices/virtual/bdi/7:5/power', 0o755)
+f('sys/devices/virtual/bdi/7:5/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/bdi/8:0', 0o755)
+l('sys/devices/virtual/bdi/8:0/subsystem', '../../../../class/bdi')
+f('sys/devices/virtual/bdi/8:0/read_ahead_kb', 0o644, b'128\n')
+f('sys/devices/virtual/bdi/8:0/uevent', 0o644, b'')
+f('sys/devices/virtual/bdi/8:0/max_ratio', 0o644, b'100\n')
+f('sys/devices/virtual/bdi/8:0/min_ratio', 0o644, b'0\n')
+d('sys/devices/virtual/bdi/8:0/power', 0o755)
+f('sys/devices/virtual/bdi/8:0/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/bdi/default', 0o755)
+l('sys/devices/virtual/bdi/default/subsystem', '../../../../class/bdi')
+f('sys/devices/virtual/bdi/default/read_ahead_kb', 0o644, b'128\n')
+f('sys/devices/virtual/bdi/default/uevent', 0o644, b'')
+f('sys/devices/virtual/bdi/default/max_ratio', 0o644, b'100\n')
+f('sys/devices/virtual/bdi/default/min_ratio', 0o644, b'0\n')
+d('sys/devices/virtual/bdi/default/power', 0o755)
+f('sys/devices/virtual/bdi/default/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/bdi/0:16', 0o755)
+l('sys/devices/virtual/bdi/0:16/subsystem', '../../../../class/bdi')
+f('sys/devices/virtual/bdi/0:16/read_ahead_kb', 0o644, b'128\n')
+f('sys/devices/virtual/bdi/0:16/uevent', 0o644, b'')
+f('sys/devices/virtual/bdi/0:16/max_ratio', 0o644, b'1\n')
+f('sys/devices/virtual/bdi/0:16/min_ratio', 0o644, b'0\n')
+d('sys/devices/virtual/bdi/0:16/power', 0o755)
+f('sys/devices/virtual/bdi/0:16/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/bdi/8:16', 0o755)
+l('sys/devices/virtual/bdi/8:16/subsystem', '../../../../class/bdi')
+f('sys/devices/virtual/bdi/8:16/read_ahead_kb', 0o644, b'128\n')
+f('sys/devices/virtual/bdi/8:16/uevent', 0o644, b'')
+f('sys/devices/virtual/bdi/8:16/max_ratio', 0o644, b'100\n')
+f('sys/devices/virtual/bdi/8:16/min_ratio', 0o644, b'0\n')
+d('sys/devices/virtual/bdi/8:16/power', 0o755)
+f('sys/devices/virtual/bdi/8:16/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/bdi/9:0', 0o755)
+l('sys/devices/virtual/bdi/9:0/subsystem', '../../../../class/bdi')
+f('sys/devices/virtual/bdi/9:0/read_ahead_kb', 0o644, b'128\n')
+f('sys/devices/virtual/bdi/9:0/uevent', 0o644, b'')
+f('sys/devices/virtual/bdi/9:0/max_ratio', 0o644, b'100\n')
+f('sys/devices/virtual/bdi/9:0/min_ratio', 0o644, b'0\n')
+d('sys/devices/virtual/bdi/9:0/power', 0o755)
+f('sys/devices/virtual/bdi/9:0/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/bdi/7:7', 0o755)
+l('sys/devices/virtual/bdi/7:7/subsystem', '../../../../class/bdi')
+f('sys/devices/virtual/bdi/7:7/read_ahead_kb', 0o644, b'0\n')
+f('sys/devices/virtual/bdi/7:7/uevent', 0o644, b'')
+f('sys/devices/virtual/bdi/7:7/max_ratio', 0o644, b'100\n')
+f('sys/devices/virtual/bdi/7:7/min_ratio', 0o644, b'0\n')
+d('sys/devices/virtual/bdi/7:7/power', 0o755)
+f('sys/devices/virtual/bdi/7:7/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/bdi/7:6', 0o755)
+l('sys/devices/virtual/bdi/7:6/subsystem', '../../../../class/bdi')
+f('sys/devices/virtual/bdi/7:6/read_ahead_kb', 0o644, b'0\n')
+f('sys/devices/virtual/bdi/7:6/uevent', 0o644, b'')
+f('sys/devices/virtual/bdi/7:6/max_ratio', 0o644, b'100\n')
+f('sys/devices/virtual/bdi/7:6/min_ratio', 0o644, b'0\n')
+d('sys/devices/virtual/bdi/7:6/power', 0o755)
+f('sys/devices/virtual/bdi/7:6/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/sound', 0o755)
+d('sys/devices/virtual/sound/timer', 0o755)
+l('sys/devices/virtual/sound/timer/subsystem', '../../../../class/sound')
+f('sys/devices/virtual/sound/timer/dev', 0o644, b'116:33\n')
+f('sys/devices/virtual/sound/timer/uevent', 0o644, b'''MAJOR=116
+MINOR=33
+''')
+d('sys/devices/virtual/sound/timer/power', 0o755)
+f('sys/devices/virtual/sound/timer/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/sound/seq', 0o755)
+l('sys/devices/virtual/sound/seq/subsystem', '../../../../class/sound')
+f('sys/devices/virtual/sound/seq/dev', 0o644, b'116:1\n')
+f('sys/devices/virtual/sound/seq/uevent', 0o644, b'''MAJOR=116
+MINOR=1
+''')
+d('sys/devices/virtual/sound/seq/power', 0o755)
+f('sys/devices/virtual/sound/seq/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/misc', 0o755)
+d('sys/devices/virtual/misc/misc-fake89999', 0o755)
+l('sys/devices/virtual/misc/misc-fake89999/subsystem', '../../../../class/misc')
+f('sys/devices/virtual/misc/misc-fake89999/dev', 0o644, b'4095:89999\n')
+f('sys/devices/virtual/misc/misc-fake89999/uevent', 0o644, b'''MAJOR=4095
+MINOR=89999
+DEVNAME=misc-fake89999
+''')
+d('sys/devices/virtual/misc/misc-fake89999/power', 0o755)
+f('sys/devices/virtual/misc/misc-fake89999/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/misc/uinput', 0o755)
+l('sys/devices/virtual/misc/uinput/subsystem', '../../../../class/misc')
+f('sys/devices/virtual/misc/uinput/dev', 0o644, b'10:223\n')
+f('sys/devices/virtual/misc/uinput/uevent', 0o644, b'''MAJOR=10
+MINOR=223
+''')
+d('sys/devices/virtual/misc/uinput/power', 0o755)
+f('sys/devices/virtual/misc/uinput/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/misc/fuse', 0o755)
+l('sys/devices/virtual/misc/fuse/subsystem', '../../../../class/misc')
+f('sys/devices/virtual/misc/fuse/dev', 0o644, b'10:229\n')
+f('sys/devices/virtual/misc/fuse/uevent', 0o644, b'''MAJOR=10
+MINOR=229
+''')
+d('sys/devices/virtual/misc/fuse/power', 0o755)
+f('sys/devices/virtual/misc/fuse/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/misc/hpet', 0o755)
+l('sys/devices/virtual/misc/hpet/subsystem', '../../../../class/misc')
+f('sys/devices/virtual/misc/hpet/dev', 0o644, b'10:228\n')
+f('sys/devices/virtual/misc/hpet/uevent', 0o644, b'''MAJOR=10
+MINOR=228
+''')
+d('sys/devices/virtual/misc/hpet/power', 0o755)
+f('sys/devices/virtual/misc/hpet/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/misc/cpu_dma_latency', 0o755)
+l('sys/devices/virtual/misc/cpu_dma_latency/subsystem', '../../../../class/misc')
+f('sys/devices/virtual/misc/cpu_dma_latency/dev', 0o644, b'10:63\n')
+f('sys/devices/virtual/misc/cpu_dma_latency/uevent', 0o644, b'''MAJOR=10
+MINOR=63
+''')
+d('sys/devices/virtual/misc/cpu_dma_latency/power', 0o755)
+f('sys/devices/virtual/misc/cpu_dma_latency/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/misc/mcelog', 0o755)
+l('sys/devices/virtual/misc/mcelog/subsystem', '../../../../class/misc')
+f('sys/devices/virtual/misc/mcelog/dev', 0o644, b'10:227\n')
+f('sys/devices/virtual/misc/mcelog/uevent', 0o644, b'''MAJOR=10
+MINOR=227
+''')
+d('sys/devices/virtual/misc/mcelog/power', 0o755)
+f('sys/devices/virtual/misc/mcelog/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/misc/device-mapper', 0o755)
+l('sys/devices/virtual/misc/device-mapper/subsystem', '../../../../class/misc')
+f('sys/devices/virtual/misc/device-mapper/dev', 0o644, b'10:60\n')
+f('sys/devices/virtual/misc/device-mapper/uevent', 0o644, b'''MAJOR=10
+MINOR=60
+''')
+d('sys/devices/virtual/misc/device-mapper/power', 0o755)
+f('sys/devices/virtual/misc/device-mapper/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/misc/psaux', 0o755)
+l('sys/devices/virtual/misc/psaux/subsystem', '../../../../class/misc')
+f('sys/devices/virtual/misc/psaux/dev', 0o644, b'10:1\n')
+f('sys/devices/virtual/misc/psaux/uevent', 0o644, b'''MAJOR=10
+MINOR=1
+''')
+d('sys/devices/virtual/misc/psaux/power', 0o755)
+f('sys/devices/virtual/misc/psaux/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/misc/misc-fake1', 0o755)
+l('sys/devices/virtual/misc/misc-fake1/subsystem', '../../../../class/misc')
+f('sys/devices/virtual/misc/misc-fake1/dev', 0o644, b'4095:1\n')
+f('sys/devices/virtual/misc/misc-fake1/uevent', 0o644, b'''MAJOR=4095
+MINOR=1
+DEVNAME=misc-fake1
+
+''')
+d('sys/devices/virtual/misc/misc-fake1/power', 0o755)
+f('sys/devices/virtual/misc/misc-fake1/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/misc/nvram', 0o755)
+l('sys/devices/virtual/misc/nvram/subsystem', '../../../../class/misc')
+f('sys/devices/virtual/misc/nvram/dev', 0o644, b'10:144\n')
+f('sys/devices/virtual/misc/nvram/uevent', 0o644, b'''MAJOR=10
+MINOR=144
+''')
+d('sys/devices/virtual/misc/nvram/power', 0o755)
+f('sys/devices/virtual/misc/nvram/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/misc/network_latency', 0o755)
+l('sys/devices/virtual/misc/network_latency/subsystem', '../../../../class/misc')
+f('sys/devices/virtual/misc/network_latency/dev', 0o644, b'10:62\n')
+f('sys/devices/virtual/misc/network_latency/uevent', 0o644, b'''MAJOR=10
+MINOR=62
+''')
+d('sys/devices/virtual/misc/network_latency/power', 0o755)
+f('sys/devices/virtual/misc/network_latency/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/misc/network_throughput', 0o755)
+l('sys/devices/virtual/misc/network_throughput/subsystem', '../../../../class/misc')
+f('sys/devices/virtual/misc/network_throughput/dev', 0o644, b'10:61\n')
+f('sys/devices/virtual/misc/network_throughput/uevent', 0o644, b'''MAJOR=10
+MINOR=61
+''')
+d('sys/devices/virtual/misc/network_throughput/power', 0o755)
+f('sys/devices/virtual/misc/network_throughput/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/misc/microcode', 0o755)
+l('sys/devices/virtual/misc/microcode/subsystem', '../../../../class/misc')
+f('sys/devices/virtual/misc/microcode/dev', 0o644, b'10:184\n')
+f('sys/devices/virtual/misc/microcode/uevent', 0o644, b'''MAJOR=10
+MINOR=184
+''')
+d('sys/devices/virtual/misc/microcode/power', 0o755)
+f('sys/devices/virtual/misc/microcode/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/vtconsole', 0o755)
+d('sys/devices/virtual/vtconsole/vtcon1', 0o755)
+l('sys/devices/virtual/vtconsole/vtcon1/subsystem', '../../../../class/vtconsole')
+f('sys/devices/virtual/vtconsole/vtcon1/bind', 0o644, b'1\n')
+f('sys/devices/virtual/vtconsole/vtcon1/name', 0o644, b'(M) frame buffer device\n')
+f('sys/devices/virtual/vtconsole/vtcon1/uevent', 0o644, b'')
+d('sys/devices/virtual/vtconsole/vtcon1/power', 0o755)
+f('sys/devices/virtual/vtconsole/vtcon1/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/vtconsole/vtcon0', 0o755)
+l('sys/devices/virtual/vtconsole/vtcon0/subsystem', '../../../../class/vtconsole')
+f('sys/devices/virtual/vtconsole/vtcon0/bind', 0o644, b'0\n')
+f('sys/devices/virtual/vtconsole/vtcon0/name', 0o644, b'(S) dummy device\n')
+f('sys/devices/virtual/vtconsole/vtcon0/uevent', 0o644, b'')
+d('sys/devices/virtual/vtconsole/vtcon0/power', 0o755)
+f('sys/devices/virtual/vtconsole/vtcon0/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/input', 0o755)
+d('sys/devices/virtual/input/mice', 0o755)
+l('sys/devices/virtual/input/mice/subsystem', '../../../../class/input')
+f('sys/devices/virtual/input/mice/dev', 0o644, b'13:63\n')
+f('sys/devices/virtual/input/mice/uevent', 0o644, b'''MAJOR=13
+MINOR=63
+''')
+d('sys/devices/virtual/input/mice/power', 0o755)
+f('sys/devices/virtual/input/mice/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/input/input6', 0o755)
+l('sys/devices/virtual/input/input6/subsystem', '../../../../class/input')
+f('sys/devices/virtual/input/input6/uniq', 0o644, b'\n')
+f('sys/devices/virtual/input/input6/phys', 0o644, b'thinkpad_acpi/input0\n')
+f('sys/devices/virtual/input/input6/modalias', 0o644, b'input:b0019v17AAp5054e4101-e0,1,4,5,k71,72,73,8E,98,C0,C2,CD,E0,E1,E3,E4,EC,F0,168,174,181,1D2,1D7,1DB,1DC,ram4,lsfw3,\n')
+f('sys/devices/virtual/input/input6/name', 0o644, b'ThinkPad Extra Buttons\n')
+f('sys/devices/virtual/input/input6/uevent', 0o644, b'''PRODUCT=19/17aa/5054/4101
+NAME="ThinkPad Extra Buttons"
+PHYS="thinkpad_acpi/input0"
+EV==33
+KEY==18840000 2 10010000000000 0 1101b00002005 1004000 e000000000000 0
+MSC==10
+SW==8
+MODALIAS=input:b0019v17AAp5054e4101-e0,1,4,5,k71,72,73,8E,98,C0,C2,CD,E0,E1,E3,E4,EC,F0,168,174,181,1D2,1D7,1DB,1DC,ram4,lsfw3,
+''')
+d('sys/devices/virtual/input/input6/id', 0o755)
+f('sys/devices/virtual/input/input6/id/version', 0o644, b'4101\n')
+f('sys/devices/virtual/input/input6/id/product', 0o644, b'5054\n')
+f('sys/devices/virtual/input/input6/id/vendor', 0o644, b'17aa\n')
+f('sys/devices/virtual/input/input6/id/bustype', 0o644, b'0019\n')
+d('sys/devices/virtual/input/input6/power', 0o755)
+f('sys/devices/virtual/input/input6/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/input/input6/event6', 0o755)
+l('sys/devices/virtual/input/input6/event6/subsystem', '../../../../../class/input')
+l('sys/devices/virtual/input/input6/event6/device', '../../input6')
+f('sys/devices/virtual/input/input6/event6/dev', 0o644, b'13:70\n')
+f('sys/devices/virtual/input/input6/event6/uevent', 0o644, b'''MAJOR=13
+MINOR=70
+''')
+d('sys/devices/virtual/input/input6/event6/power', 0o755)
+f('sys/devices/virtual/input/input6/event6/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/input/input6/capabilities', 0o755)
+f('sys/devices/virtual/input/input6/capabilities/msc', 0o644, b'10\n')
+f('sys/devices/virtual/input/input6/capabilities/abs', 0o644, b'0\n')
+f('sys/devices/virtual/input/input6/capabilities/snd', 0o644, b'0\n')
+f('sys/devices/virtual/input/input6/capabilities/ff', 0o644, b'0\n')
+f('sys/devices/virtual/input/input6/capabilities/key', 0o644, b'18840000 2 10010000000000 0 1101b00002005 1004000 e000000000000 0\n')
+f('sys/devices/virtual/input/input6/capabilities/rel', 0o644, b'0\n')
+f('sys/devices/virtual/input/input6/capabilities/sw', 0o644, b'8\n')
+f('sys/devices/virtual/input/input6/capabilities/ev', 0o644, b'33\n')
+f('sys/devices/virtual/input/input6/capabilities/led', 0o644, b'0\n')
+d('sys/devices/virtual/thermal', 0o755)
+d('sys/devices/virtual/thermal/thermal_zone1', 0o755)
+l('sys/devices/virtual/thermal/thermal_zone1/subsystem', '../../../../class/thermal')
+l('sys/devices/virtual/thermal/thermal_zone1/cdev1', '../cooling_device0')
+l('sys/devices/virtual/thermal/thermal_zone1/cdev0', '../cooling_device1')
+l('sys/devices/virtual/thermal/thermal_zone1/device', '../../../LNXSYSTM:00/LNXTHERM:00/LNXTHERM:02')
+f('sys/devices/virtual/thermal/thermal_zone1/trip_point_0_type', 0o644, b'critical\n')
+f('sys/devices/virtual/thermal/thermal_zone1/trip_point_0_temp', 0o644, b'100000\n')
+f('sys/devices/virtual/thermal/thermal_zone1/trip_point_1_temp', 0o644, b'95500\n')
+f('sys/devices/virtual/thermal/thermal_zone1/type', 0o644, b'acpitz\n')
+f('sys/devices/virtual/thermal/thermal_zone1/cdev1_trip_point', 0o644, b'1\n')
+f('sys/devices/virtual/thermal/thermal_zone1/mode', 0o644, b'kernel\n')
+f('sys/devices/virtual/thermal/thermal_zone1/temp', 0o644, b'47000\n')
+f('sys/devices/virtual/thermal/thermal_zone1/cdev0_trip_point', 0o644, b'1\n')
+f('sys/devices/virtual/thermal/thermal_zone1/uevent', 0o644, b'')
+f('sys/devices/virtual/thermal/thermal_zone1/trip_point_1_type', 0o644, b'passive\n')
+d('sys/devices/virtual/thermal/thermal_zone1/power', 0o755)
+f('sys/devices/virtual/thermal/thermal_zone1/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/thermal/cooling_device1', 0o755)
+l('sys/devices/virtual/thermal/cooling_device1/subsystem', '../../../../class/thermal')
+l('sys/devices/virtual/thermal/cooling_device1/device', '../../../LNXSYSTM:00/ACPI0007:01')
+f('sys/devices/virtual/thermal/cooling_device1/type', 0o644, b'Processor\n')
+f('sys/devices/virtual/thermal/cooling_device1/max_state', 0o644, b'10\n')
+f('sys/devices/virtual/thermal/cooling_device1/cur_state', 0o644, b'0\n')
+f('sys/devices/virtual/thermal/cooling_device1/uevent', 0o644, b'')
+d('sys/devices/virtual/thermal/cooling_device1/power', 0o755)
+f('sys/devices/virtual/thermal/cooling_device1/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/thermal/cooling_device0', 0o755)
+l('sys/devices/virtual/thermal/cooling_device0/subsystem', '../../../../class/thermal')
+l('sys/devices/virtual/thermal/cooling_device0/device', '../../../LNXSYSTM:00/ACPI0007:00')
+f('sys/devices/virtual/thermal/cooling_device0/type', 0o644, b'Processor\n')
+f('sys/devices/virtual/thermal/cooling_device0/max_state', 0o644, b'10\n')
+f('sys/devices/virtual/thermal/cooling_device0/cur_state', 0o644, b'0\n')
+f('sys/devices/virtual/thermal/cooling_device0/uevent', 0o644, b'')
+d('sys/devices/virtual/thermal/cooling_device0/power', 0o755)
+f('sys/devices/virtual/thermal/cooling_device0/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/thermal/thermal_zone0', 0o755)
+l('sys/devices/virtual/thermal/thermal_zone0/subsystem', '../../../../class/thermal')
+l('sys/devices/virtual/thermal/thermal_zone0/device', '../../../LNXSYSTM:00/LNXTHERM:00/LNXTHERM:01')
+f('sys/devices/virtual/thermal/thermal_zone0/trip_point_0_type', 0o644, b'critical\n')
+f('sys/devices/virtual/thermal/thermal_zone0/trip_point_0_temp', 0o644, b'127000\n')
+f('sys/devices/virtual/thermal/thermal_zone0/type', 0o644, b'acpitz\n')
+f('sys/devices/virtual/thermal/thermal_zone0/mode', 0o644, b'kernel\n')
+f('sys/devices/virtual/thermal/thermal_zone0/temp', 0o644, b'46000\n')
+f('sys/devices/virtual/thermal/thermal_zone0/uevent', 0o644, b'')
+d('sys/devices/virtual/thermal/thermal_zone0/power', 0o755)
+f('sys/devices/virtual/thermal/thermal_zone0/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/block', 0o755)
+d('sys/devices/virtual/block/loop1', 0o755)
+l('sys/devices/virtual/block/loop1/subsystem', '../../../../class/block')
+l('sys/devices/virtual/block/loop1/bdi', '../../bdi/7:1')
+f('sys/devices/virtual/block/loop1/capability', 0o644, b'10\n')
+f('sys/devices/virtual/block/loop1/ro', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop1/make-it-fail', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop1/size', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop1/dev', 0o644, b'7:1\n')
+f('sys/devices/virtual/block/loop1/range', 0o644, b'1\n')
+f('sys/devices/virtual/block/loop1/removable', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop1/stat', 0o644, b' 0 0 0 0 0 0 0 0 0 0 0\n')
+f('sys/devices/virtual/block/loop1/uevent', 0o644, b'''MAJOR=7
+MINOR=1
+DEVTYPE=disk
+''')
+d('sys/devices/virtual/block/loop1/power', 0o755)
+f('sys/devices/virtual/block/loop1/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/block/loop7', 0o755)
+l('sys/devices/virtual/block/loop7/subsystem', '../../../../class/block')
+l('sys/devices/virtual/block/loop7/bdi', '../../bdi/7:7')
+f('sys/devices/virtual/block/loop7/capability', 0o644, b'10\n')
+f('sys/devices/virtual/block/loop7/ro', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop7/make-it-fail', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop7/size', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop7/dev', 0o644, b'7:7\n')
+f('sys/devices/virtual/block/loop7/range', 0o644, b'1\n')
+f('sys/devices/virtual/block/loop7/removable', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop7/stat', 0o644, b' 0 0 0 0 0 0 0 0 0 0 0\n')
+f('sys/devices/virtual/block/loop7/uevent', 0o644, b'''MAJOR=7
+MINOR=7
+DEVTYPE=disk
+''')
+d('sys/devices/virtual/block/loop7/power', 0o755)
+f('sys/devices/virtual/block/loop7/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/block/loop0', 0o755)
+l('sys/devices/virtual/block/loop0/subsystem', '../../../../class/block')
+l('sys/devices/virtual/block/loop0/bdi', '../../bdi/7:0')
+f('sys/devices/virtual/block/loop0/capability', 0o644, b'10\n')
+f('sys/devices/virtual/block/loop0/ro', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop0/make-it-fail', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop0/size', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop0/dev', 0o644, b'7:0\n')
+f('sys/devices/virtual/block/loop0/range', 0o644, b'1\n')
+f('sys/devices/virtual/block/loop0/removable', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop0/stat', 0o644, b' 0 0 0 0 0 0 0 0 0 0 0\n')
+f('sys/devices/virtual/block/loop0/uevent', 0o644, b'''MAJOR=7
+MINOR=0
+DEVTYPE=disk
+''')
+d('sys/devices/virtual/block/loop0/power', 0o755)
+f('sys/devices/virtual/block/loop0/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/block/loop5', 0o755)
+l('sys/devices/virtual/block/loop5/subsystem', '../../../../class/block')
+l('sys/devices/virtual/block/loop5/bdi', '../../bdi/7:5')
+f('sys/devices/virtual/block/loop5/capability', 0o644, b'10\n')
+f('sys/devices/virtual/block/loop5/ro', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop5/make-it-fail', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop5/size', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop5/dev', 0o644, b'7:5\n')
+f('sys/devices/virtual/block/loop5/range', 0o644, b'1\n')
+f('sys/devices/virtual/block/loop5/removable', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop5/stat', 0o644, b' 0 0 0 0 0 0 0 0 0 0 0\n')
+f('sys/devices/virtual/block/loop5/uevent', 0o644, b'''MAJOR=7
+MINOR=5
+DEVTYPE=disk
+''')
+d('sys/devices/virtual/block/loop5/power', 0o755)
+f('sys/devices/virtual/block/loop5/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/block/loop3', 0o755)
+l('sys/devices/virtual/block/loop3/subsystem', '../../../../class/block')
+l('sys/devices/virtual/block/loop3/bdi', '../../bdi/7:3')
+f('sys/devices/virtual/block/loop3/capability', 0o644, b'10\n')
+f('sys/devices/virtual/block/loop3/ro', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop3/make-it-fail', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop3/size', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop3/dev', 0o644, b'7:3\n')
+f('sys/devices/virtual/block/loop3/range', 0o644, b'1\n')
+f('sys/devices/virtual/block/loop3/removable', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop3/stat', 0o644, b' 0 0 0 0 0 0 0 0 0 0 0\n')
+f('sys/devices/virtual/block/loop3/uevent', 0o644, b'''MAJOR=7
+MINOR=3
+DEVTYPE=disk
+''')
+d('sys/devices/virtual/block/loop3/power', 0o755)
+f('sys/devices/virtual/block/loop3/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/block/loop6', 0o755)
+l('sys/devices/virtual/block/loop6/subsystem', '../../../../class/block')
+l('sys/devices/virtual/block/loop6/bdi', '../../bdi/7:6')
+f('sys/devices/virtual/block/loop6/capability', 0o644, b'10\n')
+f('sys/devices/virtual/block/loop6/ro', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop6/make-it-fail', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop6/size', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop6/dev', 0o644, b'7:6\n')
+f('sys/devices/virtual/block/loop6/range', 0o644, b'1\n')
+f('sys/devices/virtual/block/loop6/removable', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop6/stat', 0o644, b' 0 0 0 0 0 0 0 0 0 0 0\n')
+f('sys/devices/virtual/block/loop6/uevent', 0o644, b'''MAJOR=7
+MINOR=6
+DEVTYPE=disk
+''')
+d('sys/devices/virtual/block/loop6/power', 0o755)
+f('sys/devices/virtual/block/loop6/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/block/loop2', 0o755)
+l('sys/devices/virtual/block/loop2/subsystem', '../../../../class/block')
+l('sys/devices/virtual/block/loop2/bdi', '../../bdi/7:2')
+f('sys/devices/virtual/block/loop2/capability', 0o644, b'10\n')
+f('sys/devices/virtual/block/loop2/ro', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop2/make-it-fail', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop2/size', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop2/dev', 0o644, b'7:2\n')
+f('sys/devices/virtual/block/loop2/range', 0o644, b'1\n')
+f('sys/devices/virtual/block/loop2/removable', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop2/stat', 0o644, b' 0 0 0 0 0 0 0 0 0 0 0\n')
+f('sys/devices/virtual/block/loop2/uevent', 0o644, b'''MAJOR=7
+MINOR=2
+DEVTYPE=disk
+''')
+d('sys/devices/virtual/block/loop2/power', 0o755)
+f('sys/devices/virtual/block/loop2/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/block/fake!blockdev0', 0o755)
+l('sys/devices/virtual/block/fake!blockdev0/subsystem', '../../../../class/block')
+f('sys/devices/virtual/block/fake!blockdev0/capability', 0o644, b'10\n')
+f('sys/devices/virtual/block/fake!blockdev0/ro', 0o644, b'0\n')
+f('sys/devices/virtual/block/fake!blockdev0/size', 0o644, b'0\n')
+f('sys/devices/virtual/block/fake!blockdev0/dev', 0o644, b'711:0\n')
+f('sys/devices/virtual/block/fake!blockdev0/range', 0o644, b'1\n')
+f('sys/devices/virtual/block/fake!blockdev0/removable', 0o644, b'0\n')
+f('sys/devices/virtual/block/fake!blockdev0/stat', 0o644, b' 0 0 0 0 0 0 0 0 0 0 0\n')
+f('sys/devices/virtual/block/fake!blockdev0/uevent', 0o644, b'''MAJOR=7
+MINOR=0
+DEVTYPE=disk
+DEVNAME=fake/blockdev0
+''')
+d('sys/devices/virtual/block/loop4', 0o755)
+l('sys/devices/virtual/block/loop4/subsystem', '../../../../class/block')
+l('sys/devices/virtual/block/loop4/bdi', '../../bdi/7:4')
+f('sys/devices/virtual/block/loop4/capability', 0o644, b'10\n')
+f('sys/devices/virtual/block/loop4/ro', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop4/make-it-fail', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop4/size', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop4/dev', 0o644, b'7:4\n')
+f('sys/devices/virtual/block/loop4/range', 0o644, b'1\n')
+f('sys/devices/virtual/block/loop4/removable', 0o644, b'0\n')
+f('sys/devices/virtual/block/loop4/stat', 0o644, b' 0 0 0 0 0 0 0 0 0 0 0\n')
+f('sys/devices/virtual/block/loop4/uevent', 0o644, b'''MAJOR=7
+MINOR=4
+DEVTYPE=disk
+''')
+d('sys/devices/virtual/block/loop4/power', 0o755)
+f('sys/devices/virtual/block/loop4/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/block/md0', 0o755)
+l('sys/devices/virtual/block/md0/subsystem', '../../../../class/block')
+l('sys/devices/virtual/block/md0/bdi', '../../bdi/9:0')
+f('sys/devices/virtual/block/md0/capability', 0o644, b'10\n')
+f('sys/devices/virtual/block/md0/ro', 0o644, b'0\n')
+f('sys/devices/virtual/block/md0/make-it-fail', 0o644, b'0\n')
+f('sys/devices/virtual/block/md0/size', 0o644, b'19534848\n')
+f('sys/devices/virtual/block/md0/dev', 0o644, b'9:0\n')
+f('sys/devices/virtual/block/md0/range', 0o644, b'1\n')
+f('sys/devices/virtual/block/md0/removable', 0o644, b'0\n')
+f('sys/devices/virtual/block/md0/stat', 0o644, b' 60 0 480 0 0 0 0 0 0 0 0\n')
+f('sys/devices/virtual/block/md0/uevent', 0o644, b'''MAJOR=9
+MINOR=0
+DEVTYPE=disk
+''')
+d('sys/devices/virtual/block/md0/power', 0o755)
+f('sys/devices/virtual/block/md0/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/block/md0/md', 0o755)
+l('sys/devices/virtual/block/md0/md/rd1', 'dev-sda9')
+f('sys/devices/virtual/block/md0/md/chunk_size', 0o644, b'0\n')
+f('sys/devices/virtual/block/md0/md/sync_action', 0o644, b'idle\n')
+f('sys/devices/virtual/block/md0/md/sync_speed_min', 0o644, b'1000 (system)\n')
+f('sys/devices/virtual/block/md0/md/sync_force_parallel', 0o644, b'0\n')
+f('sys/devices/virtual/block/md0/md/sync_min', 0o644, b'0\n')
+f('sys/devices/virtual/block/md0/md/mismatch_cnt', 0o644, b'0\n')
+f('sys/devices/virtual/block/md0/md/suspend_hi', 0o644, b'0\n')
+f('sys/devices/virtual/block/md0/md/sync_completed', 0o644, b'0 / 19534848\n')
+f('sys/devices/virtual/block/md0/md/sync_max', 0o644, b'max\n')
+f('sys/devices/virtual/block/md0/md/safe_mode_delay', 0o644, b'0.201\n')
+f('sys/devices/virtual/block/md0/md/degraded', 0o644, b'1\n')
+f('sys/devices/virtual/block/md0/md/component_size', 0o644, b'9767424\n')
+f('sys/devices/virtual/block/md0/md/suspend_lo', 0o644, b'0\n')
+f('sys/devices/virtual/block/md0/md/resync_start', 0o644, b'18446744073709551615\n')
+f('sys/devices/virtual/block/md0/md/sync_speed', 0o644, b'0\n')
+f('sys/devices/virtual/block/md0/md/reshape_position', 0o644, b'none\n')
+f('sys/devices/virtual/block/md0/md/array_state', 0o644, b'clean\n')
+f('sys/devices/virtual/block/md0/md/sync_speed_max', 0o644, b'200000 (system)\n')
+f('sys/devices/virtual/block/md0/md/level', 0o644, b'raid1\n')
+f('sys/devices/virtual/block/md0/md/layout', 0o644, b'0\n')
+f('sys/devices/virtual/block/md0/md/raid_disks', 0o644, b'2\n')
+f('sys/devices/virtual/block/md0/md/metadata_version', 0o644, b'0.90\n')
+d('sys/devices/virtual/block/md0/md/dev-sda9', 0o755)
+l('sys/devices/virtual/block/md0/md/dev-sda9/block', '../../../../../pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9')
+f('sys/devices/virtual/block/md0/md/dev-sda9/slot', 0o644, b'1\n')
+f('sys/devices/virtual/block/md0/md/dev-sda9/size', 0o644, b'23438720\n')
+f('sys/devices/virtual/block/md0/md/dev-sda9/state', 0o644, b'in_sync\n')
+f('sys/devices/virtual/block/md0/md/dev-sda9/errors', 0o644, b'0\n')
+f('sys/devices/virtual/block/md0/md/dev-sda9/offset', 0o644, b'0\n')
+d('sys/devices/virtual/block/md0/slaves', 0o755)
+l('sys/devices/virtual/block/md0/slaves/sda9', '../../../../pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9')
+d('sys/devices/virtual/graphics', 0o755)
+d('sys/devices/virtual/graphics/fbcon', 0o755)
+l('sys/devices/virtual/graphics/fbcon/subsystem', '../../../../class/graphics')
+f('sys/devices/virtual/graphics/fbcon/cursor_blink', 0o644, b'0\n')
+f('sys/devices/virtual/graphics/fbcon/rotate', 0o644, b'0\n')
+f('sys/devices/virtual/graphics/fbcon/uevent', 0o644, b'')
+d('sys/devices/virtual/graphics/fbcon/power', 0o755)
+f('sys/devices/virtual/graphics/fbcon/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty', 0o755)
+d('sys/devices/virtual/tty/tty51', 0o755)
+l('sys/devices/virtual/tty/tty51/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty51/dev', 0o644, b'4:51\n')
+f('sys/devices/virtual/tty/tty51/uevent', 0o644, b'''MAJOR=4
+MINOR=51
+''')
+d('sys/devices/virtual/tty/tty51/power', 0o755)
+f('sys/devices/virtual/tty/tty51/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty24', 0o755)
+l('sys/devices/virtual/tty/tty24/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty24/dev', 0o644, b'4:24\n')
+f('sys/devices/virtual/tty/tty24/uevent', 0o644, b'''MAJOR=4
+MINOR=24
+''')
+d('sys/devices/virtual/tty/tty24/power', 0o755)
+f('sys/devices/virtual/tty/tty24/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty61', 0o755)
+l('sys/devices/virtual/tty/tty61/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty61/dev', 0o644, b'4:61\n')
+f('sys/devices/virtual/tty/tty61/uevent', 0o644, b'''MAJOR=4
+MINOR=61
+''')
+d('sys/devices/virtual/tty/tty61/power', 0o755)
+f('sys/devices/virtual/tty/tty61/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty40', 0o755)
+l('sys/devices/virtual/tty/tty40/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty40/dev', 0o644, b'4:40\n')
+f('sys/devices/virtual/tty/tty40/uevent', 0o644, b'''MAJOR=4
+MINOR=40
+''')
+d('sys/devices/virtual/tty/tty40/power', 0o755)
+f('sys/devices/virtual/tty/tty40/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty60', 0o755)
+l('sys/devices/virtual/tty/tty60/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty60/dev', 0o644, b'4:60\n')
+f('sys/devices/virtual/tty/tty60/uevent', 0o644, b'''MAJOR=4
+MINOR=60
+''')
+d('sys/devices/virtual/tty/tty60/power', 0o755)
+f('sys/devices/virtual/tty/tty60/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty15', 0o755)
+l('sys/devices/virtual/tty/tty15/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty15/dev', 0o644, b'4:15\n')
+f('sys/devices/virtual/tty/tty15/uevent', 0o644, b'''MAJOR=4
+MINOR=15
+''')
+d('sys/devices/virtual/tty/tty15/power', 0o755)
+f('sys/devices/virtual/tty/tty15/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty27', 0o755)
+l('sys/devices/virtual/tty/tty27/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty27/dev', 0o644, b'4:27\n')
+f('sys/devices/virtual/tty/tty27/uevent', 0o644, b'''MAJOR=4
+MINOR=27
+''')
+d('sys/devices/virtual/tty/tty27/power', 0o755)
+f('sys/devices/virtual/tty/tty27/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty7', 0o755)
+l('sys/devices/virtual/tty/tty7/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty7/dev', 0o644, b'4:7\n')
+f('sys/devices/virtual/tty/tty7/uevent', 0o644, b'''MAJOR=4
+MINOR=7
+''')
+d('sys/devices/virtual/tty/tty7/power', 0o755)
+f('sys/devices/virtual/tty/tty7/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty43', 0o755)
+l('sys/devices/virtual/tty/tty43/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty43/dev', 0o644, b'4:43\n')
+f('sys/devices/virtual/tty/tty43/uevent', 0o644, b'''MAJOR=4
+MINOR=43
+''')
+d('sys/devices/virtual/tty/tty43/power', 0o755)
+f('sys/devices/virtual/tty/tty43/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty23', 0o755)
+l('sys/devices/virtual/tty/tty23/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty23/dev', 0o644, b'4:23\n')
+f('sys/devices/virtual/tty/tty23/uevent', 0o644, b'''MAJOR=4
+MINOR=23
+''')
+d('sys/devices/virtual/tty/tty23/power', 0o755)
+f('sys/devices/virtual/tty/tty23/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty14', 0o755)
+l('sys/devices/virtual/tty/tty14/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty14/dev', 0o644, b'4:14\n')
+f('sys/devices/virtual/tty/tty14/uevent', 0o644, b'''MAJOR=4
+MINOR=14
+''')
+d('sys/devices/virtual/tty/tty14/power', 0o755)
+f('sys/devices/virtual/tty/tty14/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty56', 0o755)
+l('sys/devices/virtual/tty/tty56/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty56/dev', 0o644, b'4:56\n')
+f('sys/devices/virtual/tty/tty56/uevent', 0o644, b'''MAJOR=4
+MINOR=56
+''')
+d('sys/devices/virtual/tty/tty56/power', 0o755)
+f('sys/devices/virtual/tty/tty56/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty3', 0o755)
+l('sys/devices/virtual/tty/tty3/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty3/dev', 0o644, b'4:3\n')
+f('sys/devices/virtual/tty/tty3/uevent', 0o644, b'''MAJOR=4
+MINOR=3
+''')
+d('sys/devices/virtual/tty/tty3/power', 0o755)
+f('sys/devices/virtual/tty/tty3/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty49', 0o755)
+l('sys/devices/virtual/tty/tty49/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty49/dev', 0o644, b'4:49\n')
+f('sys/devices/virtual/tty/tty49/uevent', 0o644, b'''MAJOR=4
+MINOR=49
+''')
+d('sys/devices/virtual/tty/tty49/power', 0o755)
+f('sys/devices/virtual/tty/tty49/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty47', 0o755)
+l('sys/devices/virtual/tty/tty47/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty47/dev', 0o644, b'4:47\n')
+f('sys/devices/virtual/tty/tty47/uevent', 0o644, b'''MAJOR=4
+MINOR=47
+''')
+d('sys/devices/virtual/tty/tty47/power', 0o755)
+f('sys/devices/virtual/tty/tty47/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty57', 0o755)
+l('sys/devices/virtual/tty/tty57/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty57/dev', 0o644, b'4:57\n')
+f('sys/devices/virtual/tty/tty57/uevent', 0o644, b'''MAJOR=4
+MINOR=57
+''')
+d('sys/devices/virtual/tty/tty57/power', 0o755)
+f('sys/devices/virtual/tty/tty57/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty30', 0o755)
+l('sys/devices/virtual/tty/tty30/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty30/dev', 0o644, b'4:30\n')
+f('sys/devices/virtual/tty/tty30/uevent', 0o644, b'''MAJOR=4
+MINOR=30
+''')
+d('sys/devices/virtual/tty/tty30/power', 0o755)
+f('sys/devices/virtual/tty/tty30/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty45', 0o755)
+l('sys/devices/virtual/tty/tty45/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty45/dev', 0o644, b'4:45\n')
+f('sys/devices/virtual/tty/tty45/uevent', 0o644, b'''MAJOR=4
+MINOR=45
+''')
+d('sys/devices/virtual/tty/tty45/power', 0o755)
+f('sys/devices/virtual/tty/tty45/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty22', 0o755)
+l('sys/devices/virtual/tty/tty22/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty22/dev', 0o644, b'4:22\n')
+f('sys/devices/virtual/tty/tty22/uevent', 0o644, b'''MAJOR=4
+MINOR=22
+''')
+d('sys/devices/virtual/tty/tty22/power', 0o755)
+f('sys/devices/virtual/tty/tty22/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty55', 0o755)
+l('sys/devices/virtual/tty/tty55/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty55/dev', 0o644, b'4:55\n')
+f('sys/devices/virtual/tty/tty55/uevent', 0o644, b'''MAJOR=4
+MINOR=55
+''')
+d('sys/devices/virtual/tty/tty55/power', 0o755)
+f('sys/devices/virtual/tty/tty55/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty11', 0o755)
+l('sys/devices/virtual/tty/tty11/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty11/dev', 0o644, b'4:11\n')
+f('sys/devices/virtual/tty/tty11/uevent', 0o644, b'''MAJOR=4
+MINOR=11
+''')
+d('sys/devices/virtual/tty/tty11/power', 0o755)
+f('sys/devices/virtual/tty/tty11/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty53', 0o755)
+l('sys/devices/virtual/tty/tty53/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty53/dev', 0o644, b'4:53\n')
+f('sys/devices/virtual/tty/tty53/uevent', 0o644, b'''MAJOR=4
+MINOR=53
+''')
+d('sys/devices/virtual/tty/tty53/power', 0o755)
+f('sys/devices/virtual/tty/tty53/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty12', 0o755)
+l('sys/devices/virtual/tty/tty12/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty12/dev', 0o644, b'4:12\n')
+f('sys/devices/virtual/tty/tty12/uevent', 0o644, b'''MAJOR=4
+MINOR=12
+''')
+d('sys/devices/virtual/tty/tty12/power', 0o755)
+f('sys/devices/virtual/tty/tty12/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty28', 0o755)
+l('sys/devices/virtual/tty/tty28/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty28/dev', 0o644, b'4:28\n')
+f('sys/devices/virtual/tty/tty28/uevent', 0o644, b'''MAJOR=4
+MINOR=28
+''')
+d('sys/devices/virtual/tty/tty28/power', 0o755)
+f('sys/devices/virtual/tty/tty28/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty58', 0o755)
+l('sys/devices/virtual/tty/tty58/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty58/dev', 0o644, b'4:58\n')
+f('sys/devices/virtual/tty/tty58/uevent', 0o644, b'''MAJOR=4
+MINOR=58
+''')
+d('sys/devices/virtual/tty/tty58/power', 0o755)
+f('sys/devices/virtual/tty/tty58/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty32', 0o755)
+l('sys/devices/virtual/tty/tty32/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty32/dev', 0o644, b'4:32\n')
+f('sys/devices/virtual/tty/tty32/uevent', 0o644, b'''MAJOR=4
+MINOR=32
+''')
+d('sys/devices/virtual/tty/tty32/power', 0o755)
+f('sys/devices/virtual/tty/tty32/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty44', 0o755)
+l('sys/devices/virtual/tty/tty44/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty44/dev', 0o644, b'4:44\n')
+f('sys/devices/virtual/tty/tty44/uevent', 0o644, b'''MAJOR=4
+MINOR=44
+''')
+d('sys/devices/virtual/tty/tty44/power', 0o755)
+f('sys/devices/virtual/tty/tty44/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty6', 0o755)
+l('sys/devices/virtual/tty/tty6/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty6/dev', 0o644, b'4:6\n')
+f('sys/devices/virtual/tty/tty6/uevent', 0o644, b'''MAJOR=4
+MINOR=6
+''')
+d('sys/devices/virtual/tty/tty6/power', 0o755)
+f('sys/devices/virtual/tty/tty6/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty9', 0o755)
+l('sys/devices/virtual/tty/tty9/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty9/dev', 0o644, b'4:9\n')
+f('sys/devices/virtual/tty/tty9/uevent', 0o644, b'''MAJOR=4
+MINOR=9
+''')
+d('sys/devices/virtual/tty/tty9/power', 0o755)
+f('sys/devices/virtual/tty/tty9/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty26', 0o755)
+l('sys/devices/virtual/tty/tty26/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty26/dev', 0o644, b'4:26\n')
+f('sys/devices/virtual/tty/tty26/uevent', 0o644, b'''MAJOR=4
+MINOR=26
+''')
+d('sys/devices/virtual/tty/tty26/power', 0o755)
+f('sys/devices/virtual/tty/tty26/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty10', 0o755)
+l('sys/devices/virtual/tty/tty10/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty10/dev', 0o644, b'4:10\n')
+f('sys/devices/virtual/tty/tty10/uevent', 0o644, b'''MAJOR=4
+MINOR=10
+''')
+d('sys/devices/virtual/tty/tty10/power', 0o755)
+f('sys/devices/virtual/tty/tty10/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty39', 0o755)
+l('sys/devices/virtual/tty/tty39/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty39/dev', 0o644, b'4:39\n')
+f('sys/devices/virtual/tty/tty39/uevent', 0o644, b'''MAJOR=4
+MINOR=39
+''')
+d('sys/devices/virtual/tty/tty39/power', 0o755)
+f('sys/devices/virtual/tty/tty39/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty0', 0o755)
+l('sys/devices/virtual/tty/tty0/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty0/dev', 0o644, b'4:0\n')
+f('sys/devices/virtual/tty/tty0/uevent', 0o644, b'''MAJOR=4
+MINOR=0
+DEVNAME=tty0
+''')
+d('sys/devices/virtual/tty/tty0/power', 0o755)
+f('sys/devices/virtual/tty/tty0/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty36', 0o755)
+l('sys/devices/virtual/tty/tty36/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty36/dev', 0o644, b'4:36\n')
+f('sys/devices/virtual/tty/tty36/uevent', 0o644, b'''MAJOR=4
+MINOR=36
+''')
+d('sys/devices/virtual/tty/tty36/power', 0o755)
+f('sys/devices/virtual/tty/tty36/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty34', 0o755)
+l('sys/devices/virtual/tty/tty34/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty34/dev', 0o644, b'4:34\n')
+f('sys/devices/virtual/tty/tty34/uevent', 0o644, b'''MAJOR=4
+MINOR=34
+''')
+d('sys/devices/virtual/tty/tty34/power', 0o755)
+f('sys/devices/virtual/tty/tty34/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty16', 0o755)
+l('sys/devices/virtual/tty/tty16/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty16/dev', 0o644, b'4:16\n')
+f('sys/devices/virtual/tty/tty16/uevent', 0o644, b'''MAJOR=4
+MINOR=16
+''')
+d('sys/devices/virtual/tty/tty16/power', 0o755)
+f('sys/devices/virtual/tty/tty16/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty25', 0o755)
+l('sys/devices/virtual/tty/tty25/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty25/dev', 0o644, b'4:25\n')
+f('sys/devices/virtual/tty/tty25/uevent', 0o644, b'''MAJOR=4
+MINOR=25
+''')
+d('sys/devices/virtual/tty/tty25/power', 0o755)
+f('sys/devices/virtual/tty/tty25/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty13', 0o755)
+l('sys/devices/virtual/tty/tty13/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty13/dev', 0o644, b'4:13\n')
+f('sys/devices/virtual/tty/tty13/uevent', 0o644, b'''MAJOR=4
+MINOR=13
+''')
+d('sys/devices/virtual/tty/tty13/power', 0o755)
+f('sys/devices/virtual/tty/tty13/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty52', 0o755)
+l('sys/devices/virtual/tty/tty52/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty52/dev', 0o644, b'4:52\n')
+f('sys/devices/virtual/tty/tty52/uevent', 0o644, b'''MAJOR=4
+MINOR=52
+''')
+d('sys/devices/virtual/tty/tty52/power', 0o755)
+f('sys/devices/virtual/tty/tty52/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty31', 0o755)
+l('sys/devices/virtual/tty/tty31/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty31/dev', 0o644, b'4:31\n')
+f('sys/devices/virtual/tty/tty31/uevent', 0o644, b'''MAJOR=4
+MINOR=31
+''')
+d('sys/devices/virtual/tty/tty31/power', 0o755)
+f('sys/devices/virtual/tty/tty31/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty35', 0o755)
+l('sys/devices/virtual/tty/tty35/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty35/dev', 0o644, b'4:35\n')
+f('sys/devices/virtual/tty/tty35/uevent', 0o644, b'''MAJOR=4
+MINOR=35
+''')
+d('sys/devices/virtual/tty/tty35/power', 0o755)
+f('sys/devices/virtual/tty/tty35/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty54', 0o755)
+l('sys/devices/virtual/tty/tty54/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty54/dev', 0o644, b'4:54\n')
+f('sys/devices/virtual/tty/tty54/uevent', 0o644, b'''MAJOR=4
+MINOR=54
+''')
+d('sys/devices/virtual/tty/tty54/power', 0o755)
+f('sys/devices/virtual/tty/tty54/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty63', 0o755)
+l('sys/devices/virtual/tty/tty63/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty63/dev', 0o644, b'4:63\n')
+f('sys/devices/virtual/tty/tty63/uevent', 0o644, b'''MAJOR=4
+MINOR=63
+''')
+d('sys/devices/virtual/tty/tty63/power', 0o755)
+f('sys/devices/virtual/tty/tty63/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty1', 0o755)
+l('sys/devices/virtual/tty/tty1/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty1/dev', 0o644, b'4:1\n')
+f('sys/devices/virtual/tty/tty1/uevent', 0o644, b'''MAJOR=4
+MINOR=1
+''')
+d('sys/devices/virtual/tty/tty1/power', 0o755)
+f('sys/devices/virtual/tty/tty1/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty33', 0o755)
+l('sys/devices/virtual/tty/tty33/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty33/dev', 0o644, b'4:33\n')
+f('sys/devices/virtual/tty/tty33/uevent', 0o644, b'''MAJOR=4
+MINOR=33
+DEVNAME=tty33
+''')
+d('sys/devices/virtual/tty/tty33/power', 0o755)
+f('sys/devices/virtual/tty/tty33/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty18', 0o755)
+l('sys/devices/virtual/tty/tty18/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty18/dev', 0o644, b'4:18\n')
+f('sys/devices/virtual/tty/tty18/uevent', 0o644, b'''MAJOR=4
+MINOR=18
+''')
+d('sys/devices/virtual/tty/tty18/power', 0o755)
+f('sys/devices/virtual/tty/tty18/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty42', 0o755)
+l('sys/devices/virtual/tty/tty42/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty42/dev', 0o644, b'4:42\n')
+f('sys/devices/virtual/tty/tty42/uevent', 0o644, b'''MAJOR=4
+MINOR=42
+''')
+d('sys/devices/virtual/tty/tty42/power', 0o755)
+f('sys/devices/virtual/tty/tty42/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty8', 0o755)
+l('sys/devices/virtual/tty/tty8/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty8/dev', 0o644, b'4:8\n')
+f('sys/devices/virtual/tty/tty8/uevent', 0o644, b'''MAJOR=4
+MINOR=8
+''')
+d('sys/devices/virtual/tty/tty8/power', 0o755)
+f('sys/devices/virtual/tty/tty8/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty37', 0o755)
+l('sys/devices/virtual/tty/tty37/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty37/dev', 0o644, b'4:37\n')
+f('sys/devices/virtual/tty/tty37/uevent', 0o644, b'''MAJOR=4
+MINOR=37
+''')
+d('sys/devices/virtual/tty/tty37/power', 0o755)
+f('sys/devices/virtual/tty/tty37/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty5', 0o755)
+l('sys/devices/virtual/tty/tty5/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty5/dev', 0o644, b'4:5\n')
+f('sys/devices/virtual/tty/tty5/uevent', 0o644, b'''MAJOR=4
+MINOR=5
+''')
+d('sys/devices/virtual/tty/tty5/power', 0o755)
+f('sys/devices/virtual/tty/tty5/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty48', 0o755)
+l('sys/devices/virtual/tty/tty48/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty48/dev', 0o644, b'4:48\n')
+f('sys/devices/virtual/tty/tty48/uevent', 0o644, b'''MAJOR=4
+MINOR=48
+''')
+d('sys/devices/virtual/tty/tty48/power', 0o755)
+f('sys/devices/virtual/tty/tty48/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty17', 0o755)
+l('sys/devices/virtual/tty/tty17/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty17/dev', 0o644, b'4:17\n')
+f('sys/devices/virtual/tty/tty17/uevent', 0o644, b'''MAJOR=4
+MINOR=17
+''')
+d('sys/devices/virtual/tty/tty17/power', 0o755)
+f('sys/devices/virtual/tty/tty17/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty62', 0o755)
+l('sys/devices/virtual/tty/tty62/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty62/dev', 0o644, b'4:62\n')
+f('sys/devices/virtual/tty/tty62/uevent', 0o644, b'''MAJOR=4
+MINOR=62
+''')
+d('sys/devices/virtual/tty/tty62/power', 0o755)
+f('sys/devices/virtual/tty/tty62/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty59', 0o755)
+l('sys/devices/virtual/tty/tty59/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty59/dev', 0o644, b'4:59\n')
+f('sys/devices/virtual/tty/tty59/uevent', 0o644, b'''MAJOR=4
+MINOR=59
+''')
+d('sys/devices/virtual/tty/tty59/power', 0o755)
+f('sys/devices/virtual/tty/tty59/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty50', 0o755)
+l('sys/devices/virtual/tty/tty50/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty50/dev', 0o644, b'4:50\n')
+f('sys/devices/virtual/tty/tty50/uevent', 0o644, b'''MAJOR=4
+MINOR=50
+''')
+d('sys/devices/virtual/tty/tty50/power', 0o755)
+f('sys/devices/virtual/tty/tty50/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty21', 0o755)
+l('sys/devices/virtual/tty/tty21/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty21/dev', 0o644, b'4:21\n')
+f('sys/devices/virtual/tty/tty21/uevent', 0o644, b'''MAJOR=4
+MINOR=21
+''')
+d('sys/devices/virtual/tty/tty21/power', 0o755)
+f('sys/devices/virtual/tty/tty21/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty19', 0o755)
+l('sys/devices/virtual/tty/tty19/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty19/dev', 0o644, b'4:19\n')
+f('sys/devices/virtual/tty/tty19/uevent', 0o644, b'''MAJOR=4
+MINOR=19
+''')
+d('sys/devices/virtual/tty/tty19/power', 0o755)
+f('sys/devices/virtual/tty/tty19/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/ptmx', 0o755)
+l('sys/devices/virtual/tty/ptmx/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/ptmx/dev', 0o644, b'5:2\n')
+f('sys/devices/virtual/tty/ptmx/uevent', 0o644, b'''MAJOR=5
+MINOR=2
+''')
+d('sys/devices/virtual/tty/ptmx/power', 0o755)
+f('sys/devices/virtual/tty/ptmx/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty46', 0o755)
+l('sys/devices/virtual/tty/tty46/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty46/dev', 0o644, b'4:46\n')
+f('sys/devices/virtual/tty/tty46/uevent', 0o644, b'''MAJOR=4
+MINOR=46
+''')
+d('sys/devices/virtual/tty/tty46/power', 0o755)
+f('sys/devices/virtual/tty/tty46/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty2', 0o755)
+l('sys/devices/virtual/tty/tty2/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty2/dev', 0o644, b'4:2\n')
+f('sys/devices/virtual/tty/tty2/uevent', 0o644, b'''MAJOR=4
+MINOR=2
+''')
+d('sys/devices/virtual/tty/tty2/power', 0o755)
+f('sys/devices/virtual/tty/tty2/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/console', 0o755)
+l('sys/devices/virtual/tty/console/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/console/dev', 0o644, b'5:1\n')
+f('sys/devices/virtual/tty/console/uevent', 0o644, b'''MAJOR=5
+MINOR=1
+DEVNAME=console
+''')
+d('sys/devices/virtual/tty/console/power', 0o755)
+f('sys/devices/virtual/tty/console/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty41', 0o755)
+l('sys/devices/virtual/tty/tty41/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty41/dev', 0o644, b'4:41\n')
+f('sys/devices/virtual/tty/tty41/uevent', 0o644, b'''MAJOR=4
+MINOR=41
+''')
+d('sys/devices/virtual/tty/tty41/power', 0o755)
+f('sys/devices/virtual/tty/tty41/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty4', 0o755)
+l('sys/devices/virtual/tty/tty4/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty4/dev', 0o644, b'4:4\n')
+f('sys/devices/virtual/tty/tty4/uevent', 0o644, b'''MAJOR=4
+MINOR=4
+''')
+d('sys/devices/virtual/tty/tty4/power', 0o755)
+f('sys/devices/virtual/tty/tty4/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty29', 0o755)
+l('sys/devices/virtual/tty/tty29/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty29/dev', 0o644, b'4:29\n')
+f('sys/devices/virtual/tty/tty29/uevent', 0o644, b'''MAJOR=4
+MINOR=29
+''')
+d('sys/devices/virtual/tty/tty29/power', 0o755)
+f('sys/devices/virtual/tty/tty29/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty', 0o755)
+l('sys/devices/virtual/tty/tty/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty/dev', 0o644, b'5:0\n')
+f('sys/devices/virtual/tty/tty/uevent', 0o644, b'''MAJOR=5
+MINOR=0
+''')
+d('sys/devices/virtual/tty/tty/power', 0o755)
+f('sys/devices/virtual/tty/tty/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty38', 0o755)
+l('sys/devices/virtual/tty/tty38/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty38/dev', 0o644, b'4:38\n')
+f('sys/devices/virtual/tty/tty38/uevent', 0o644, b'''MAJOR=4
+MINOR=38
+''')
+d('sys/devices/virtual/tty/tty38/power', 0o755)
+f('sys/devices/virtual/tty/tty38/power/wakeup', 0o644, b'\n')
+d('sys/devices/virtual/tty/tty20', 0o755)
+l('sys/devices/virtual/tty/tty20/subsystem', '../../../../class/tty')
+f('sys/devices/virtual/tty/tty20/dev', 0o644, b'4:20\n')
+f('sys/devices/virtual/tty/tty20/uevent', 0o644, b'''MAJOR=4
+MINOR=20
+''')
+d('sys/devices/virtual/tty/tty20/power', 0o755)
+f('sys/devices/virtual/tty/tty20/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00', 0o755)
+l('sys/devices/LNXSYSTM:00/subsystem', '../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/hid', 0o644, b'LNXSYSTM\n')
+f('sys/devices/LNXSYSTM:00/modalias', 0o644, b'acpi:LNXSYSTM:\n')
+f('sys/devices/LNXSYSTM:00/path', 0o644, b'\\\n')
+f('sys/devices/LNXSYSTM:00/uevent', 0o644, b'MODALIAS=acpi:LNXSYSTM:\n')
+d('sys/devices/LNXSYSTM:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/ACPI0007:01', 0o755)
+l('sys/devices/LNXSYSTM:00/ACPI0007:01/thermal_cooling', '../../virtual/thermal/cooling_device1')
+l('sys/devices/LNXSYSTM:00/ACPI0007:01/subsystem', '../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/ACPI0007:01/sysdev', '../../system/cpu/cpu1')
+l('sys/devices/LNXSYSTM:00/ACPI0007:01/driver', '../../../bus/acpi/drivers/processor')
+f('sys/devices/LNXSYSTM:00/ACPI0007:01/hid', 0o644, b'ACPI0007\n')
+f('sys/devices/LNXSYSTM:00/ACPI0007:01/modalias', 0o644, b'acpi:ACPI0007:\n')
+f('sys/devices/LNXSYSTM:00/ACPI0007:01/path', 0o644, b'\\_PR_.CPU1\n')
+f('sys/devices/LNXSYSTM:00/ACPI0007:01/uevent', 0o644, b'''DRIVER=processor
+MODALIAS=acpi:ACPI0007:
+''')
+d('sys/devices/LNXSYSTM:00/ACPI0007:01/power', 0o755)
+f('sys/devices/LNXSYSTM:00/ACPI0007:01/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/LNXTHERM:00', 0o755)
+l('sys/devices/LNXSYSTM:00/LNXTHERM:00/subsystem', '../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/LNXTHERM:00/hid', 0o644, b'LNXTHERM\n')
+f('sys/devices/LNXSYSTM:00/LNXTHERM:00/modalias', 0o644, b'acpi:LNXTHERM:\n')
+f('sys/devices/LNXSYSTM:00/LNXTHERM:00/path', 0o644, b'\\_TZ_\n')
+f('sys/devices/LNXSYSTM:00/LNXTHERM:00/uevent', 0o644, b'MODALIAS=acpi:LNXTHERM:\n')
+d('sys/devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:01', 0o755)
+l('sys/devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:01/subsystem', '../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:01/thermal_zone', '../../../virtual/thermal/thermal_zone0')
+l('sys/devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:01/driver', '../../../../bus/acpi/drivers/thermal')
+f('sys/devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:01/hid', 0o644, b'LNXTHERM\n')
+f('sys/devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:01/modalias', 0o644, b'acpi:LNXTHERM:\n')
+f('sys/devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:01/path', 0o644, b'\\_TZ_.THM0\n')
+f('sys/devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:01/uevent', 0o644, b'''DRIVER=thermal
+MODALIAS=acpi:LNXTHERM:
+''')
+d('sys/devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:01/power', 0o755)
+f('sys/devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:01/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/LNXTHERM:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/LNXTHERM:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:02', 0o755)
+l('sys/devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:02/subsystem', '../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:02/thermal_zone', '../../../virtual/thermal/thermal_zone1')
+l('sys/devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:02/driver', '../../../../bus/acpi/drivers/thermal')
+f('sys/devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:02/hid', 0o644, b'LNXTHERM\n')
+f('sys/devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:02/modalias', 0o644, b'acpi:LNXTHERM:\n')
+f('sys/devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:02/path', 0o644, b'\\_TZ_.THM1\n')
+f('sys/devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:02/uevent', 0o644, b'''DRIVER=thermal
+MODALIAS=acpi:LNXTHERM:
+''')
+d('sys/devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:02/power', 0o755)
+f('sys/devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:02/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/subsystem', '../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/path', 0o644, b'\\_SB_\n')
+f('sys/devices/LNXSYSTM:00/device:00/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:05', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:05/subsystem', '../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:05/driver', '../../../../bus/acpi/drivers/pci_link')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:05/hid', 0o644, b'PNP0C0F\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:05/modalias', 0o644, b'acpi:PNP0C0F:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:05/path', 0o644, b'\\_SB_.LNKF\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:05/uevent', 0o644, b'''DRIVER=pci_link
+MODALIAS=acpi:PNP0C0F:
+''')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:05/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:05/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/subsystem', '../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/driver', '../../../../bus/acpi/drivers/button')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/hid', 0o644, b'PNP0C0E\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/modalias', 0o644, b'acpi:PNP0C0E:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/path', 0o644, b'\\_SB_.SLPB\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/uevent', 0o644, b'''DRIVER=button
+MODALIAS=acpi:PNP0C0E:
+''')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input', 0o755)
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/subsystem', '../../../../../../class/input')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/device', '../../../PNP0C0E:00')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/uniq', 0o644, b'\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/phys', 0o644, b'PNP0C0E/button/input0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/modalias', 0o644, b'input:b0019v0000p0003e0000-e0,1,k8E,ramlsfw\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/name', 0o644, b'Sleep Button (CM)\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/uevent', 0o644, b'''PRODUCT=19/0/3/0
+NAME="Sleep Button (CM)"
+PHYS="PNP0C0E/button/input0"
+EV==3
+KEY==4000 0 0
+MODALIAS=input:b0019v0000p0003e0000-e0,1,k8E,ramlsfw
+''')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/id', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/id/version', 0o644, b'0000\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/id/product', 0o644, b'0003\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/id/vendor', 0o644, b'0000\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/id/bustype', 0o644, b'0019\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/event5', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/event5/subsystem', '../../../../../../../class/input')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/event5/device', '../../input5')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/event5/dev', 0o644, b'13:69\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/event5/uevent', 0o644, b'''MAJOR=13
+MINOR=69
+''')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/event5/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/event5/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/capabilities', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/capabilities/msc', 0o644, b'0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/capabilities/abs', 0o644, b'0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/capabilities/snd', 0o644, b'0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/capabilities/ff', 0o644, b'0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/capabilities/key', 0o644, b'4000 0 0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/capabilities/rel', 0o644, b'0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/capabilities/sw', 0o644, b'0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/capabilities/ev', 0o644, b'3\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0E:00/input/input5/capabilities/led', 0o644, b'0\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/subsystem', '../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/physical_node', '../../../pci0000:00')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/driver', '../../../../bus/acpi/drivers/pci_root')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/hid', 0o644, b'PNP0A08\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/modalias', 0o644, b'acpi:PNP0A08:PNP0A03:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/path', 0o644, b'\\_SB_.PCI0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/uevent', 0o644, b'''DRIVER=pci_root
+MODALIAS=acpi:PNP0A08:PNP0A03:
+''')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:11', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:11/subsystem', '../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:11/physical_node', '../../../../pci0000:00/0000:00:1e.0')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:11/path', 0o644, b'\\_SB_.PCI0.PCI1\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:11/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:11/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:11/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:11/device:12', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:11/device:12/subsystem', '../../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:11/device:12/physical_node', '../../../../../pci0000:00/0000:00:1e.0/0000:15:00.0')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:11/device:12/path', 0o644, b'\\_SB_.PCI0.PCI1.CDBS\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:11/device:12/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:11/device:12/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:11/device:12/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/subsystem', '../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/physical_node', '../../../../pci0000:00/0000:00:1d.7')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/path', 0o644, b'\\_SB_.PCI0.USB7\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/device:22', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/device:22/subsystem', '../../../../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/device:22/path', 0o644, b'\\_SB_.PCI0.USB7.URTH\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/device:22/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/device:22/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/device:22/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/device:22/device:23', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/device:22/device:23/subsystem', '../../../../../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/device:22/device:23/path', 0o644, b'\\_SB_.PCI0.USB7.URTH.UPDK\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/device:22/device:23/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/device:22/device:23/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/device:22/device:23/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/device:22/device:24', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/device:22/device:24/subsystem', '../../../../../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/device:22/device:24/path', 0o644, b'\\_SB_.PCI0.USB7.URTH.UPEX\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/device:22/device:24/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/device:22/device:24/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:21/device:22/device:24/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0b', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0b/subsystem', '../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0b/physical_node', '../../../../pci0000:00/0000:00:1c.0')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0b/path', 0o644, b'\\_SB_.PCI0.EXP0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0b/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0b/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0b/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/subsystem', '../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/physical_node', '../../../../pci0000:00/0000:00:01.0')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/path', 0o644, b'\\_SB_.PCI0.AGP_\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/subsystem', '../../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/physical_node', '../../../../../pci0000:00/0000:00:01.0/0000:01:00.0')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/modalias', 0o644, b'acpi:LNXVIDEO:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/path', 0o644, b'\\_SB_.PCI0.AGP_.VID_\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/uevent', 0o644, b'MODALIAS=acpi:LNXVIDEO:\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/device:08', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/device:08/subsystem', '../../../../../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/device:08/path', 0o644, b'\\_SB_.PCI0.AGP_.VID_.LCD0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/device:08/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/device:08/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/device:08/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/device:09', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/device:09/subsystem', '../../../../../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/device:09/path', 0o644, b'\\_SB_.PCI0.AGP_.VID_.CRT0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/device:09/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/device:09/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/device:09/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/device:0a', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/device:0a/subsystem', '../../../../../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/device:0a/path', 0o644, b'\\_SB_.PCI0.AGP_.VID_.DVI0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/device:0a/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/device:0a/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:06/device:07/device:0a/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:18', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:18/subsystem', '../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:18/physical_node', '../../../../pci0000:00/0000:00:1f.3')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:18/path', 0o644, b'\\_SB_.PCI0.SMBU\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:18/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:18/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:18/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0c', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0c/subsystem', '../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0c/physical_node', '../../../../pci0000:00/0000:00:1c.1')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0c/path', 0o644, b'\\_SB_.PCI0.EXP1\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0c/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0c/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0c/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/subsystem', '../../../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/modalias', 0o644, b'acpi:LNXVIDEO:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/path', 0o644, b'\\_SB_.PCI0.VID_\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/uevent', 0o644, b'MODALIAS=acpi:LNXVIDEO:\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/device:04', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/device:04/subsystem', '../../../../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/device:04/path', 0o644, b'\\_SB_.PCI0.VID_.CRT0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/device:04/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/device:04/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/device:04/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/device:05', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/device:05/subsystem', '../../../../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/device:05/path', 0o644, b'\\_SB_.PCI0.VID_.DVI0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/device:05/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/device:05/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/device:05/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/device:03', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/device:03/subsystem', '../../../../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/device:03/path', 0o644, b'\\_SB_.PCI0.VID_.LCD0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/device:03/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/device:03/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:02/device:03/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13/subsystem', '../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13/physical_node', '../../../../pci0000:00/0000:00:1f.1')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13/path', 0o644, b'\\_SB_.PCI0.IDE0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13/device:14', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13/device:14/subsystem', '../../../../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13/device:14/path', 0o644, b'\\_SB_.PCI0.IDE0.PRIM\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13/device:14/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13/device:14/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13/device:14/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13/device:14/device:15', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13/device:14/device:15/subsystem', '../../../../../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13/device:14/device:15/modalias', 0o644, b'acpi:LNXIOBAY:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13/device:14/device:15/path', 0o644, b'\\_SB_.PCI0.IDE0.PRIM.MSTR\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13/device:14/device:15/uevent', 0o644, b'MODALIAS=acpi:LNXIOBAY:\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13/device:14/device:15/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:13/device:14/device:15/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1d', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1d/subsystem', '../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1d/physical_node', '../../../../pci0000:00/0000:00:1d.2')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1d/path', 0o644, b'\\_SB_.PCI0.USB2\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1d/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1d/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1d/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1d/device:1e', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1d/device:1e/subsystem', '../../../../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1d/device:1e/path', 0o644, b'\\_SB_.PCI0.USB2.URTH\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1d/device:1e/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1d/device:1e/device:1f', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1d/device:1e/device:1f/subsystem', '../../../../../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1d/device:1e/device:1f/path', 0o644, b'\\_SB_.PCI0.USB2.URTH.UPDK\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1d/device:1e/device:1f/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1d/device:1e/device:1f/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1d/device:1e/device:1f/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1d/device:1e/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1d/device:1e/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:19', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:19/subsystem', '../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:19/physical_node', '../../../../pci0000:00/0000:00:1d.0')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:19/path', 0o644, b'\\_SB_.PCI0.USB0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:19/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:19/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:19/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1a', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1a/subsystem', '../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1a/physical_node', '../../../../pci0000:00/0000:00:1d.1')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1a/path', 0o644, b'\\_SB_.PCI0.USB1\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1a/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1a/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1a/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1a/device:1b', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1a/device:1b/subsystem', '../../../../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1a/device:1b/path', 0o644, b'\\_SB_.PCI0.USB1.URTH\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1a/device:1b/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1a/device:1b/device:1c', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1a/device:1b/device:1c/subsystem', '../../../../../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1a/device:1b/device:1c/path', 0o644, b'\\_SB_.PCI0.USB1.URTH.UPEX\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1a/device:1b/device:1c/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1a/device:1b/device:1c/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1a/device:1b/device:1c/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1a/device:1b/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:1a/device:1b/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0d', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0d/subsystem', '../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0d/physical_node', '../../../../pci0000:00/0000:00:1c.2')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0d/path', 0o644, b'\\_SB_.PCI0.EXP2\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0d/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0d/device:0e', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0d/device:0e/subsystem', '../../../../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0d/device:0e/path', 0o644, b'\\_SB_.PCI0.EXP2.EXUP\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0d/device:0e/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0d/device:0e/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0d/device:0e/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0d/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0d/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:25', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:25/subsystem', '../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:25/physical_node', '../../../../pci0000:00/0000:00:1b.0')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:25/path', 0o644, b'\\_SB_.PCI0.HDEF\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:25/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:25/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:25/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/subsystem', '../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/physical_node', '../../../../pci0000:00/0000:00:1f.0')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/path', 0o644, b'\\_SB_.PCI0.LPC_\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0000:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0000:00/subsystem', '../../../../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0000:00/hid', 0o644, b'PNP0000\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0000:00/modalias', 0o644, b'acpi:PNP0000:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0000:00/path', 0o644, b'\\_SB_.PCI0.LPC_.PIC_\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0000:00/uevent', 0o644, b'MODALIAS=acpi:PNP0000:\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0000:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0000:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0103:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0103:00/subsystem', '../../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0103:00/physical_node', '../../../../../pnp0/00:03')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0103:00/hid', 0o644, b'PNP0103\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0103:00/modalias', 0o644, b'acpi:PNP0103:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0103:00/path', 0o644, b'\\_SB_.PCI0.LPC_.HPET\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0103:00/uevent', 0o644, b'MODALIAS=acpi:PNP0103:\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0103:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0103:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/ATM1200:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/ATM1200:00/subsystem', '../../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/ATM1200:00/physical_node', '../../../../../pnp0/00:0a')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/ATM1200:00/hid', 0o644, b'ATM1200\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/ATM1200:00/modalias', 0o644, b'acpi:ATM1200:PNP0C31:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/ATM1200:00/path', 0o644, b'\\_SB_.PCI0.LPC_.TPM_\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/ATM1200:00/uevent', 0o644, b'MODALIAS=acpi:ATM1200:PNP0C31:\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/ATM1200:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/ATM1200:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0303:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0303:00/subsystem', '../../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0303:00/physical_node', '../../../../../pnp0/00:08')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0303:00/hid', 0o644, b'PNP0303\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0303:00/modalias', 0o644, b'acpi:PNP0303:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0303:00/path', 0o644, b'\\_SB_.PCI0.LPC_.KBD_\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0303:00/uevent', 0o644, b'MODALIAS=acpi:PNP0303:\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0303:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0303:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C04:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C04:00/subsystem', '../../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C04:00/physical_node', '../../../../../pnp0/00:06')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C04:00/hid', 0o644, b'PNP0C04\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C04:00/modalias', 0o644, b'acpi:PNP0C04:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C04:00/path', 0o644, b'\\_SB_.PCI0.LPC_.FPU_\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C04:00/uevent', 0o644, b'MODALIAS=acpi:PNP0C04:\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C04:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C04:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0800:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0800:00/subsystem', '../../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0800:00/physical_node', '../../../../../pnp0/00:05')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0800:00/hid', 0o644, b'PNP0800\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0800:00/modalias', 0o644, b'acpi:PNP0800:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0800:00/path', 0o644, b'\\_SB_.PCI0.LPC_.SPKR\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0800:00/uevent', 0o644, b'MODALIAS=acpi:PNP0800:\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0800:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0800:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C02:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C02:00/subsystem', '../../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C02:00/physical_node', '../../../../../pnp0/00:02')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C02:00/hid', 0o644, b'PNP0C02\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C02:00/modalias', 0o644, b'acpi:PNP0C02:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C02:00/path', 0o644, b'\\_SB_.PCI0.LPC_.SIO_\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C02:00/uevent', 0o644, b'MODALIAS=acpi:PNP0C02:\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C02:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C02:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0100:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0100:00/subsystem', '../../../../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0100:00/hid', 0o644, b'PNP0100\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0100:00/modalias', 0o644, b'acpi:PNP0100:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0100:00/path', 0o644, b'\\_SB_.PCI0.LPC_.TIMR\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0100:00/uevent', 0o644, b'MODALIAS=acpi:PNP0100:\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0100:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0100:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/subsystem', '../../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/driver', '../../../../../../bus/acpi/drivers/ec')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/hid', 0o644, b'PNP0C09\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/modalias', 0o644, b'acpi:PNP0C09:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/path', 0o644, b'\\_SB_.PCI0.LPC_.EC__\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/uevent', 0o644, b'''DRIVER=ec
+MODALIAS=acpi:PNP0C09:
+''')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/LNXPOWER:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/LNXPOWER:00/subsystem', '../../../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/LNXPOWER:00/driver', '../../../../../../../bus/acpi/drivers/power')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/LNXPOWER:00/hid', 0o644, b'LNXPOWER\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/LNXPOWER:00/modalias', 0o644, b'acpi:LNXPOWER:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/LNXPOWER:00/path', 0o644, b'\\_SB_.PCI0.LPC_.EC__.PUBS\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/LNXPOWER:00/uevent', 0o644, b'''DRIVER=power
+MODALIAS=acpi:LNXPOWER:
+''')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/LNXPOWER:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/LNXPOWER:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/ACPI0003:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/ACPI0003:00/subsystem', '../../../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/ACPI0003:00/driver', '../../../../../../../bus/acpi/drivers/ac')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/ACPI0003:00/hid', 0o644, b'ACPI0003\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/ACPI0003:00/modalias', 0o644, b'acpi:ACPI0003:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/ACPI0003:00/path', 0o644, b'\\_SB_.PCI0.LPC_.EC__.AC__\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/ACPI0003:00/uevent', 0o644, b'''DRIVER=ac
+MODALIAS=acpi:ACPI0003:
+''')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/ACPI0003:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/ACPI0003:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/ACPI0003:00/power_supply', 0o755)
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/ACPI0003:00/power_supply/AC', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/ACPI0003:00/power_supply/AC/subsystem', '../../../../../../../../../class/power_supply')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/ACPI0003:00/power_supply/AC/device', '../../../ACPI0003:00')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/ACPI0003:00/power_supply/AC/type', 0o644, b'Mains\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/ACPI0003:00/power_supply/AC/online', 0o644, b'0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/ACPI0003:00/power_supply/AC/uevent', 0o644, b'''POWER_SUPPLY_NAME=AC
+POWER_SUPPLY_TYPE=Mains
+POWER_SUPPLY_ONLINE=0
+''')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/ACPI0003:00/power_supply/AC/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/ACPI0003:00/power_supply/AC/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/subsystem', '../../../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/driver', '../../../../../../../bus/acpi/drivers/battery')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/hid', 0o644, b'PNP0C0A\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/modalias', 0o644, b'acpi:PNP0C0A:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/path', 0o644, b'\\_SB_.PCI0.LPC_.EC__.BAT0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/uevent', 0o644, b'''DRIVER=battery
+MODALIAS=acpi:PNP0C0A:
+''')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply', 0o755)
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/subsystem', '../../../../../../../../../class/power_supply')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/device', '../../../PNP0C0A:00')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/model_name', 0o644, b'42T5245\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/voltage_min_design', 0o644, b'10800000\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/type', 0o644, b'Battery\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/current_now', 0o644, b'25830000\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/energy_now', 0o644, b'59980000\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/technology', 0o644, b'Li-ion\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/voltage_now', 0o644, b'12207000\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/energy_full_design', 0o644, b'84240000\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/serial_number', 0o644, b' 6463\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/present', 0o644, b'1\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/alarm', 0o644, b'3075000\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/uevent', 0o644, b'''POWER_SUPPLY_NAME=BAT0
+POWER_SUPPLY_TYPE=Battery
+POWER_SUPPLY_STATUS=Discharging
+POWER_SUPPLY_PRESENT=1
+POWER_SUPPLY_TECHNOLOGY=Li-ion
+POWER_SUPPLY_VOLTAGE_MIN_DESIGN=10800000
+POWER_SUPPLY_VOLTAGE_NOW=12207000
+POWER_SUPPLY_CURRENT_NOW=25830000
+POWER_SUPPLY_ENERGY_FULL_DESIGN=84240000
+POWER_SUPPLY_ENERGY_FULL=61510000
+POWER_SUPPLY_ENERGY_NOW=59980000
+POWER_SUPPLY_MODEL_NAME=42T5245
+POWER_SUPPLY_MANUFACTURER=SANYO
+POWER_SUPPLY_SERIAL_NUMBER= 6463
+''')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/manufacturer', 0o644, b'SANYO\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/energy_full', 0o644, b'61510000\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/status', 0o644, b'Discharging\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/IBM0068:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/IBM0068:00/subsystem', '../../../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/IBM0068:00/driver', '../../../../../../../bus/acpi/drivers/thinkpad_hotkey')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/IBM0068:00/hid', 0o644, b'IBM0068\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/IBM0068:00/modalias', 0o644, b'acpi:IBM0068:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/IBM0068:00/path', 0o644, b'\\_SB_.PCI0.LPC_.EC__.HKEY\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/IBM0068:00/uevent', 0o644, b'''DRIVER=thinkpad_hotkey
+MODALIAS=acpi:IBM0068:
+''')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/IBM0068:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/IBM0068:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0200:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0200:00/subsystem', '../../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0200:00/physical_node', '../../../../../pnp0/00:04')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0200:00/hid', 0o644, b'PNP0200\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0200:00/modalias', 0o644, b'acpi:PNP0200:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0200:00/path', 0o644, b'\\_SB_.PCI0.LPC_.DMAC\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0200:00/uevent', 0o644, b'MODALIAS=acpi:PNP0200:\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0200:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0200:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/IBM0057:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/IBM0057:00/subsystem', '../../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/IBM0057:00/physical_node', '../../../../../pnp0/00:09')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/IBM0057:00/hid', 0o644, b'IBM0057\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/IBM0057:00/modalias', 0o644, b'acpi:IBM0057:PNP0F13:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/IBM0057:00/path', 0o644, b'\\_SB_.PCI0.LPC_.MOU_\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/IBM0057:00/uevent', 0o644, b'MODALIAS=acpi:IBM0057:PNP0F13:\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/IBM0057:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/IBM0057:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0B00:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0B00:00/subsystem', '../../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0B00:00/physical_node', '../../../../../pnp0/00:07')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0B00:00/hid', 0o644, b'PNP0B00\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0B00:00/modalias', 0o644, b'acpi:PNP0B00:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0B00:00/path', 0o644, b'\\_SB_.PCI0.LPC_.RTC_\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0B00:00/uevent', 0o644, b'MODALIAS=acpi:PNP0B00:\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0B00:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0B00:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:20', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:20/subsystem', '../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:20/physical_node', '../../../../pci0000:00/0000:00:1d.3')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:20/path', 0o644, b'\\_SB_.PCI0.USB3\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:20/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:20/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:20/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0f', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0f/subsystem', '../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0f/physical_node', '../../../../pci0000:00/0000:00:1c.3')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0f/path', 0o644, b'\\_SB_.PCI0.EXP3\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0f/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0f/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0f/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0f/device:10', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0f/device:10/subsystem', '../../../../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0f/device:10/path', 0o644, b'\\_SB_.PCI0.EXP3.EXPD\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0f/device:10/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0f/device:10/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0f/device:10/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:16', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:16/subsystem', '../../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:16/physical_node', '../../../../pci0000:00/0000:00:1f.2')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:16/path', 0o644, b'\\_SB_.PCI0.SATA\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:16/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:16/device:17', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:16/device:17/subsystem', '../../../../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:16/device:17/path', 0o644, b'\\_SB_.PCI0.SATA.PRT0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:16/device:17/uevent', 0o644, b'')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:16/device:17/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:16/device:17/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:16/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:16/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/IBM0079:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/IBM0079:00/subsystem', '../../../../bus/acpi')
+f('sys/devices/LNXSYSTM:00/device:00/IBM0079:00/hid', 0o644, b'IBM0079\n')
+f('sys/devices/LNXSYSTM:00/device:00/IBM0079:00/modalias', 0o644, b'acpi:IBM0079:PNP0C15:LNXDOCK:\n')
+f('sys/devices/LNXSYSTM:00/device:00/IBM0079:00/path', 0o644, b'\\_SB_.GDCK\n')
+f('sys/devices/LNXSYSTM:00/device:00/IBM0079:00/uevent', 0o644, b'MODALIAS=acpi:IBM0079:PNP0C15:LNXDOCK:\n')
+d('sys/devices/LNXSYSTM:00/device:00/IBM0079:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/IBM0079:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/subsystem', '../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/driver', '../../../../bus/acpi/drivers/button')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/hid', 0o644, b'PNP0C0D\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/modalias', 0o644, b'acpi:PNP0C0D:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/path', 0o644, b'\\_SB_.LID_\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/uevent', 0o644, b'''DRIVER=button
+MODALIAS=acpi:PNP0C0D:
+''')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input', 0o755)
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/subsystem', '../../../../../../class/input')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/device', '../../../PNP0C0D:00')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/uniq', 0o644, b'\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/phys', 0o644, b'PNP0C0D/button/input0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/modalias', 0o644, b'input:b0019v0000p0005e0000-e0,5,kramlsfw0,\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/name', 0o644, b'Lid Switch\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/uevent', 0o644, b'''PRODUCT=19/0/5/0
+NAME="Lid Switch"
+PHYS="PNP0C0D/button/input0"
+EV==21
+SW==1
+MODALIAS=input:b0019v0000p0005e0000-e0,5,kramlsfw0,
+''')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/event4', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/event4/subsystem', '../../../../../../../class/input')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/event4/device', '../../input4')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/event4/dev', 0o644, b'13:68\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/event4/uevent', 0o644, b'''MAJOR=13
+MINOR=68
+''')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/event4/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/event4/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/id', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/id/version', 0o644, b'0000\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/id/product', 0o644, b'0005\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/id/vendor', 0o644, b'0000\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/id/bustype', 0o644, b'0019\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/capabilities', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/capabilities/msc', 0o644, b'0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/capabilities/abs', 0o644, b'0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/capabilities/snd', 0o644, b'0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/capabilities/ff', 0o644, b'0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/capabilities/key', 0o644, b'0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/capabilities/rel', 0o644, b'0\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/capabilities/sw', 0o644, b'1\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/capabilities/ev', 0o644, b'21\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0D:00/input/input4/capabilities/led', 0o644, b'0\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C01:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C01:00/subsystem', '../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C01:00/physical_node', '../../../pnp0/00:00')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C01:00/hid', 0o644, b'PNP0C01\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C01:00/modalias', 0o644, b'acpi:PNP0C01:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C01:00/path', 0o644, b'\\_SB_.MEM_\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C01:00/uevent', 0o644, b'MODALIAS=acpi:PNP0C01:\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C01:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C01:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:07', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:07/subsystem', '../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:07/driver', '../../../../bus/acpi/drivers/pci_link')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:07/hid', 0o644, b'PNP0C0F\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:07/modalias', 0o644, b'acpi:PNP0C0F:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:07/path', 0o644, b'\\_SB_.LNKH\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:07/uevent', 0o644, b'''DRIVER=pci_link
+MODALIAS=acpi:PNP0C0F:
+''')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:07/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:07/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:04', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:04/subsystem', '../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:04/driver', '../../../../bus/acpi/drivers/pci_link')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:04/hid', 0o644, b'PNP0C0F\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:04/modalias', 0o644, b'acpi:PNP0C0F:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:04/path', 0o644, b'\\_SB_.LNKE\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:04/uevent', 0o644, b'''DRIVER=pci_link
+MODALIAS=acpi:PNP0C0F:
+''')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:04/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:04/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:02', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:02/subsystem', '../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:02/driver', '../../../../bus/acpi/drivers/pci_link')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:02/hid', 0o644, b'PNP0C0F\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:02/modalias', 0o644, b'acpi:PNP0C0F:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:02/path', 0o644, b'\\_SB_.LNKC\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:02/uevent', 0o644, b'''DRIVER=pci_link
+MODALIAS=acpi:PNP0C0F:
+''')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:02/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:02/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:00', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:00/subsystem', '../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:00/driver', '../../../../bus/acpi/drivers/pci_link')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:00/hid', 0o644, b'PNP0C0F\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:00/modalias', 0o644, b'acpi:PNP0C0F:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:00/path', 0o644, b'\\_SB_.LNKA\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:00/uevent', 0o644, b'''DRIVER=pci_link
+MODALIAS=acpi:PNP0C0F:
+''')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:01', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:01/subsystem', '../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:01/driver', '../../../../bus/acpi/drivers/pci_link')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:01/hid', 0o644, b'PNP0C0F\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:01/modalias', 0o644, b'acpi:PNP0C0F:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:01/path', 0o644, b'\\_SB_.LNKB\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:01/uevent', 0o644, b'''DRIVER=pci_link
+MODALIAS=acpi:PNP0C0F:
+''')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:01/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:01/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:06', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:06/subsystem', '../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:06/driver', '../../../../bus/acpi/drivers/pci_link')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:06/hid', 0o644, b'PNP0C0F\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:06/modalias', 0o644, b'acpi:PNP0C0F:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:06/path', 0o644, b'\\_SB_.LNKG\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:06/uevent', 0o644, b'''DRIVER=pci_link
+MODALIAS=acpi:PNP0C0F:
+''')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:06/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:06/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:03', 0o755)
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:03/subsystem', '../../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:03/driver', '../../../../bus/acpi/drivers/pci_link')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:03/hid', 0o644, b'PNP0C0F\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:03/modalias', 0o644, b'acpi:PNP0C0F:\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:03/path', 0o644, b'\\_SB_.LNKD\n')
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:03/uevent', 0o644, b'''DRIVER=pci_link
+MODALIAS=acpi:PNP0C0F:
+''')
+d('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:03/power', 0o755)
+f('sys/devices/LNXSYSTM:00/device:00/PNP0C0F:03/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/ACPI0007:00', 0o755)
+l('sys/devices/LNXSYSTM:00/ACPI0007:00/thermal_cooling', '../../virtual/thermal/cooling_device0')
+l('sys/devices/LNXSYSTM:00/ACPI0007:00/subsystem', '../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/ACPI0007:00/sysdev', '../../system/cpu/cpu0')
+l('sys/devices/LNXSYSTM:00/ACPI0007:00/driver', '../../../bus/acpi/drivers/processor')
+f('sys/devices/LNXSYSTM:00/ACPI0007:00/hid', 0o644, b'ACPI0007\n')
+f('sys/devices/LNXSYSTM:00/ACPI0007:00/modalias', 0o644, b'acpi:ACPI0007:\n')
+f('sys/devices/LNXSYSTM:00/ACPI0007:00/path', 0o644, b'\\_PR_.CPU0\n')
+f('sys/devices/LNXSYSTM:00/ACPI0007:00/uevent', 0o644, b'''DRIVER=processor
+MODALIAS=acpi:ACPI0007:
+''')
+d('sys/devices/LNXSYSTM:00/ACPI0007:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/ACPI0007:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/LNXPWRBN:00', 0o755)
+l('sys/devices/LNXSYSTM:00/LNXPWRBN:00/subsystem', '../../../bus/acpi')
+l('sys/devices/LNXSYSTM:00/LNXPWRBN:00/driver', '../../../bus/acpi/drivers/button')
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/hid', 0o644, b'LNXPWRBN\n')
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/modalias', 0o644, b'acpi:LNXPWRBN:\n')
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/uevent', 0o644, b'''DRIVER=button
+MODALIAS=acpi:LNXPWRBN:
+''')
+d('sys/devices/LNXSYSTM:00/LNXPWRBN:00/power', 0o755)
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input', 0o755)
+d('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3', 0o755)
+l('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/subsystem', '../../../../../class/input')
+l('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/device', '../../../LNXPWRBN:00')
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/uniq', 0o644, b'\n')
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/phys', 0o644, b'LNXPWRBN/button/input0\n')
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/modalias', 0o644, b'input:b0019v0000p0002e0000-e0,1,k74,ramlsfw\n')
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/name', 0o644, b'Power Button (FF)\n')
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/uevent', 0o644, b'''PRODUCT=19/0/2/0
+NAME="Power Button (FF)"
+PHYS="LNXPWRBN/button/input0"
+EV==3
+KEY==10000000000000 0
+MODALIAS=input:b0019v0000p0002e0000-e0,1,k74,ramlsfw
+''')
+d('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/id', 0o755)
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/id/version', 0o644, b'0000\n')
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/id/product', 0o644, b'0002\n')
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/id/vendor', 0o644, b'0000\n')
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/id/bustype', 0o644, b'0019\n')
+d('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/power', 0o755)
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/event3', 0o755)
+l('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/event3/subsystem', '../../../../../../class/input')
+l('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/event3/device', '../../input3')
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/event3/dev', 0o644, b'13:67\n')
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/event3/uevent', 0o644, b'''MAJOR=13
+MINOR=67
+''')
+d('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/event3/power', 0o755)
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/event3/power/wakeup', 0o644, b'\n')
+d('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/capabilities', 0o755)
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/capabilities/msc', 0o644, b'0\n')
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/capabilities/abs', 0o644, b'0\n')
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/capabilities/snd', 0o644, b'0\n')
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/capabilities/ff', 0o644, b'0\n')
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/capabilities/key', 0o644, b'10000000000000 0\n')
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/capabilities/rel', 0o644, b'0\n')
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/capabilities/sw', 0o644, b'0\n')
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/capabilities/ev', 0o644, b'3\n')
+f('sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input3/capabilities/led', 0o644, b'0\n')
+d('sys/devices/platform', 0o755)
+f('sys/devices/platform/uevent', 0o644, b'')
+d('sys/devices/platform/pcspkr', 0o755)
+l('sys/devices/platform/pcspkr/subsystem', '../../../bus/platform')
+l('sys/devices/platform/pcspkr/driver', '../../../bus/platform/drivers/pcspkr')
+f('sys/devices/platform/pcspkr/modalias', 0o644, b'platform:pcspkr\n')
+f('sys/devices/platform/pcspkr/uevent', 0o644, b'''DRIVER=pcspkr
+MODALIAS=platform:pcspkr
+''')
+d('sys/devices/platform/pcspkr/power', 0o755)
+f('sys/devices/platform/pcspkr/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/pcspkr/input', 0o755)
+d('sys/devices/platform/pcspkr/input/input2', 0o755)
+l('sys/devices/platform/pcspkr/input/input2/subsystem', '../../../../../class/input')
+l('sys/devices/platform/pcspkr/input/input2/device', '../../../pcspkr')
+f('sys/devices/platform/pcspkr/input/input2/uniq', 0o644, b'\n')
+f('sys/devices/platform/pcspkr/input/input2/phys', 0o644, b'isa0061/input0\n')
+f('sys/devices/platform/pcspkr/input/input2/modalias', 0o644, b'input:b0010v001Fp0001e0100-e0,12,kramls1,2,fw\n')
+f('sys/devices/platform/pcspkr/input/input2/name', 0o644, b'PC Speaker\n')
+f('sys/devices/platform/pcspkr/input/input2/uevent', 0o644, b'''PRODUCT=10/1f/1/100
+NAME="PC Speaker"
+PHYS="isa0061/input0"
+EV==40001
+SND==6
+MODALIAS=input:b0010v001Fp0001e0100-e0,12,kramls1,2,fw
+''')
+d('sys/devices/platform/pcspkr/input/input2/event2', 0o755)
+l('sys/devices/platform/pcspkr/input/input2/event2/subsystem', '../../../../../../class/input')
+l('sys/devices/platform/pcspkr/input/input2/event2/device', '../../input2')
+f('sys/devices/platform/pcspkr/input/input2/event2/dev', 0o644, b'13:66\n')
+f('sys/devices/platform/pcspkr/input/input2/event2/uevent', 0o644, b'''MAJOR=13
+MINOR=66
+''')
+d('sys/devices/platform/pcspkr/input/input2/event2/power', 0o755)
+f('sys/devices/platform/pcspkr/input/input2/event2/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/pcspkr/input/input2/id', 0o755)
+f('sys/devices/platform/pcspkr/input/input2/id/version', 0o644, b'0100\n')
+f('sys/devices/platform/pcspkr/input/input2/id/product', 0o644, b'0001\n')
+f('sys/devices/platform/pcspkr/input/input2/id/vendor', 0o644, b'001f\n')
+f('sys/devices/platform/pcspkr/input/input2/id/bustype', 0o644, b'0010\n')
+d('sys/devices/platform/pcspkr/input/input2/power', 0o755)
+f('sys/devices/platform/pcspkr/input/input2/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/pcspkr/input/input2/capabilities', 0o755)
+f('sys/devices/platform/pcspkr/input/input2/capabilities/msc', 0o644, b'0\n')
+f('sys/devices/platform/pcspkr/input/input2/capabilities/abs', 0o644, b'0\n')
+f('sys/devices/platform/pcspkr/input/input2/capabilities/snd', 0o644, b'6\n')
+f('sys/devices/platform/pcspkr/input/input2/capabilities/ff', 0o644, b'0\n')
+f('sys/devices/platform/pcspkr/input/input2/capabilities/key', 0o644, b'0\n')
+f('sys/devices/platform/pcspkr/input/input2/capabilities/rel', 0o644, b'0\n')
+f('sys/devices/platform/pcspkr/input/input2/capabilities/sw', 0o644, b'0\n')
+f('sys/devices/platform/pcspkr/input/input2/capabilities/ev', 0o644, b'40001\n')
+f('sys/devices/platform/pcspkr/input/input2/capabilities/led', 0o644, b'0\n')
+d('sys/devices/platform/power', 0o755)
+f('sys/devices/platform/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/vesafb.0', 0o755)
+l('sys/devices/platform/vesafb.0/subsystem', '../../../bus/platform')
+l('sys/devices/platform/vesafb.0/driver', '../../../bus/platform/drivers/vesafb')
+f('sys/devices/platform/vesafb.0/modalias', 0o644, b'platform:vesafb\n')
+f('sys/devices/platform/vesafb.0/uevent', 0o644, b'''DRIVER=vesafb
+MODALIAS=platform:vesafb
+''')
+d('sys/devices/platform/vesafb.0/power', 0o755)
+f('sys/devices/platform/vesafb.0/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/vesafb.0/graphics', 0o755)
+d('sys/devices/platform/vesafb.0/graphics/fb0', 0o755)
+l('sys/devices/platform/vesafb.0/graphics/fb0/subsystem', '../../../../../class/graphics')
+l('sys/devices/platform/vesafb.0/graphics/fb0/device', '../../../vesafb.0')
+f('sys/devices/platform/vesafb.0/graphics/fb0/pan', 0o644, b'0,0\n')
+f('sys/devices/platform/vesafb.0/graphics/fb0/rotate', 0o644, b'0\n')
+f('sys/devices/platform/vesafb.0/graphics/fb0/mode', 0o644, b'')
+f('sys/devices/platform/vesafb.0/graphics/fb0/virtual_size', 0o644, b'800,600\n')
+f('sys/devices/platform/vesafb.0/graphics/fb0/dev', 0o644, b'29:0\n')
+f('sys/devices/platform/vesafb.0/graphics/fb0/state', 0o644, b'0\n')
+f('sys/devices/platform/vesafb.0/graphics/fb0/blank', 0o644, b'')
+f('sys/devices/platform/vesafb.0/graphics/fb0/bits_per_pixel', 0o644, b'16\n')
+f('sys/devices/platform/vesafb.0/graphics/fb0/stride', 0o644, b'1600\n')
+f('sys/devices/platform/vesafb.0/graphics/fb0/name', 0o644, b'VESA VGA\n')
+f('sys/devices/platform/vesafb.0/graphics/fb0/modes', 0o644, b'U:800x600p-75\n')
+f('sys/devices/platform/vesafb.0/graphics/fb0/cursor', 0o644, b'')
+f('sys/devices/platform/vesafb.0/graphics/fb0/uevent', 0o644, b'''MAJOR=29
+MINOR=0
+''')
+f('sys/devices/platform/vesafb.0/graphics/fb0/console', 0o644, b'')
+d('sys/devices/platform/vesafb.0/graphics/fb0/power', 0o755)
+f('sys/devices/platform/vesafb.0/graphics/fb0/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/dock.0', 0o755)
+l('sys/devices/platform/dock.0/subsystem', '../../../bus/platform')
+f('sys/devices/platform/dock.0/modalias', 0o644, b'platform:dock\n')
+f('sys/devices/platform/dock.0/uid', 0o644, b'0\n')
+f('sys/devices/platform/dock.0/flags', 0o644, b'0\n')
+f('sys/devices/platform/dock.0/docked', 0o644, b'0\n')
+f('sys/devices/platform/dock.0/uevent', 0o644, b'MODALIAS=platform:dock\n')
+d('sys/devices/platform/dock.0/power', 0o755)
+f('sys/devices/platform/dock.0/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/serial8250', 0o755)
+l('sys/devices/platform/serial8250/subsystem', '../../../bus/platform')
+l('sys/devices/platform/serial8250/driver', '../../../bus/platform/drivers/serial8250')
+f('sys/devices/platform/serial8250/modalias', 0o644, b'platform:serial8250\n')
+f('sys/devices/platform/serial8250/uevent', 0o644, b'''DRIVER=serial8250
+MODALIAS=platform:serial8250
+''')
+d('sys/devices/platform/serial8250/power', 0o755)
+f('sys/devices/platform/serial8250/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/serial8250/tty', 0o755)
+d('sys/devices/platform/serial8250/tty/ttyS1', 0o755)
+l('sys/devices/platform/serial8250/tty/ttyS1/subsystem', '../../../../../class/tty')
+l('sys/devices/platform/serial8250/tty/ttyS1/device', '../../../serial8250')
+f('sys/devices/platform/serial8250/tty/ttyS1/dev', 0o644, b'4:65\n')
+f('sys/devices/platform/serial8250/tty/ttyS1/uevent', 0o644, b'''MAJOR=4
+MINOR=65
+''')
+d('sys/devices/platform/serial8250/tty/ttyS1/power', 0o755)
+f('sys/devices/platform/serial8250/tty/ttyS1/power/wakeup', 0o644, b'disabled\n')
+d('sys/devices/platform/serial8250/tty/ttyS3', 0o755)
+l('sys/devices/platform/serial8250/tty/ttyS3/subsystem', '../../../../../class/tty')
+l('sys/devices/platform/serial8250/tty/ttyS3/device', '../../../serial8250')
+f('sys/devices/platform/serial8250/tty/ttyS3/dev', 0o644, b'4:67\n')
+f('sys/devices/platform/serial8250/tty/ttyS3/uevent', 0o644, b'''MAJOR=4
+MINOR=67
+''')
+d('sys/devices/platform/serial8250/tty/ttyS3/power', 0o755)
+f('sys/devices/platform/serial8250/tty/ttyS3/power/wakeup', 0o644, b'disabled\n')
+d('sys/devices/platform/serial8250/tty/ttyS0', 0o755)
+l('sys/devices/platform/serial8250/tty/ttyS0/subsystem', '../../../../../class/tty')
+l('sys/devices/platform/serial8250/tty/ttyS0/device', '../../../serial8250')
+f('sys/devices/platform/serial8250/tty/ttyS0/dev', 0o644, b'4:64\n')
+f('sys/devices/platform/serial8250/tty/ttyS0/uevent', 0o644, b'''MAJOR=4
+MINOR=64
+''')
+d('sys/devices/platform/serial8250/tty/ttyS0/power', 0o755)
+f('sys/devices/platform/serial8250/tty/ttyS0/power/wakeup', 0o644, b'disabled\n')
+d('sys/devices/platform/serial8250/tty/ttyS2', 0o755)
+l('sys/devices/platform/serial8250/tty/ttyS2/subsystem', '../../../../../class/tty')
+l('sys/devices/platform/serial8250/tty/ttyS2/device', '../../../serial8250')
+f('sys/devices/platform/serial8250/tty/ttyS2/dev', 0o644, b'4:66\n')
+f('sys/devices/platform/serial8250/tty/ttyS2/uevent', 0o644, b'''MAJOR=4
+MINOR=66
+''')
+d('sys/devices/platform/serial8250/tty/ttyS2/power', 0o755)
+f('sys/devices/platform/serial8250/tty/ttyS2/power/wakeup', 0o644, b'disabled\n')
+d('sys/devices/platform/thinkpad_acpi', 0o755)
+l('sys/devices/platform/thinkpad_acpi/subsystem', '../../../bus/platform')
+l('sys/devices/platform/thinkpad_acpi/driver', '../../../bus/platform/drivers/thinkpad_acpi')
+f('sys/devices/platform/thinkpad_acpi/modalias', 0o644, b'platform:thinkpad_acpi\n')
+f('sys/devices/platform/thinkpad_acpi/hotkey_all_mask', 0o644, b'0x00ffffff\n')
+f('sys/devices/platform/thinkpad_acpi/hotkey_poll_freq', 0o644, b'10\n')
+f('sys/devices/platform/thinkpad_acpi/hotkey_bios_enabled', 0o644, b'0\n')
+f('sys/devices/platform/thinkpad_acpi/hotkey_recommended_mask', 0o644, b'0x008c7fff\n')
+f('sys/devices/platform/thinkpad_acpi/hotkey_bios_mask', 0o644, b'0x0000080c\n')
+f('sys/devices/platform/thinkpad_acpi/hotkey_mask', 0o644, b'0x00ffffff\n')
+f('sys/devices/platform/thinkpad_acpi/wakeup_hotunplug_complete', 0o644, b'0\n')
+f('sys/devices/platform/thinkpad_acpi/hotkey_source_mask', 0o644, b'0x00000000\n')
+f('sys/devices/platform/thinkpad_acpi/hotkey_report_mode', 0o644, b'1\n')
+f('sys/devices/platform/thinkpad_acpi/hotkey_radio_sw', 0o644, b'1\n')
+f('sys/devices/platform/thinkpad_acpi/hotkey_enable', 0o644, b'1\n')
+f('sys/devices/platform/thinkpad_acpi/uevent', 0o644, b'''DRIVER=thinkpad_acpi
+MODALIAS=platform:thinkpad_acpi
+''')
+f('sys/devices/platform/thinkpad_acpi/bluetooth_enable', 0o644, b'1\n')
+f('sys/devices/platform/thinkpad_acpi/wakeup_reason', 0o644, b'0\n')
+d('sys/devices/platform/thinkpad_acpi/rfkill', 0o755)
+d('sys/devices/platform/thinkpad_acpi/rfkill/rfkill0', 0o755)
+l('sys/devices/platform/thinkpad_acpi/rfkill/rfkill0/subsystem', '../../../../../class/rfkill')
+l('sys/devices/platform/thinkpad_acpi/rfkill/rfkill0/device', '../../../thinkpad_acpi')
+f('sys/devices/platform/thinkpad_acpi/rfkill/rfkill0/type', 0o644, b'bluetooth\n')
+f('sys/devices/platform/thinkpad_acpi/rfkill/rfkill0/state', 0o644, b'1\n')
+f('sys/devices/platform/thinkpad_acpi/rfkill/rfkill0/name', 0o644, b'tpacpi_bluetooth_sw\n')
+f('sys/devices/platform/thinkpad_acpi/rfkill/rfkill0/uevent', 0o644, b'''RFKILL_NAME=tpacpi_bluetooth_sw
+RFKILL_TYPE=bluetooth
+RFKILL_STATE=1
+''')
+f('sys/devices/platform/thinkpad_acpi/rfkill/rfkill0/claim', 0o644, b'0\n')
+d('sys/devices/platform/thinkpad_acpi/rfkill/rfkill0/power', 0o755)
+f('sys/devices/platform/thinkpad_acpi/rfkill/rfkill0/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/thinkpad_acpi/power', 0o755)
+f('sys/devices/platform/thinkpad_acpi/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/thinkpad_acpi/leds', 0o755)
+d('sys/devices/platform/thinkpad_acpi/leds/tpacpi::bay_active', 0o755)
+l('sys/devices/platform/thinkpad_acpi/leds/tpacpi::bay_active/subsystem', '../../../../../class/leds')
+l('sys/devices/platform/thinkpad_acpi/leds/tpacpi::bay_active/device', '../../../thinkpad_acpi')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::bay_active/trigger', 0o644, b'[none] AC-online BAT0-charging-or-full BAT0-charging BAT0-full rfkill0 phy0rx phy0tx phy0assoc phy0radio \n')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::bay_active/brightness', 0o644, b'0\n\x00')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::bay_active/uevent', 0o644, b'')
+d('sys/devices/platform/thinkpad_acpi/leds/tpacpi::bay_active/power', 0o755)
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::bay_active/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/thinkpad_acpi/leds/tpacpi:orange:batt', 0o755)
+l('sys/devices/platform/thinkpad_acpi/leds/tpacpi:orange:batt/subsystem', '../../../../../class/leds')
+l('sys/devices/platform/thinkpad_acpi/leds/tpacpi:orange:batt/device', '../../../thinkpad_acpi')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi:orange:batt/trigger', 0o644, b'[none] AC-online BAT0-charging-or-full BAT0-charging BAT0-full rfkill0 phy0rx phy0tx phy0assoc phy0radio \n')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi:orange:batt/brightness', 0o644, b'0\n\x00')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi:orange:batt/uevent', 0o644, b'')
+d('sys/devices/platform/thinkpad_acpi/leds/tpacpi:orange:batt/power', 0o755)
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi:orange:batt/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/thinkpad_acpi/leds/tpacpi::dock_active', 0o755)
+l('sys/devices/platform/thinkpad_acpi/leds/tpacpi::dock_active/subsystem', '../../../../../class/leds')
+l('sys/devices/platform/thinkpad_acpi/leds/tpacpi::dock_active/device', '../../../thinkpad_acpi')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::dock_active/trigger', 0o644, b'[none] AC-online BAT0-charging-or-full BAT0-charging BAT0-full rfkill0 phy0rx phy0tx phy0assoc phy0radio \n')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::dock_active/brightness', 0o644, b'0\n\x00')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::dock_active/uevent', 0o644, b'')
+d('sys/devices/platform/thinkpad_acpi/leds/tpacpi::dock_active/power', 0o755)
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::dock_active/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/thinkpad_acpi/leds/tpacpi::unknown_led', 0o755)
+l('sys/devices/platform/thinkpad_acpi/leds/tpacpi::unknown_led/subsystem', '../../../../../class/leds')
+l('sys/devices/platform/thinkpad_acpi/leds/tpacpi::unknown_led/device', '../../../thinkpad_acpi')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::unknown_led/trigger', 0o644, b'[none] AC-online BAT0-charging-or-full BAT0-charging BAT0-full rfkill0 phy0rx phy0tx phy0assoc phy0radio \n')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::unknown_led/brightness', 0o644, b'0\n\x00')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::unknown_led/uevent', 0o644, b'')
+d('sys/devices/platform/thinkpad_acpi/leds/tpacpi::unknown_led/power', 0o755)
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::unknown_led/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/thinkpad_acpi/leds/tpacpi:green:batt', 0o755)
+l('sys/devices/platform/thinkpad_acpi/leds/tpacpi:green:batt/subsystem', '../../../../../class/leds')
+l('sys/devices/platform/thinkpad_acpi/leds/tpacpi:green:batt/device', '../../../thinkpad_acpi')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi:green:batt/trigger', 0o644, b'[none] AC-online BAT0-charging-or-full BAT0-charging BAT0-full rfkill0 phy0rx phy0tx phy0assoc phy0radio \n')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi:green:batt/brightness', 0o644, b'0\n\x00')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi:green:batt/uevent', 0o644, b'')
+d('sys/devices/platform/thinkpad_acpi/leds/tpacpi:green:batt/power', 0o755)
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi:green:batt/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/thinkpad_acpi/leds/tpacpi::dock_batt', 0o755)
+l('sys/devices/platform/thinkpad_acpi/leds/tpacpi::dock_batt/subsystem', '../../../../../class/leds')
+l('sys/devices/platform/thinkpad_acpi/leds/tpacpi::dock_batt/device', '../../../thinkpad_acpi')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::dock_batt/trigger', 0o644, b'[none] AC-online BAT0-charging-or-full BAT0-charging BAT0-full rfkill0 phy0rx phy0tx phy0assoc phy0radio \n')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::dock_batt/brightness', 0o644, b'0\n\x00')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::dock_batt/uevent', 0o644, b'')
+d('sys/devices/platform/thinkpad_acpi/leds/tpacpi::dock_batt/power', 0o755)
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::dock_batt/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/thinkpad_acpi/leds/tpacpi::thinklight', 0o755)
+l('sys/devices/platform/thinkpad_acpi/leds/tpacpi::thinklight/subsystem', '../../../../../class/leds')
+l('sys/devices/platform/thinkpad_acpi/leds/tpacpi::thinklight/device', '../../../thinkpad_acpi')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::thinklight/trigger', 0o644, b'[none] AC-online BAT0-charging-or-full BAT0-charging BAT0-full rfkill0 phy0rx phy0tx phy0assoc phy0radio \n')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::thinklight/brightness', 0o644, b'255\n\x00')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::thinklight/uevent', 0o644, b'')
+d('sys/devices/platform/thinkpad_acpi/leds/tpacpi::thinklight/power', 0o755)
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::thinklight/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/thinkpad_acpi/leds/tpacpi::power', 0o755)
+l('sys/devices/platform/thinkpad_acpi/leds/tpacpi::power/subsystem', '../../../../../class/leds')
+l('sys/devices/platform/thinkpad_acpi/leds/tpacpi::power/device', '../../../thinkpad_acpi')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::power/trigger', 0o644, b'[none] AC-online BAT0-charging-or-full BAT0-charging BAT0-full rfkill0 phy0rx phy0tx phy0assoc phy0radio \n')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::power/brightness', 0o644, b'0\n\x00')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::power/uevent', 0o644, b'')
+d('sys/devices/platform/thinkpad_acpi/leds/tpacpi::power/power', 0o755)
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::power/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/thinkpad_acpi/leds/tpacpi::standby', 0o755)
+l('sys/devices/platform/thinkpad_acpi/leds/tpacpi::standby/subsystem', '../../../../../class/leds')
+l('sys/devices/platform/thinkpad_acpi/leds/tpacpi::standby/device', '../../../thinkpad_acpi')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::standby/trigger', 0o644, b'[none] AC-online BAT0-charging-or-full BAT0-charging BAT0-full rfkill0 phy0rx phy0tx phy0assoc phy0radio \n')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::standby/brightness', 0o644, b'0\n\x00')
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::standby/uevent', 0o644, b'')
+d('sys/devices/platform/thinkpad_acpi/leds/tpacpi::standby/power', 0o755)
+f('sys/devices/platform/thinkpad_acpi/leds/tpacpi::standby/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/thinkpad_hwmon', 0o755)
+l('sys/devices/platform/thinkpad_hwmon/subsystem', '../../../bus/platform')
+l('sys/devices/platform/thinkpad_hwmon/driver', '../../../bus/platform/drivers/thinkpad_hwmon')
+f('sys/devices/platform/thinkpad_hwmon/fan1_input', 0o644, b'3446\n')
+f('sys/devices/platform/thinkpad_hwmon/temp4_input', 0o644, b'63000\n')
+f('sys/devices/platform/thinkpad_hwmon/pwm1', 0o644, b'255\n')
+f('sys/devices/platform/thinkpad_hwmon/temp11_input', 0o644, b'43000\n')
+f('sys/devices/platform/thinkpad_hwmon/modalias', 0o644, b'platform:thinkpad_hwmon\n')
+f('sys/devices/platform/thinkpad_hwmon/temp15_input', 0o644, b'')
+f('sys/devices/platform/thinkpad_hwmon/temp2_input', 0o644, b'41000\n')
+f('sys/devices/platform/thinkpad_hwmon/temp1_input', 0o644, b'46000\n')
+f('sys/devices/platform/thinkpad_hwmon/temp5_input', 0o644, b'35000\n')
+f('sys/devices/platform/thinkpad_hwmon/temp13_input', 0o644, b'')
+f('sys/devices/platform/thinkpad_hwmon/temp6_input', 0o644, b'')
+f('sys/devices/platform/thinkpad_hwmon/temp8_input', 0o644, b'')
+f('sys/devices/platform/thinkpad_hwmon/pwm1_enable', 0o644, b'2\n')
+f('sys/devices/platform/thinkpad_hwmon/temp10_input', 0o644, b'49000\n')
+f('sys/devices/platform/thinkpad_hwmon/temp3_input', 0o644, b'33000\n')
+f('sys/devices/platform/thinkpad_hwmon/temp9_input', 0o644, b'35000\n')
+f('sys/devices/platform/thinkpad_hwmon/name', 0o644, b'thinkpad\n')
+f('sys/devices/platform/thinkpad_hwmon/temp12_input', 0o644, b'')
+f('sys/devices/platform/thinkpad_hwmon/uevent', 0o644, b'''DRIVER=thinkpad_hwmon
+MODALIAS=platform:thinkpad_hwmon
+''')
+f('sys/devices/platform/thinkpad_hwmon/temp7_input', 0o644, b'33000\n')
+f('sys/devices/platform/thinkpad_hwmon/temp16_input', 0o644, b'')
+f('sys/devices/platform/thinkpad_hwmon/temp14_input', 0o644, b'')
+d('sys/devices/platform/thinkpad_hwmon/hwmon', 0o755)
+d('sys/devices/platform/thinkpad_hwmon/hwmon/hwmon0', 0o755)
+l('sys/devices/platform/thinkpad_hwmon/hwmon/hwmon0/subsystem', '../../../../../class/hwmon')
+l('sys/devices/platform/thinkpad_hwmon/hwmon/hwmon0/device', '../../../thinkpad_hwmon')
+f('sys/devices/platform/thinkpad_hwmon/hwmon/hwmon0/uevent', 0o644, b'')
+d('sys/devices/platform/thinkpad_hwmon/hwmon/hwmon0/power', 0o755)
+f('sys/devices/platform/thinkpad_hwmon/hwmon/hwmon0/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/thinkpad_hwmon/power', 0o755)
+f('sys/devices/platform/thinkpad_hwmon/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/microcode', 0o755)
+l('sys/devices/platform/microcode/subsystem', '../../../bus/platform')
+f('sys/devices/platform/microcode/modalias', 0o644, b'platform:microcode\n')
+f('sys/devices/platform/microcode/uevent', 0o644, b'MODALIAS=platform:microcode\n')
+d('sys/devices/platform/microcode/power', 0o755)
+f('sys/devices/platform/microcode/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/i8042', 0o755)
+l('sys/devices/platform/i8042/subsystem', '../../../bus/platform')
+l('sys/devices/platform/i8042/driver', '../../../bus/platform/drivers/i8042')
+f('sys/devices/platform/i8042/modalias', 0o644, b'platform:i8042\n')
+f('sys/devices/platform/i8042/uevent', 0o644, b'''DRIVER=i8042
+MODALIAS=platform:i8042
+''')
+d('sys/devices/platform/i8042/power', 0o755)
+f('sys/devices/platform/i8042/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/i8042/serio0', 0o755)
+l('sys/devices/platform/i8042/serio0/subsystem', '../../../../bus/serio')
+l('sys/devices/platform/i8042/serio0/driver', '../../../../bus/serio/drivers/atkbd')
+f('sys/devices/platform/i8042/serio0/modalias', 0o644, b'serio:ty06pr00id00ex00\n')
+f('sys/devices/platform/i8042/serio0/set', 0o644, b'2\n')
+f('sys/devices/platform/i8042/serio0/bind_mode', 0o644, b'auto\n')
+f('sys/devices/platform/i8042/serio0/description', 0o644, b'i8042 KBD port\n')
+f('sys/devices/platform/i8042/serio0/softrepeat', 0o644, b'0\n')
+f('sys/devices/platform/i8042/serio0/scroll', 0o644, b'0\n')
+f('sys/devices/platform/i8042/serio0/softraw', 0o644, b'1\n')
+f('sys/devices/platform/i8042/serio0/err_count', 0o644, b'0\n')
+f('sys/devices/platform/i8042/serio0/extra', 0o644, b'0\n')
+f('sys/devices/platform/i8042/serio0/uevent', 0o644, b'''DRIVER=atkbd
+SERIO_TYPE=06
+SERIO_PROTO=00
+SERIO_ID=00
+SERIO_EXTRA=00
+MODALIAS=serio:ty06pr00id00ex00
+''')
+d('sys/devices/platform/i8042/serio0/id', 0o755)
+f('sys/devices/platform/i8042/serio0/id/proto', 0o644, b'00\n')
+f('sys/devices/platform/i8042/serio0/id/id', 0o644, b'00\n')
+f('sys/devices/platform/i8042/serio0/id/type', 0o644, b'06\n')
+f('sys/devices/platform/i8042/serio0/id/extra', 0o644, b'00\n')
+d('sys/devices/platform/i8042/serio0/power', 0o755)
+f('sys/devices/platform/i8042/serio0/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/i8042/serio0/input', 0o755)
+d('sys/devices/platform/i8042/serio0/input/input0', 0o755)
+l('sys/devices/platform/i8042/serio0/input/input0/subsystem', '../../../../../../class/input')
+l('sys/devices/platform/i8042/serio0/input/input0/device', '../../../serio0')
+f('sys/devices/platform/i8042/serio0/input/input0/uniq', 0o644, b'\n')
+f('sys/devices/platform/i8042/serio0/input/input0/phys', 0o644, b'isa0060/serio0/input0\n')
+f('sys/devices/platform/i8042/serio0/input/input0/modalias', 0o644, b'input:b0011v0001p0001eAB54-e0,1,4,11,14,k71,72,73,74,75,76,77,79,7A,7B,7C,7D,7E,7F,80,8C,8E,8F,9B,9C,9D,9E,9F,A3,A4,A5,A6,AC,AD,B7,B8,B9,D9,E2,ram4,l0,1,2,sfw\n')
+f('sys/devices/platform/i8042/serio0/input/input0/name', 0o644, b'AT Translated Set 2 keyboard\n')
+f('sys/devices/platform/i8042/serio0/input/input0/uevent', 0o644, b'''PRODUCT=11/1/1/ab54
+NAME="AT Translated Set 2 keyboard"
+PHYS="isa0060/serio0/input0"
+EV==120013
+KEY==402000000 3803078f800d001 feffffdfffefffff fffffffffffffffe
+MSC==10
+LED==7
+MODALIAS=input:b0011v0001p0001eAB54-e0,1,4,11,14,k71,72,73,74,75,76,77,79,7A,7B,7C,7D,7E,7F,80,8C,8E,8F,9B,9C,9D,9E,9F,A3,A4,A5,A6,AC,AD,B7,B8,B9,D9,E2,ram4,l0,1,2,sfw
+''')
+d('sys/devices/platform/i8042/serio0/input/input0/event0', 0o755)
+l('sys/devices/platform/i8042/serio0/input/input0/event0/subsystem', '../../../../../../../class/input')
+l('sys/devices/platform/i8042/serio0/input/input0/event0/device', '../../input0')
+f('sys/devices/platform/i8042/serio0/input/input0/event0/dev', 0o644, b'13:64\n')
+f('sys/devices/platform/i8042/serio0/input/input0/event0/uevent', 0o644, b'''MAJOR=13
+MINOR=64
+''')
+d('sys/devices/platform/i8042/serio0/input/input0/event0/power', 0o755)
+f('sys/devices/platform/i8042/serio0/input/input0/event0/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/i8042/serio0/input/input0/id', 0o755)
+f('sys/devices/platform/i8042/serio0/input/input0/id/version', 0o644, b'ab54\n')
+f('sys/devices/platform/i8042/serio0/input/input0/id/product', 0o644, b'0001\n')
+f('sys/devices/platform/i8042/serio0/input/input0/id/vendor', 0o644, b'0001\n')
+f('sys/devices/platform/i8042/serio0/input/input0/id/bustype', 0o644, b'0011\n')
+d('sys/devices/platform/i8042/serio0/input/input0/power', 0o755)
+f('sys/devices/platform/i8042/serio0/input/input0/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/i8042/serio0/input/input0/capabilities', 0o755)
+f('sys/devices/platform/i8042/serio0/input/input0/capabilities/msc', 0o644, b'10\n')
+f('sys/devices/platform/i8042/serio0/input/input0/capabilities/abs', 0o644, b'0\n')
+f('sys/devices/platform/i8042/serio0/input/input0/capabilities/snd', 0o644, b'0\n')
+f('sys/devices/platform/i8042/serio0/input/input0/capabilities/ff', 0o644, b'0\n')
+f('sys/devices/platform/i8042/serio0/input/input0/capabilities/key', 0o644, b'402000000 3803078f800d001 feffffdfffefffff fffffffffffffffe\n')
+f('sys/devices/platform/i8042/serio0/input/input0/capabilities/rel', 0o644, b'0\n')
+f('sys/devices/platform/i8042/serio0/input/input0/capabilities/sw', 0o644, b'0\n')
+f('sys/devices/platform/i8042/serio0/input/input0/capabilities/ev', 0o644, b'120013\n')
+f('sys/devices/platform/i8042/serio0/input/input0/capabilities/led', 0o644, b'7\n')
+d('sys/devices/platform/i8042/serio1', 0o755)
+l('sys/devices/platform/i8042/serio1/subsystem', '../../../../bus/serio')
+l('sys/devices/platform/i8042/serio1/driver', '../../../../bus/serio/drivers/psmouse')
+f('sys/devices/platform/i8042/serio1/upthresh', 0o644, b'255\n')
+f('sys/devices/platform/i8042/serio1/modalias', 0o644, b'serio:ty01pr00id00ex00\n')
+f('sys/devices/platform/i8042/serio1/resync_time', 0o644, b'0\n')
+f('sys/devices/platform/i8042/serio1/skipback', 0o644, b'0\n')
+f('sys/devices/platform/i8042/serio1/draghys', 0o644, b'255\n')
+f('sys/devices/platform/i8042/serio1/ext_dev', 0o644, b'1\n')
+f('sys/devices/platform/i8042/serio1/bind_mode', 0o644, b'auto\n')
+f('sys/devices/platform/i8042/serio1/resolution', 0o644, b'200\n')
+f('sys/devices/platform/i8042/serio1/resetafter', 0o644, b'5\n')
+f('sys/devices/platform/i8042/serio1/sensitivity', 0o644, b'128\n')
+f('sys/devices/platform/i8042/serio1/rate', 0o644, b'100\n')
+f('sys/devices/platform/i8042/serio1/inertia', 0o644, b'6\n')
+f('sys/devices/platform/i8042/serio1/mindrag', 0o644, b'20\n')
+f('sys/devices/platform/i8042/serio1/reach', 0o644, b'10\n')
+f('sys/devices/platform/i8042/serio1/description', 0o644, b'i8042 AUX port\n')
+f('sys/devices/platform/i8042/serio1/press_to_select', 0o644, b'0\n')
+f('sys/devices/platform/i8042/serio1/ztime', 0o644, b'38\n')
+f('sys/devices/platform/i8042/serio1/speed', 0o644, b'97\n')
+f('sys/devices/platform/i8042/serio1/thresh', 0o644, b'8\n')
+f('sys/devices/platform/i8042/serio1/jenks', 0o644, b'135\n')
+f('sys/devices/platform/i8042/serio1/uevent', 0o644, b'''DRIVER=psmouse
+SERIO_TYPE=01
+SERIO_PROTO=00
+SERIO_ID=00
+SERIO_EXTRA=00
+MODALIAS=serio:ty01pr00id00ex00
+''')
+f('sys/devices/platform/i8042/serio1/protocol', 0o644, b'TPPS/2\n')
+d('sys/devices/platform/i8042/serio1/id', 0o755)
+f('sys/devices/platform/i8042/serio1/id/proto', 0o644, b'00\n')
+f('sys/devices/platform/i8042/serio1/id/id', 0o644, b'00\n')
+f('sys/devices/platform/i8042/serio1/id/type', 0o644, b'01\n')
+f('sys/devices/platform/i8042/serio1/id/extra', 0o644, b'00\n')
+d('sys/devices/platform/i8042/serio1/power', 0o755)
+f('sys/devices/platform/i8042/serio1/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/i8042/serio1/input', 0o755)
+d('sys/devices/platform/i8042/serio1/input/input1', 0o755)
+l('sys/devices/platform/i8042/serio1/input/input1/subsystem', '../../../../../../class/input')
+l('sys/devices/platform/i8042/serio1/input/input1/device', '../../../serio1')
+f('sys/devices/platform/i8042/serio1/input/input1/uniq', 0o644, b'\n')
+f('sys/devices/platform/i8042/serio1/input/input1/phys', 0o644, b'isa0060/serio1/input0\n')
+f('sys/devices/platform/i8042/serio1/input/input1/modalias', 0o644, b'input:b0011v0002p000Ae0000-e0,1,2,k110,111,112,r0,1,amlsfw\n')
+f('sys/devices/platform/i8042/serio1/input/input1/name', 0o644, b'TPPS/2 IBM TrackPoint\n')
+f('sys/devices/platform/i8042/serio1/input/input1/uevent', 0o644, b'''PRODUCT=11/2/a/0
+NAME="TPPS/2 IBM TrackPoint"
+PHYS="isa0060/serio1/input0"
+EV==7
+KEY==70000 0 0 0 0
+REL==3
+MODALIAS=input:b0011v0002p000Ae0000-e0,1,2,k110,111,112,r0,1,amlsfw
+''')
+d('sys/devices/platform/i8042/serio1/input/input1/mouse0', 0o755)
+l('sys/devices/platform/i8042/serio1/input/input1/mouse0/subsystem', '../../../../../../../class/input')
+l('sys/devices/platform/i8042/serio1/input/input1/mouse0/device', '../../input1')
+f('sys/devices/platform/i8042/serio1/input/input1/mouse0/dev', 0o644, b'13:32\n')
+f('sys/devices/platform/i8042/serio1/input/input1/mouse0/uevent', 0o644, b'''MAJOR=13
+MINOR=32
+''')
+d('sys/devices/platform/i8042/serio1/input/input1/mouse0/power', 0o755)
+f('sys/devices/platform/i8042/serio1/input/input1/mouse0/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/i8042/serio1/input/input1/id', 0o755)
+f('sys/devices/platform/i8042/serio1/input/input1/id/version', 0o644, b'0000\n')
+f('sys/devices/platform/i8042/serio1/input/input1/id/product', 0o644, b'000a\n')
+f('sys/devices/platform/i8042/serio1/input/input1/id/vendor', 0o644, b'0002\n')
+f('sys/devices/platform/i8042/serio1/input/input1/id/bustype', 0o644, b'0011\n')
+d('sys/devices/platform/i8042/serio1/input/input1/power', 0o755)
+f('sys/devices/platform/i8042/serio1/input/input1/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/i8042/serio1/input/input1/event1', 0o755)
+l('sys/devices/platform/i8042/serio1/input/input1/event1/subsystem', '../../../../../../../class/input')
+l('sys/devices/platform/i8042/serio1/input/input1/event1/device', '../../input1')
+f('sys/devices/platform/i8042/serio1/input/input1/event1/dev', 0o644, b'13:65\n')
+f('sys/devices/platform/i8042/serio1/input/input1/event1/uevent', 0o644, b'''MAJOR=13
+MINOR=65
+''')
+d('sys/devices/platform/i8042/serio1/input/input1/event1/power', 0o755)
+f('sys/devices/platform/i8042/serio1/input/input1/event1/power/wakeup', 0o644, b'\n')
+d('sys/devices/platform/i8042/serio1/input/input1/capabilities', 0o755)
+f('sys/devices/platform/i8042/serio1/input/input1/capabilities/msc', 0o644, b'0\n')
+f('sys/devices/platform/i8042/serio1/input/input1/capabilities/abs', 0o644, b'0\n')
+f('sys/devices/platform/i8042/serio1/input/input1/capabilities/snd', 0o644, b'0\n')
+f('sys/devices/platform/i8042/serio1/input/input1/capabilities/ff', 0o644, b'0\n')
+f('sys/devices/platform/i8042/serio1/input/input1/capabilities/key', 0o644, b'70000 0 0 0 0\n')
+f('sys/devices/platform/i8042/serio1/input/input1/capabilities/rel', 0o644, b'3\n')
+f('sys/devices/platform/i8042/serio1/input/input1/capabilities/sw', 0o644, b'0\n')
+f('sys/devices/platform/i8042/serio1/input/input1/capabilities/ev', 0o644, b'7\n')
+f('sys/devices/platform/i8042/serio1/input/input1/capabilities/led', 0o644, b'0\n')
diff --git a/test/sys.tar.xz b/test/sys.tar.xz
deleted file mode 100644
index 49ee8027b2..0000000000
--- a/test/sys.tar.xz
+++ /dev/null
Binary files differ
diff --git a/test/sysv-generator-test.py b/test/sysv-generator-test.py
index 838dd57a6f..16ea65690a 100755
--- a/test/sysv-generator-test.py
+++ b/test/sysv-generator-test.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
#
# systemd-sysv-generator integration test
#
@@ -308,7 +308,7 @@ class SysvGeneratorTest(unittest.TestCase):
err, results = self.run_generator()
self.assertEqual(list(results), ['foo.service'])
self.assertEqual(os.readlink(os.path.join(self.out_dir, 'foo\\x2b.service')),
- 'foo.service')
+ 'foo.service')
self.assertNotIn('Overwriting', err)
def test_same_provides_in_multiple_scripts(self):
diff --git a/test/test-execute/exec-privatedevices-no.service b/test/test-execute/exec-privatedevices-no.service
index 77aeb951b5..0285a83ee4 100644
--- a/test/test-execute/exec-privatedevices-no.service
+++ b/test/test-execute/exec-privatedevices-no.service
@@ -2,6 +2,6 @@
Description=Test for PrivateDev=no
[Service]
-ExecStart=/bin/sh -x -c 'test -c /dev/mem'
+ExecStart=/bin/sh -x -c 'test -c /dev/kmsg'
Type=oneshot
PrivateDevices=no
diff --git a/test/test-execute/exec-privatedevices-yes.service b/test/test-execute/exec-privatedevices-yes.service
index ab958b646e..094257f414 100644
--- a/test/test-execute/exec-privatedevices-yes.service
+++ b/test/test-execute/exec-privatedevices-yes.service
@@ -2,6 +2,6 @@
Description=Test for PrivateDev=yes
[Service]
-ExecStart=/bin/sh -c 'test ! -c /dev/mem'
+ExecStart=/bin/sh -c 'test ! -c /dev/kmsg'
Type=oneshot
PrivateDevices=yes
diff --git a/test/test-execute/exec-read-only-path-succeed.service b/test/test-execute/exec-read-only-path-succeed.service
new file mode 100644
index 0000000000..b54d48f281
--- /dev/null
+++ b/test/test-execute/exec-read-only-path-succeed.service
@@ -0,0 +1,8 @@
+[Service]
+Type=oneshot
+# This should work, as we explicitly disable the effect of ReadOnlyPaths=
+ExecStart=+/bin/touch /tmp/thisisasimpletest
+# This should also work, as we do not disable the effect of ReadOnlyPaths= but invert the exit code
+ExecStart=/bin/sh -x -c '! /bin/touch /tmp/thisisasimpletest'
+ExecStart=+/bin/rm /tmp/thisisasimpletest
+ReadOnlyPaths=/tmp
diff --git a/test/test-execute/exec-restrict-namespaces-mnt-blacklist.service b/test/test-execute/exec-restrict-namespaces-mnt-blacklist.service
new file mode 100644
index 0000000000..ab909cbd94
--- /dev/null
+++ b/test/test-execute/exec-restrict-namespaces-mnt-blacklist.service
@@ -0,0 +1,7 @@
+[Unit]
+Description=Test RestrictNamespaces=~mnt
+
+[Service]
+RestrictNamespaces=~mnt
+ExecStart=/bin/sh -x -c 'unshare -m'
+Type=oneshot
diff --git a/test/test-execute/exec-restrict-namespaces-mnt.service b/test/test-execute/exec-restrict-namespaces-mnt.service
new file mode 100644
index 0000000000..1aeed72717
--- /dev/null
+++ b/test/test-execute/exec-restrict-namespaces-mnt.service
@@ -0,0 +1,7 @@
+[Unit]
+Description=Test RestrictNamespaces=mnt
+
+[Service]
+RestrictNamespaces=mnt
+ExecStart=/bin/sh -x -c 'unshare -m'
+Type=oneshot
diff --git a/test/test-execute/exec-restrict-namespaces-no.service b/test/test-execute/exec-restrict-namespaces-no.service
new file mode 100644
index 0000000000..33500302d2
--- /dev/null
+++ b/test/test-execute/exec-restrict-namespaces-no.service
@@ -0,0 +1,7 @@
+[Unit]
+Description=Test RestrictNamespaces=no
+
+[Service]
+RestrictNamespaces=no
+ExecStart=/bin/sh -x -c 'unshare -m -u -i -n -p -f'
+Type=oneshot
diff --git a/test/test-execute/exec-restrict-namespaces-yes.service b/test/test-execute/exec-restrict-namespaces-yes.service
new file mode 100644
index 0000000000..3fe70e2bea
--- /dev/null
+++ b/test/test-execute/exec-restrict-namespaces-yes.service
@@ -0,0 +1,7 @@
+[Unit]
+Description=Test RestrictNamespaces=yes
+
+[Service]
+RestrictNamespaces=yes
+ExecStart=/bin/sh -x -c 'unshare -m'
+Type=oneshot
diff --git a/test/test-functions b/test/test-functions
index 2a21a64c5c..fd7c198166 100644
--- a/test/test-functions
+++ b/test/test-functions
@@ -5,13 +5,14 @@ PATH=/sbin:/bin:/usr/sbin:/usr/bin
export PATH
LOOKS_LIKE_DEBIAN=$(source /etc/os-release && [[ "$ID" = "debian" || "$ID_LIKE" = "debian" ]] && echo yes)
+LOOKS_LIKE_ARCH=$(source /etc/os-release && [[ "$ID" = "arch" ]] && echo yes)
KERNEL_VER=${KERNEL_VER-$(uname -r)}
KERNEL_MODS="/lib/modules/$KERNEL_VER/"
QEMU_TIMEOUT="${QEMU_TIMEOUT:-infinity}"
NSPAWN_TIMEOUT="${NSPAWN_TIMEOUT:-infinity}"
TIMED_OUT= # will be 1 after run_* if *_TIMEOUT is set and test timed out
FSTYPE="${FSTYPE:-ext3}"
-UNIFIED_CGROUP_HIERARCHY="${UNIFIED_CGROUP_HIERARCHY:-no}"
+UNIFIED_CGROUP_HIERARCHY="${UNIFIED_CGROUP_HIERARCHY:-default}"
if ! ROOTLIBDIR=$(pkg-config --variable=systemdutildir systemd); then
echo "WARNING! Cannot determine rootlibdir from pkg-config, assuming /usr/lib/systemd" >&2
@@ -39,6 +40,9 @@ function find_qemu_bin() {
# i386 version of QEMU
[ "$QEMU_BIN" ] || QEMU_BIN=$(which -a qemu 2>/dev/null | grep '^/' -m1)
;;
+ ppc64*)
+ [ "$QEMU_BIN" ] || QEMU_BIN=$(which -a qemu-system-$ARCH 2>/dev/null | grep '^/' -m1)
+ ;;
esac
if [ ! -e "$QEMU_BIN" ]; then
@@ -58,15 +62,43 @@ run_qemu() {
&& KERNEL_BIN="/boot/$MACHINE_ID/$KERNEL_VER/linux"
fi
+ if [[ ! "$KERNEL_BIN" ]]; then
+ if [[ "$LOOKS_LIKE_ARCH" ]]; then
+ KERNEL_BIN=/boot/vmlinuz-linux
+ else
+ KERNEL_BIN=/boot/vmlinuz-$KERNEL_VER
+ fi
+ fi
+
default_fedora_initrd=/boot/initramfs-${KERNEL_VER}.img
default_debian_initrd=/boot/initrd.img-${KERNEL_VER}
- [ "$KERNEL_BIN" ] || KERNEL_BIN=/boot/vmlinuz-$KERNEL_VER
- [ "$INITRD" ] || { [ -e "$default_fedora_initrd" ] && INITRD=$default_fedora_initrd; }
- [ "$INITRD" ] || { [ "$LOOKS_LIKE_DEBIAN" ] && [ -e "$default_debian_initrd" ] && INITRD=$default_debian_initrd; }
+ default_arch_initrd=/boot/initramfs-linux.img
+ if [[ ! "$INITRD" ]]; then
+ if [[ -e "$default_fedora_initrd" ]]; then
+ INITRD="$default_fedora_initrd"
+ elif [[ "$LOOKS_LIKE_DEBIAN" && -e "$default_debian_initrd" ]]; then
+ INITRD="$default_debian_initrd"
+ elif [[ "$LOOKS_LIKE_ARCH" && -e "$default_arch_initrd" ]]; then
+ INITRD="$default_arch_initrd"
+ fi
+ fi
+
[ "$QEMU_SMP" ] || QEMU_SMP=1
find_qemu_bin || return 1
+ local _cgroup_args
+ if [[ "$UNIFIED_CGROUP_HIERARCHY" = "yes" ]]; then
+ _cgroup_args="systemd.unified_cgroup_hierarchy=yes"
+ elif [[ "$UNIFIED_CGROUP_HIERARCHY" = "no" ]]; then
+ _cgroup_args="systemd.unified_cgroup_hierarchy=no systemd.legacy_systemd_cgroup_controller=yes"
+ elif [[ "$UNIFIED_CGROUP_HIERARCHY" = "hybrid" ]]; then
+ _cgroup_args="systemd.unified_cgroup_hierarchy=no systemd.legacy_systemd_cgroup_controller=no"
+ elif [[ "$UNIFIED_CGROUP_HIERARCHY" != "default" ]]; then
+ dfatal "Unknown UNIFIED_CGROUP_HIERARCHY. Got $UNIFIED_CGROUP_HIERARCHY, expected [yes|no|hybrid|default]"
+ exit 1
+ fi
+
KERNEL_APPEND="root=/dev/sda1 \
raid=noautodetect \
loglevel=2 \
@@ -74,7 +106,7 @@ init=$ROOTLIBDIR/systemd \
ro \
console=ttyS0 \
selinux=0 \
-systemd.unified_cgroup_hierarchy=$UNIFIED_CGROUP_HIERARCHY \
+$_cgroup_args \
$KERNEL_APPEND \
"
@@ -118,7 +150,17 @@ run_nspawn() {
_nspawn_cmd="timeout --foreground $NSPAWN_TIMEOUT $_nspawn_cmd"
fi
- _nspawn_cmd="env UNIFIED_CGROUP_HIERARCHY=$UNIFIED_CGROUP_HIERARCHY $_nspawn_cmd"
+ if [[ "$UNIFIED_CGROUP_HIERARCHY" = "hybrid" ]]; then
+ dwarn "nspawn doesn't support UNIFIED_CGROUP_HIERARCHY=hybrid, skipping"
+ exit
+ elif [[ "$UNIFIED_CGROUP_HIERARCHY" = "yes" || "$UNIFIED_CGROUP_HIERARCHY" = "no" ]]; then
+ _nspawn_cmd="env UNIFIED_CGROUP_HIERARCHY=$UNIFIED_CGROUP_HIERARCHY $_nspawn_cmd"
+ elif [[ "$UNIFIED_CGROUP_HIERARCHY" = "default" ]]; then
+ _nspawn_cmd="env --unset=UNIFIED_CGROUP_HIERARCHY $_nspawn_cmd"
+ else
+ dfatal "Unknown UNIFIED_CGROUP_HIERARCHY. Got $UNIFIED_CGROUP_HIERARCHY, expected [yes|no|hybrid|default]"
+ exit 1
+ fi
(set -x; $_nspawn_cmd)
rc=$?
diff --git a/src/resolve/test-data/_443._tcp.fedoraproject.org.pkts b/test/test-resolve/_443._tcp.fedoraproject.org.pkts
index a383c6286d..a383c6286d 100644
--- a/src/resolve/test-data/_443._tcp.fedoraproject.org.pkts
+++ b/test/test-resolve/_443._tcp.fedoraproject.org.pkts
Binary files differ
diff --git a/src/resolve/test-data/_openpgpkey.fedoraproject.org.pkts b/test/test-resolve/_openpgpkey.fedoraproject.org.pkts
index 15de02e997..15de02e997 100644
--- a/src/resolve/test-data/_openpgpkey.fedoraproject.org.pkts
+++ b/test/test-resolve/_openpgpkey.fedoraproject.org.pkts
Binary files differ
diff --git a/src/resolve/test-data/fake-caa.pkts b/test/test-resolve/fake-caa.pkts
index 1c3ecc5491..1c3ecc5491 100644
--- a/src/resolve/test-data/fake-caa.pkts
+++ b/test/test-resolve/fake-caa.pkts
Binary files differ
diff --git a/src/resolve/test-data/fedoraproject.org.pkts b/test/test-resolve/fedoraproject.org.pkts
index 17874844d9..17874844d9 100644
--- a/src/resolve/test-data/fedoraproject.org.pkts
+++ b/test/test-resolve/fedoraproject.org.pkts
Binary files differ
diff --git a/src/resolve/test-data/gandi.net.pkts b/test/test-resolve/gandi.net.pkts
index 5ef51e0c8e..5ef51e0c8e 100644
--- a/src/resolve/test-data/gandi.net.pkts
+++ b/test/test-resolve/gandi.net.pkts
Binary files differ
diff --git a/src/resolve/test-data/google.com.pkts b/test/test-resolve/google.com.pkts
index f98c4cd855..f98c4cd855 100644
--- a/src/resolve/test-data/google.com.pkts
+++ b/test/test-resolve/google.com.pkts
Binary files differ
diff --git a/src/resolve/test-data/kyhwana.org.pkts b/test/test-resolve/kyhwana.org.pkts
index e28a725c9a..e28a725c9a 100644
--- a/src/resolve/test-data/kyhwana.org.pkts
+++ b/test/test-resolve/kyhwana.org.pkts
Binary files differ
diff --git a/src/resolve/test-data/root.pkts b/test/test-resolve/root.pkts
index 54ba668c75..54ba668c75 100644
--- a/src/resolve/test-data/root.pkts
+++ b/test/test-resolve/root.pkts
Binary files differ
diff --git a/src/resolve/test-data/sw1a1aa-sw1a2aa-sw1a2ab-sw1a2ac.find.me.uk.pkts b/test/test-resolve/sw1a1aa-sw1a2aa-sw1a2ab-sw1a2ac.find.me.uk.pkts
index a854249532..a854249532 100644
--- a/src/resolve/test-data/sw1a1aa-sw1a2aa-sw1a2ab-sw1a2ac.find.me.uk.pkts
+++ b/test/test-resolve/sw1a1aa-sw1a2aa-sw1a2ab-sw1a2ac.find.me.uk.pkts
Binary files differ
diff --git a/src/resolve/test-data/teamits.com.pkts b/test/test-resolve/teamits.com.pkts
index 11deb39677..11deb39677 100644
--- a/src/resolve/test-data/teamits.com.pkts
+++ b/test/test-resolve/teamits.com.pkts
Binary files differ
diff --git a/src/resolve/test-data/zbyszek@fedoraproject.org.pkts b/test/test-resolve/zbyszek@fedoraproject.org.pkts
index f0a6f982df..f0a6f982df 100644
--- a/src/resolve/test-data/zbyszek@fedoraproject.org.pkts
+++ b/test/test-resolve/zbyszek@fedoraproject.org.pkts
Binary files differ
diff --git a/test/udev-test.pl b/test/udev-test.pl
index 9723386b23..7e33479004 100755
--- a/test/udev-test.pl
+++ b/test/udev-test.pl
@@ -741,6 +741,86 @@ KERNEL=="ttyACM[0-9]*", SYMLINK=" one two "
EOF
},
{
+ desc => "symlink with spaces in substituted variable",
+ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+ exp_name => "name-one_two_three-end",
+ not_exp_name => " ",
+ rules => <<EOF
+ENV{WITH_WS}="one two three"
+SYMLINK="name-\$env{WITH_WS}-end"
+EOF
+ },
+ {
+ desc => "symlink with leading space in substituted variable",
+ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+ exp_name => "name-one_two_three-end",
+ not_exp_name => " ",
+ rules => <<EOF
+ENV{WITH_WS}=" one two three"
+SYMLINK="name-\$env{WITH_WS}-end"
+EOF
+ },
+ {
+ desc => "symlink with trailing space in substituted variable",
+ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+ exp_name => "name-one_two_three-end",
+ not_exp_name => " ",
+ rules => <<EOF
+ENV{WITH_WS}="one two three "
+SYMLINK="name-\$env{WITH_WS}-end"
+EOF
+ },
+ {
+ desc => "symlink with lots of space in substituted variable",
+ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+ exp_name => "name-one_two_three-end",
+ not_exp_name => " ",
+ rules => <<EOF
+ENV{WITH_WS}=" one two three "
+SYMLINK="name-\$env{WITH_WS}-end"
+EOF
+ },
+ {
+ desc => "symlink with multiple spaces in substituted variable",
+ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+ exp_name => "name-one_two_three-end",
+ not_exp_name => " ",
+ rules => <<EOF
+ENV{WITH_WS}=" one two three "
+SYMLINK="name-\$env{WITH_WS}-end"
+EOF
+ },
+ {
+ desc => "symlink with space and var with space, part 1",
+ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+ exp_name => "first",
+ not_exp_name => " ",
+ rules => <<EOF
+ENV{WITH_WS}=" one two three "
+SYMLINK=" first name-\$env{WITH_WS}-end another_symlink a b c "
+EOF
+ },
+ {
+ desc => "symlink with space and var with space, part 2",
+ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+ exp_name => "name-one_two_three-end",
+ not_exp_name => " ",
+ rules => <<EOF
+ENV{WITH_WS}=" one two three "
+SYMLINK=" first name-\$env{WITH_WS}-end another_symlink a b c "
+EOF
+ },
+ {
+ desc => "symlink with space and var with space, part 3",
+ devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
+ exp_name => "another_symlink",
+ not_exp_name => " ",
+ rules => <<EOF
+ENV{WITH_WS}=" one two three "
+SYMLINK=" first name-\$env{WITH_WS}-end another_symlink a b c "
+EOF
+ },
+ {
desc => "symlink creation (same directory)",
devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
exp_name => "modem0",
diff --git a/tmpfiles.d/systemd.conf.m4 b/tmpfiles.d/systemd.conf.m4
index 2cd58e9121..76e3829ab2 100644
--- a/tmpfiles.d/systemd.conf.m4
+++ b/tmpfiles.d/systemd.conf.m4
@@ -49,21 +49,21 @@ z /var/log/journal/%m/system.journal 0640 root systemd-journal - -
m4_ifdef(`HAVE_ACL',`m4_dnl
m4_ifdef(`ENABLE_ADM_GROUP',`m4_dnl
m4_ifdef(`ENABLE_WHEEL_GROUP',``
-a+ /var/log/journal - - - - d:group:adm:r-x,d:group:wheel:r-x
-a+ /var/log/journal - - - - group:adm:r-x,group:wheel:r-x
+a+ /var/log/journal - - - - d:group::r-x,d:group:adm:r-x,d:group:wheel:r-x
+a+ /var/log/journal - - - - group::r-x,group:adm:r-x,group:wheel:r-x
a+ /var/log/journal/%m - - - - d:group:adm:r-x,d:group:wheel:r-x
a+ /var/log/journal/%m - - - - group:adm:r-x,group:wheel:r-x
a+ /var/log/journal/%m/system.journal - - - - group:adm:r--,group:wheel:r--
'', ``
-a+ /var/log/journal - - - - d:group:adm:r-x
-a+ /var/log/journal - - - - group:adm:r-x
+a+ /var/log/journal - - - - d:group::r-x,d:group:adm:r-x
+a+ /var/log/journal - - - - group::r-x,group:adm:r-x
a+ /var/log/journal/%m - - - - d:group:adm:r-x
a+ /var/log/journal/%m - - - - group:adm:r-x
a+ /var/log/journal/%m/system.journal - - - - group:adm:r--
'')',`m4_dnl
m4_ifdef(`ENABLE_WHEEL_GROUP',``
-a+ /var/log/journal - - - - d:group:wheel:r-x
-a+ /var/log/journal - - - - group:wheel:r-x
+a+ /var/log/journal - - - - d:group::r-x,d:group:wheel:r-x
+a+ /var/log/journal - - - - group::r-x,group:wheel:r-x
a+ /var/log/journal/%m - - - - d:group:wheel:r-x
a+ /var/log/journal/%m - - - - group:wheel:r-x
a+ /var/log/journal/%m/system.journal - - - - group:wheel:r--
diff --git a/tmpfiles.d/tmp.conf b/tmpfiles.d/tmp.conf
index 6bbd1aa341..22555a0076 100644
--- a/tmpfiles.d/tmp.conf
+++ b/tmpfiles.d/tmp.conf
@@ -16,3 +16,7 @@ x /tmp/systemd-private-%b-*
X /tmp/systemd-private-%b-*/tmp
x /var/tmp/systemd-private-%b-*
X /var/tmp/systemd-private-%b-*/tmp
+
+# Remove top-level private temporary directories on each boot
+R! /tmp/systemd-private-*
+R! /var/tmp/systemd-private-*
diff --git a/tools/catalog-report.py b/tools/catalog-report.py
new file mode 100644
index 0000000000..b220060cc8
--- /dev/null
+++ b/tools/catalog-report.py
@@ -0,0 +1,87 @@
+#!/usr/bin/python3
+# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
+#
+# This file is part of systemd. It is distrubuted under the MIT license, see
+# below.
+#
+# Copyright 2016 Zbigniew Jędrzejewski-Szmek
+#
+# The MIT License (MIT)
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+"""
+Prints out journal entries with no or bad catalog explanations.
+"""
+
+import re
+from systemd import journal, id128
+
+j = journal.Reader()
+
+logged = set()
+pattern = re.compile('@[A-Z0-9_]+@')
+
+mids = {v:k for k,v in id128.__dict__.items()
+ if k.startswith('SD_MESSAGE')}
+
+freq = 1000
+
+def log_entry(x):
+ if 'CODE_FILE' in x:
+ # some of our code was using 'CODE_FUNCTION' instead of 'CODE_FUNC'
+ print('{}:{} {}'.format(x.get('CODE_FILE', '???'),
+ x.get('CODE_LINE', '???'),
+ x.get('CODE_FUNC', None) or x.get('CODE_FUNCTION', '???')))
+ print(' {}'.format(x.get('MESSAGE', 'no message!')))
+ for k, v in x.items():
+ if k.startswith('CODE_') or k in {'MESSAGE_ID', 'MESSAGE'}:
+ continue
+ print(' {}={}'.format(k, v))
+ print()
+
+for i, x in enumerate(j):
+ if i % freq == 0:
+ print(i, end='\r')
+
+ try:
+ mid = x['MESSAGE_ID']
+ except KeyError:
+ continue
+ name = mids.get(mid, 'unknown')
+
+ try:
+ desc = journal.get_catalog(mid)
+ except FileNotFoundError:
+ if mid in logged:
+ continue
+
+ print('{} {.hex}: no catalog entry'.format(name, mid))
+ log_entry(x)
+ logged.add(mid)
+ continue
+
+ fields = [field[1:-1] for field in pattern.findall(desc)]
+ for field in fields:
+ index = (mid, field)
+ if field in x or index in logged:
+ continue
+ print('{} {.hex}: no field {}'.format(name, mid, field))
+ log_entry(x)
+ logged.add(index)
diff --git a/tools/gdb-sd_dump_hashmaps.py b/tools/gdb-sd_dump_hashmaps.py
index 9ee81fb05a..d20016e005 100644
--- a/tools/gdb-sd_dump_hashmaps.py
+++ b/tools/gdb-sd_dump_hashmaps.py
@@ -1,3 +1,4 @@
+#!/usr/bin/python3
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#
# This file is part of systemd.
diff --git a/tools/make-directive-index.py b/tools/make-directive-index.py
index 256ff3dc5d..8ce09ca2fa 100755
--- a/tools/make-directive-index.py
+++ b/tools/make-directive-index.py
@@ -1,3 +1,4 @@
+#!/usr/bin/python3
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#
# This file is part of systemd.
diff --git a/tools/make-man-index.py b/tools/make-man-index.py
index 74a47b821a..50ad9532cd 100755
--- a/tools/make-man-index.py
+++ b/tools/make-man-index.py
@@ -1,3 +1,4 @@
+#!/usr/bin/python3
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#
# This file is part of systemd.
diff --git a/tools/make-man-rules.py b/tools/make-man-rules.py
index 5e61917d60..18aa513952 100644
--- a/tools/make-man-rules.py
+++ b/tools/make-man-rules.py
@@ -1,3 +1,4 @@
+#!/usr/bin/python3
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#
# This file is part of systemd.
diff --git a/tools/xml_helper.py b/tools/xml_helper.py
index e87126f2f7..b2c036909d 100644
--- a/tools/xml_helper.py
+++ b/tools/xml_helper.py
@@ -1,3 +1,4 @@
+#!/usr/bin/python3
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#
# This file is part of systemd.
diff --git a/units/.gitignore b/units/.gitignore
index 8f4949258e..4398a59f91 100644
--- a/units/.gitignore
+++ b/units/.gitignore
@@ -16,6 +16,7 @@
/rc-local.service
/rescue.service
/serial-getty@.service
+/system-update-cleanup.service
/systemd-ask-password-console.service
/systemd-ask-password-wall.service
/systemd-backlight@.service
@@ -74,5 +75,6 @@
/systemd-update-utmp.service
/systemd-user-sessions.service
/systemd-vconsole-setup.service
+/systemd-volatile-root.service
/tmp.mount
/user@.service
diff --git a/units/initrd-switch-root.service.in b/units/initrd-switch-root.service.in
index 82893dafb1..d31497f5e3 100644
--- a/units/initrd-switch-root.service.in
+++ b/units/initrd-switch-root.service.in
@@ -15,6 +15,4 @@ AllowIsolate=yes
[Service]
Type=oneshot
-# we have to use "--force" here, otherwise systemd would umount /run
-ExecStart=@rootbindir@/systemctl --no-block --force switch-root /sysroot
-KillMode=none
+ExecStart=@rootbindir@/systemctl --no-block switch-root /sysroot
diff --git a/units/sys-fs-fuse-connections.mount b/units/sys-fs-fuse-connections.mount
index e940beb09f..336b5f6277 100644
--- a/units/sys-fs-fuse-connections.mount
+++ b/units/sys-fs-fuse-connections.mount
@@ -12,6 +12,7 @@ Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
ConditionPathExists=/sys/fs/fuse/connections
ConditionCapability=CAP_SYS_ADMIN
+ConditionVirtualization=!private-users
After=systemd-modules-load.service
Before=sysinit.target
diff --git a/units/system-update-cleanup.service.in b/units/system-update-cleanup.service.in
new file mode 100644
index 0000000000..116be8bc2d
--- /dev/null
+++ b/units/system-update-cleanup.service.in
@@ -0,0 +1,32 @@
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=Remove the Offline System Updates symlink
+Documentation=man:systemd.special(5) man:systemd.offline-updates(7)
+After=system-update.target
+DefaultDependencies=no
+Conflicts=shutdown.target
+
+# system-update-generator uses laccess("/system-update"), while a plain
+# ConditionPathExists=/system-update uses access("/system-update"), so
+# we need an alternate condition to cover the case of a dangling symlink.
+#
+# This service is only invoked if /system-update exists, i.e. if the
+# condition tested by system-update-generator remains true and the system
+# would be diverted into system-update.target again after reboot. This way
+# we guard against being diverted into system-update.target again, which
+# works as a safety measure, but we will not step on the toes of the
+# update script if it successfully removed the symlink and scheduled a
+# reboot or some other action on its own.
+ConditionPathExists=|/system-update
+ConditionPathIsSymbolicLink=|/system-update
+
+[Service]
+Type=oneshot
+ExecStart=/bin/rm -fv /system-update
+ExecStart=@SYSTEMCTL@ reboot
diff --git a/units/system-update.target b/units/system-update.target
index 48d46fcbda..3542879706 100644
--- a/units/system-update.target
+++ b/units/system-update.target
@@ -6,11 +6,12 @@
# (at your option) any later version.
[Unit]
-Description=System Update
-Documentation=http://freedesktop.org/wiki/Software/systemd/SystemUpdates
+Description=Offline System Update
+Documentation=man:systemd.offline-updates(7)
Documentation=man:systemd.special(7) man:systemd-system-update-generator(8)
Requires=sysinit.target
Conflicts=shutdown.target
After=sysinit.target
Before=shutdown.target
AllowIsolate=yes
+Wants=system-update-cleanup.service
diff --git a/units/systemd-journal-catalog-update.service.in b/units/systemd-journal-catalog-update.service.in
index 6370dd478f..276f052b1a 100644
--- a/units/systemd-journal-catalog-update.service.in
+++ b/units/systemd-journal-catalog-update.service.in
@@ -12,7 +12,7 @@ DefaultDependencies=no
Conflicts=shutdown.target
After=local-fs.target
Before=sysinit.target shutdown.target systemd-update-done.service
-ConditionNeedsUpdate=/etc
+ConditionNeedsUpdate=/var
[Service]
Type=oneshot
diff --git a/units/systemd-networkd.service.m4.in b/units/systemd-networkd.service.m4.in
index a968d8bd45..2623b21947 100644
--- a/units/systemd-networkd.service.m4.in
+++ b/units/systemd-networkd.service.m4.in
@@ -10,9 +10,8 @@ Description=Network Service
Documentation=man:systemd-networkd.service(8)
ConditionCapability=CAP_NET_ADMIN
DefaultDependencies=no
-# dbus.service can be dropped once on kdbus, and systemd-udevd.service can be
-# dropped once tuntap is moved to netlink
-After=systemd-udevd.service dbus.service network-pre.target systemd-sysusers.service systemd-sysctl.service
+# systemd-udevd.service can be dropped once tuntap is moved to netlink
+After=systemd-udevd.service network-pre.target systemd-sysusers.service systemd-sysctl.service
Before=network.target multi-user.target shutdown.target
Conflicts=shutdown.target
Wants=network.target
@@ -40,3 +39,9 @@ SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete
[Install]
WantedBy=multi-user.target
Also=systemd-networkd.socket
+
+# We want to enable systemd-networkd-wait-online.service whenever this service
+# is enabled. systemd-networkd-wait-online.service has
+# WantedBy=network-online.target, so enabling it only has an effect if
+# network-online.target itself is enabled or pulled in by some other unit.
+Also=systemd-networkd-wait-online.service
diff --git a/units/systemd-nspawn@.service.in b/units/systemd-nspawn@.service.in
index c8141639b6..5e80054a57 100644
--- a/units/systemd-nspawn@.service.in
+++ b/units/systemd-nspawn@.service.in
@@ -10,7 +10,8 @@ Description=Container %i
Documentation=man:systemd-nspawn(1)
PartOf=machines.target
Before=machines.target
-After=network.target
+After=network.target systemd-resolved.service
+RequiresMountsFor=/var/lib/machines
[Service]
ExecStart=@bindir@/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --network-veth -U --settings=override --machine=%i
@@ -22,9 +23,9 @@ Slice=machine.slice
Delegate=yes
TasksMax=16384
-# Enforce a strict device policy, similar to the one nspawn configures
-# when it allocates its own scope unit. Make sure to keep these
-# policies in sync if you change them!
+## Enforce a strict device policy, similar to the one nspawn configures
+## when it allocates its own scope unit. Make sure to keep these
+## policies in sync if you change them!
DevicePolicy=closed
DeviceAllow=/dev/net/tun rwm
DeviceAllow=char-pts rw
diff --git a/units/systemd-resolved.service.m4.in b/units/systemd-resolved.service.m4.in
index 0f0440ddaf..41f696abe5 100644
--- a/units/systemd-resolved.service.m4.in
+++ b/units/systemd-resolved.service.m4.in
@@ -12,6 +12,8 @@ Documentation=http://www.freedesktop.org/wiki/Software/systemd/resolved
Documentation=http://www.freedesktop.org/wiki/Software/systemd/writing-network-configuration-managers
Documentation=http://www.freedesktop.org/wiki/Software/systemd/writing-resolver-clients
After=systemd-networkd.service network.target
+Before=network-online.target nss-lookup.target
+Wants=nss-lookup.target
# On kdbus systems we pull in the busname explicitly, because it
# carries policy that allows the daemon to acquire its name.
@@ -38,3 +40,4 @@ SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete
[Install]
WantedBy=multi-user.target
+Alias=dbus-org.freedesktop.resolve1.service
diff --git a/units/systemd-vconsole-setup.service.in b/units/systemd-vconsole-setup.service.in
index 2bd1fd1a5d..8bb75c6a4f 100644
--- a/units/systemd-vconsole-setup.service.in
+++ b/units/systemd-vconsole-setup.service.in
@@ -9,6 +9,7 @@
Description=Setup Virtual Console
Documentation=man:systemd-vconsole-setup.service(8) man:vconsole.conf(5)
DefaultDependencies=no
+Before=initrd-switch-root.target shutdown.target
ConditionPathExists=/dev/tty0
[Service]
diff --git a/units/systemd-volatile-root.service.in b/units/systemd-volatile-root.service.in
new file mode 100644
index 0000000000..cc4e604e4c
--- /dev/null
+++ b/units/systemd-volatile-root.service.in
@@ -0,0 +1,21 @@
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=Enforce Volatile Root File Systems
+Documentation=man:systemd-volatile-root.service(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=sysroot.mount
+Before=initrd-root-fs.target shutdown.target
+Conflicts=shutdown.target
+AssertPathExists=/etc/initrd-release
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@rootlibexecdir@/systemd-volatile-root yes /sysroot