Compare commits

...

57 Commits

Author SHA1 Message Date
Yu Watanabe 669c7b687b
Merge 5e2d802c01 into b8cb1bc983 2024-11-06 15:13:44 +01:00
Léane GRASSER b8cb1bc983 po: Translated using Weblate (French)
Currently translated at 100.0% (253 of 253 strings)

Co-authored-by: Léane GRASSER <leane.grasser@proton.me>
Translate-URL: https://translate.fedoraproject.org/projects/systemd/main/fr/
Translation: systemd/main
2024-11-06 15:07:28 +01:00
Luca Boccassi d99fe076b5
introduce report_errno_and_exit() helper (#35028)
This is a follow for https://github.com/systemd/systemd/pull/34853. In
particular, this comment
https://github.com/systemd/systemd/pull/34853#discussion_r1825837705.
2024-11-06 13:51:10 +00:00
Yu Watanabe b66948bbf2 core/manager: silence false-positive warning by coverity
Follow-up for 406f177501.

Closes CID#1564897.
2024-11-06 13:47:33 +00:00
Luca Boccassi 4055529003
machine: introduce io.systemd.Machine.Open method (#34867)
This PR introduces io.systemd.Machine.Open method which combines three
DBus alternatives:
- OpenMachinePTY
- OpenMachineLogin
- OpenMachineShell

The PR contains basic tests.
2024-11-06 13:45:04 +00:00
Zbigniew Jędrzejewski-Szmek d0ab0e5fa5 pid1: stop refusing to boot with cgroup v1
Since v256 we completely fail to boot if v1 is configured. Fedora 41 was just
released with v256.7 and this is probably the first major exposure of users to
this code. It turns out not work very well. Fedora switched to v2 as default in
F31 (2019) and at that time some people added configuration to use v1 either
because of Docker or for other reasons. But it's been long enough ago that
people don't remember this and are now very unhappy when the system refuses to
boot after an upgrade.

Refusing to boot is also unnecessarilly punishing to users. For machines that
are used remotely, this could mean somebody needs to physically access the
machine. For other users, the machine might be the only way to access the net
and help, and people might not know how to set kernel parameters without some
docs. And because this is in systemd, after an upgrade all boot choices are
affected, and it's not possible to e.g. select an older kernel for boot. And
crashing the machine doesn't really serve our goal either: we were giving a
hint how to continue using v1 and nothing else.

If the new override is configured, warn and immediately boot to v1.
If v1 is configured w/o the override, warn and wait 30 s and boot to v2.
Also give a hint how to switch to v2.

https://bugzilla.redhat.com/show_bug.cgi?id=2323323
https://bugzilla.redhat.com/show_bug.cgi?id=2323345
https://bugzilla.redhat.com/show_bug.cgi?id=2322467
https://www.reddit.com/r/Fedora/comments/1gfcyw9/refusing_to_run_under_cgroup_01_sy_specified_on/

The advice is to set systemd.unified_cgroup_hierarchy=1 (instead of removing
systemd.unified_cgroup_hierarchy=0). I think this is easier to convey. Users
who are understand what is going on can just remove the option instead.

The caching is dropped in cg_is_legacy_wanted(). It turns out that the
order in which those functions are called during early setup is very fragile.
If cg_is_legacy_wanted() is called before we have set up the v2 hierarchy,
we incorrectly cache a true answer. The function is called just a handful
of times at most, so we don't really need to cache the response.
2024-11-06 13:43:25 +00:00
Ivan Kruglov 1e2cd07394 machine: tests for io.systemd.Machine.Open 2024-11-06 11:58:51 +01:00
Ivan Kruglov a686bedb88 machine: introduce io.systemd.Machine.Open method 2024-11-06 11:37:51 +01:00
Ivan Kruglov 7779d4944c json: introduce json_dispatch_strv_environment()
I just moved json_dispatch_environment() from src/shared/user-record.c
under name 'json_dispatch_strv_environment()' to shared json code.
2024-11-06 11:37:51 +01:00
Ivan Kruglov b0eca6dee0 machine: machine_default_shell_path() & machine_default_shell_args() helper functions 2024-11-06 11:37:51 +01:00
Ivan Kruglov 41f1f283d7 machine: introduce machine_start_getty() and machine_start_shell() helpers 2024-11-06 11:37:51 +01:00
Ivan Kruglov c0589b0227 use report_errno_and_exit() in src/core/exec-invoke.c 2024-11-06 11:18:38 +01:00
Ivan Kruglov 7022563b5b use report_errno_and_exit() in src/shared/elf-util.c 2024-11-06 11:18:38 +01:00
Ivan Kruglov 3d44b469f3 use report_errno_and_exit() in src/shared/dissect-image.c 2024-11-06 11:18:38 +01:00
Ivan Kruglov 9af164b71c use report_errno_and_exit() in src/shared/mount-util.c 2024-11-06 11:18:38 +01:00
Ivan Kruglov f72a64f352 use report_errno_and_exit() in src/shutdown/umount.c 2024-11-06 11:18:38 +01:00
Ivan Kruglov a567de392d process-util: introduce report_errno_and_exit() as part of src/basic/process-util.{h,c} 2024-11-06 11:18:38 +01:00
Yu Watanabe ea457d59e9 man/varlink: fix typo
Follow-up for 4f5fabe7a3.
2024-11-06 19:06:47 +09:00
Yu Watanabe 9dcf5c226e man/udev: fix typo
Follow-up for df8f9b88bd.
2024-11-06 19:06:40 +09:00
Zbigniew Jędrzejewski-Szmek f755ac99cb man/systemd-measure: add forgotten "="
Both syntaxes work, but let's use one syntax for consistency.

Fixup for 0641ce809a27cc1bc358924c26770f19d1213ec1.
2024-11-06 10:18:16 +01:00
Zbigniew Jędrzejewski-Szmek ad6a4bf09c man/systemd-measure: update to new ukify syntax, non-root operation
It's been a while, but systemd-measure doesn't need root, and
ukify has a more modern syntax.
2024-11-06 10:14:29 +01:00
Yu Watanabe df69f29728
network: reconfigure interface more gracefully (#35035)
split-out of #34989.
2024-11-06 17:57:56 +09:00
Lennart Poettering 682195a00a
UKI: Introduce `.dtbauto` sections (#34855)
Split out from #34158
2024-11-06 09:29:04 +01:00
Andres Beltran f348831d27 namespace-util: make idmapping not supported if syscalls return EPERM 2024-11-06 09:27:33 +01:00
Lennart Poettering 299b6c3c28
Various man page updates (#35032)
Fixes: #34996
Fixes: #15032
Fixes: #32751
Fixes: #33130
Fixes: #34735
Fixes: #34840
Fixes: #34949
2024-11-06 09:26:57 +01:00
Zbigniew Jędrzejewski-Szmek ddcdc6b365
mount-util: introduce path_is_network_fs_harder() and use it in networkd (#35040)
Closes #32426.
2024-11-06 08:39:24 +01:00
Lennart Poettering df8f9b88bd man: convert multiple left-over "See Also" sections to <simplelist>
These were forgotten during the initial conversion, probably because
most of them consisted only of a single entry.

Fix that.
2024-11-05 22:57:51 +01:00
Lennart Poettering 607d297487 man: link up D-Bus API docs from daemon man pages
Let's systematically make sure that we link up the D-Bus interfaces from
the daemon man pages once in prose and once in short form at the bottom
("See Also"), for all daemons.

Also, add reverse links at the bottom of the D-Bus API docs.

Fixes: #34996
2024-11-05 22:57:51 +01:00
Lennart Poettering 2f69ad26ca man: point people from sd-bus man page to busctl 2024-11-05 22:57:51 +01:00
Lennart Poettering 4f5fabe7a3 man: add brief entrypoint man page for sd-varlink
We have this in a similar fashion for the other APIs libsystemd
provides. Add the same for sd-varlink. There isn't too much on it for
now, but at least it's a start.

Also link it up everywhere.
2024-11-05 22:57:51 +01:00
Lennart Poettering ac804bc2f8 man: tone down claims on processes having exited already in ExecStop=
Processes can easily survive the first kill operation we execute, hence
we shouldn't make strong claims about them having exited already. Let's
just say "likely" hence.

Fixes: #15032
2024-11-05 22:57:51 +01:00
Lennart Poettering 5adc433799 man: document that .path units don't care for hidden files
Fixes: #32751
2024-11-05 22:57:51 +01:00
Lennart Poettering b711737096 man: document that PrivateTmp= is unaffected by ProtectSystem=strict
Fixes: #33130
2024-11-05 22:57:51 +01:00
Lennart Poettering 172ac39fc8 man: highlight the privilege issues around the LogControl1 more
Let's emphasize the privilege thing with a <caution> section.

Let's also point out that other D-Bus libraries are less restrictive
than sd-bus by default regarding permission access.

Fixes: #34735
2024-11-05 22:57:34 +01:00
anonymix007 73b1fbc777 man: Document stub behaviour for .hwids and .dtbauto sections 2024-11-06 00:47:04 +03:00
anonymix007 1d79f667f4 stub: Handle .dtbauto sections 2024-11-06 00:47:04 +03:00
anonymix007 4c0b7f4250 measure: Introduce .dtbauto support 2024-11-06 00:47:04 +03:00
anonymix007 630cf4e7da uki: add new .dtbauto PE section type
.dtbauto section contains DT blobs, just like .dtb, the difference is
that multiple .dtbauto sections are allowed to be in a UKI and only one
is selected automatically

Temporarily drop an assert_cc() check in systemd-measure to make it compilable before the next commit
2024-11-06 00:47:04 +03:00
anonymix007 763028a16c measure: introduce support for a .hwids section 2024-11-06 00:47:04 +03:00
anonymix007 c033267912 boot: Add .dtbauto section matching in PE section discovery against HWIDs and FW-provided DT 2024-11-06 00:46:57 +03:00
Lennart Poettering ecbe9ae5a0 man: don't claim SELinuxContext= only worked in the system service manager
Fixes: #34840
2024-11-05 22:42:38 +01:00
Lennart Poettering af080967ba man: document the timeout applied to /usr/lib/systemd/system-shutdown/ drop-in binaries
Fixes: #34949
2024-11-05 22:42:32 +01:00
Yu Watanabe c0323de6ca network: use path_is_network_fs_harder()
Closes #32426.
2024-11-06 04:58:59 +09:00
Yu Watanabe d49d95df0a mount-util: introduce path_is_network_fs_harder()
It also detects e.g. glusterfs or mounts with "_netdev" option.
2024-11-06 04:58:55 +09:00
anonymix007 6bb76ab959 boot: Add HWID calculation from SMBIOS strings and matching against a built-in list 2024-11-05 22:29:58 +03:00
anonymix007 1c3a0a4b1f boot: Add firmware_devicetree_exists() 2024-11-05 22:29:58 +03:00
Diogo Ivo e6cb29fa0f boot: add matching against FW-provided Devicetree blob
Add support for matching the DT contained in a .dtb section of the
UKI image against the FW provided FDT or arbitrary compatible.
2024-11-05 22:29:40 +03:00
Yu Watanabe 6e0c9b7dac network: introduce LINK_RECONFIGURE_CLEANLY flag
And use it when explicit reconfiguration is requested by Reconfigure() DBus method
or networkd certainly detects that connected network is changed.
Otherwise do not use the flag especially when we come back from sleep mode.
2024-11-06 02:05:00 +09:00
Yu Watanabe 451c2baf30 network: keep dynamic configurations as possible as we can on reconfigure
E.g. when a .network file is updated, but DHCP setting is unchanged, it
is not necessary to drop acquired DHCP lease.
So, let's not stop DHCP client and friends in link_reconfigure_impl(),
but stop them later when we know they are not necessary anymore.

Still DHCP clients and friends are stopped and leases are dropped when
the explicit reconfiguration is requested
2024-11-06 02:05:00 +09:00
Yu Watanabe dd6d53a8dc network: merge link_foreignize_config() and link_drop_foreign_config()
When a reconfiguration of an interface is triggered, previously we
call link_foreignize_config(), which sets all static configurations as
foreign, then later call link_drop_foreign_config(), which drops
unnecessary foreign configurations.

This commit merges these two steps into one, link_drop_unmanaged_config(),
which drops unnecessary static and foreign configurations.

Also, this renames link_drop_managed_configs() to
link_drop_static_config(), as it only drops static configurations.
Note that dynamically aquired configurations are dropped by
link_stop_engines().
2024-11-06 02:05:00 +09:00
Yu Watanabe 2b07a3211b network: several cleanups for link_reconfigure()
Effectively no functional changes, just refactoring and preparation for
later changes.

- convert boolean flag 'force' to LinkReconfigurationFlag enum,
- merge link_reconfigure() and reconfigure_handler_on_bus_method_reload() as
  link_reconfigure_full(),
- Rename ReconfigureData -> LinkReconfigurationData,
- make Reconfigure() DBus message wait for reconfiguration being
  started before sending reply.
2024-11-06 02:05:00 +09:00
Yu Watanabe 5a1ef6dffb network: split out link_enter_unmanaged() from link_reconfigure_impl()
No functional change, just refactoring.
2024-11-06 02:05:00 +09:00
anonymix007 26060eb7a0 fundamental: Add HWID calculation 2024-11-05 14:48:43 +03:00
anonymix007 09f16de6d8 boot: Add xnew0
Same as xnew but initialized with zeros
2024-11-05 14:48:33 +03:00
Yu Watanabe 5e2d802c01 bootctl: do not try to update the same file multiple times
Otherwise, copy_file_with_version_check() -> version_check() will fail
and warn about that the same version is already installed.

Fixes a regression caused by 929f41c652.
Fixes #33392.
2024-06-19 16:17:47 +09:00
Yu Watanabe f3159f9389 bootctl: check file type before update
This also adds missing assertions.

Follow-up for 929f41c652.
2024-06-19 16:17:47 +09:00
Yu Watanabe 8393fab8e0 bootctl: add missing error messages in version_check() 2024-06-19 16:17:47 +09:00
130 changed files with 2278 additions and 927 deletions

View File

@ -69,6 +69,9 @@ The following exceptions apply:
* the following sources are under **Public Domain** (LicenseRef-alg-sha1-public-domain): * the following sources are under **Public Domain** (LicenseRef-alg-sha1-public-domain):
- src/fundamental/sha1-fundamental.c - src/fundamental/sha1-fundamental.c
- src/fundamental/sha1-fundamental.h - src/fundamental/sha1-fundamental.h
* the following files are licensed under **BSD-3-Clause** license:
- src/boot/efi/chid.c
- src/boot/efi/chid.h
* Heebo fonts under docs/fonts/ are licensed under the **SIL Open Font License 1.1**, * Heebo fonts under docs/fonts/ are licensed under the **SIL Open Font License 1.1**,
* any files under test/ without an explicit license we assume non-copyrightable * any files under test/ without an explicit license we assume non-copyrightable
(eg: computer-generated fuzzer data) (eg: computer-generated fuzzer data)

13
NEWS
View File

@ -51,6 +51,12 @@ CHANGES WITH 257 in spe:
too many systems, because most NVMe devices only know a namespace 1 too many systems, because most NVMe devices only know a namespace 1
by default. by default.
* Support for cgroup v1 ('legacy' and 'hybrid' hierarchies) is now
considered obsolete and systemd by default will ignore configuration
that enables them. To forcibly reenable cgroup v1 support,
SYSTEMD_CGROUP_ENABLE_LEGACY_FORCE=1 must additionally be set on the
kernel command line.
Announcements of Future Feature Removals: Announcements of Future Feature Removals:
* The D-Bus method org.freedesktop.systemd1.StartAuxiliaryScope() is * The D-Bus method org.freedesktop.systemd1.StartAuxiliaryScope() is
@ -64,11 +70,8 @@ CHANGES WITH 257 in spe:
will be phased out in a future release in 2025, i.e. we expect to bump will be phased out in a future release in 2025, i.e. we expect to bump
the minimum baseline to v5.4 then too. the minimum baseline to v5.4 then too.
* Support for cgroup v1 ('legacy' and 'hybrid' hierarchies) is now * The complete removal of support for cgroup v1 ('legacy' and 'hybrid'
considered obsolete and systemd by default will refuse to boot under hierarchies) is scheduled for v258.
it. To forcibly reenable cgroup v1 support,
SYSTEMD_CGROUP_ENABLE_LEGACY_FORCE=1 must be set on kernel command
line. The complete removal of cgroup v1 is scheduled for v258.
* Support for System V service scripts is deprecated and will be * Support for System V service scripts is deprecated and will be
removed in v258. Please make sure to update your software removed in v258. Please make sure to update your software

View File

@ -106,17 +106,17 @@
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para> <para><simplelist type="inline">
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>, <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<citerefentry><refentrytitle>user@.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>, <member><citerefentry><refentrytitle>user@.service</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>, <member><citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>5</manvolnum></citerefentry>, <member><citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>, <member><citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>, <member><citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>, <member><citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<citerefentry><refentrytitle>systemd-run</refentrytitle><manvolnum>1</manvolnum></citerefentry>, <member><citerefentry><refentrytitle>systemd-run</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<citerefentry><refentrytitle>busctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>, <member><citerefentry><refentrytitle>busctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<citerefentry project='man-pages'><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry> <member><citerefentry project='man-pages'><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
</para> </simplelist></para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -145,10 +145,8 @@ PROPERTY_WITH_SPACES=some string</programlisting>
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para> <para><simplelist type="inline">
<citerefentry> <member><citerefentry><refentrytitle>systemd-hwdb</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<refentrytitle>systemd-hwdb</refentrytitle><manvolnum>8</manvolnum> </simplelist></para>
</citerefentry>
</para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -35,6 +35,7 @@
#include &lt;systemd/sd-login.h&gt; #include &lt;systemd/sd-login.h&gt;
#include &lt;systemd/sd-messages.h&gt; #include &lt;systemd/sd-messages.h&gt;
#include &lt;systemd/sd-path.h&gt; #include &lt;systemd/sd-path.h&gt;
#include &lt;systemd/sd-varlink.h&gt;
</programlisting> </programlisting>
<cmdsynopsis> <cmdsynopsis>
@ -61,8 +62,9 @@
<citerefentry><refentrytitle>sd-id128</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd-id128</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd-json</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd-json</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
and
<citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>3</manvolnum></citerefentry> <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>3</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>sd-varlink</refentrytitle><manvolnum>3</manvolnum></citerefentry>
for information about different parts of the library interface.</para> for information about different parts of the library interface.</para>
</refsect1> </refsect1>

View File

@ -89,7 +89,9 @@ node /org/freedesktop/LogControl1 {
<citerefentry project="man-pages"><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry> call). <citerefentry project="man-pages"><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry> call).
</para> </para>
<para>Those two properties are writable, so they may be set by sufficiently privileged users.</para> <caution><title>Write Access</title><para>The <varname>LogLevel</varname> and
<varname>LogTarget</varname> properties are supposed to be writable. Care should be taken to ensure
that only appropriately privileged clients can modify them.</para></caution>
<para><varname>SyslogIdentifier</varname> is a read-only property that shows the "syslog identifier". <para><varname>SyslogIdentifier</varname> is a read-only property that shows the "syslog identifier".
It is a short string that identifies the program that is the source of log messages that is passed to It is a short string that identifies the program that is the source of log messages that is passed to
@ -127,6 +129,11 @@ node /org/freedesktop/LogControl1 {
<para>This creates a simple server on the bus. It implements the LogControl1 interface by providing <para>This creates a simple server on the bus. It implements the LogControl1 interface by providing
the required properties and allowing to set the writable ones. It logs at the configured log level using the required properties and allowing to set the writable ones. It logs at the configured log level using
<citerefentry><refentrytitle>sd_journal_print</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para> <citerefentry><refentrytitle>sd_journal_print</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
<para>Note that when porting this example to other D-Bus libraries it might be necessary to add manual
client privilege checks, as they typically do not default to the restrictive defaults of sd-bus, where
unprivileged access to properties is controlled via the <constant>SD_BUS_VTABLE_UNPRIVILEGED</constant>
flag that is opt-in rather than opt-out.</para>
</example> </example>
</refsect1> </refsect1>

View File

@ -427,8 +427,6 @@ node /org/freedesktop/hostname1 {
name.</para> name.</para>
</refsect1> </refsect1>
<xi:include href="org.freedesktop.locale1.xml" xpointer="versioning"/>
<refsect1> <refsect1>
<title>Examples</title> <title>Examples</title>
@ -442,12 +440,7 @@ node /org/freedesktop/hostname1 {
</example> </example>
</refsect1> </refsect1>
<refsect1> <xi:include href="org.freedesktop.locale1.xml" xpointer="versioning"/>
<title>See Also</title>
<para>David Zeuthen's original Fedora
<ulink url="https://fedoraproject.org/wiki/Features/BetterHostname">Feature page about xdg-hostname</ulink></para>
</refsect1>
<refsect1> <refsect1>
<title>History</title> <title>History</title>
@ -462,4 +455,16 @@ node /org/freedesktop/hostname1 {
<varname>VSockCID</varname> were added in version 256.</para> <varname>VSockCID</varname> were added in version 256.</para>
</refsect2> </refsect2>
</refsect1> </refsect1>
<refsect1>
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-hostnamed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>hostnamectl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member>David Zeuthen's original Fedora
<ulink url="https://fedoraproject.org/wiki/Features/BetterHostname">Feature page about xdg-hostname</ulink></member>
</simplelist></para>
</refsect1>
</refentry> </refentry>

View File

@ -453,6 +453,7 @@ node /org/freedesktop/import1/transfer/_1 {
</refsect1> </refsect1>
<xi:include href="org.freedesktop.locale1.xml" xpointer="versioning"/> <xi:include href="org.freedesktop.locale1.xml" xpointer="versioning"/>
<refsect1> <refsect1>
<title>History</title> <title>History</title>
<refsect2> <refsect2>
@ -469,4 +470,13 @@ node /org/freedesktop/import1/transfer/_1 {
</refsect2> </refsect2>
</refsect1> </refsect1>
<refsect1>
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-importd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>importctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>
</refentry> </refentry>

View File

@ -185,4 +185,14 @@ $ gdbus introspect --system \
<para>These D-Bus interfaces follow <ulink url="https://0pointer.de/blog/projects/versioning-dbus.html"> <para>These D-Bus interfaces follow <ulink url="https://0pointer.de/blog/projects/versioning-dbus.html">
the usual interface versioning guidelines</ulink>.</para> the usual interface versioning guidelines</ulink>.</para>
</refsect1> </refsect1>
<refsect1>
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-localed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>localectl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>
</refentry> </refentry>

View File

@ -1648,4 +1648,13 @@ node /org/freedesktop/login1/session/1 {
<para><function>SetClass()</function> was added in version 256.</para> <para><function>SetClass()</function> was added in version 256.</para>
</refsect2> </refsect2>
</refsect1> </refsect1>
<refsect1>
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-logind.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>loginctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>
</refentry> </refentry>

View File

@ -719,4 +719,13 @@ $ gdbus introspect --system \
and <varname>SSHPrivateKeyPath</varname> were added in version 256.</para> and <varname>SSHPrivateKeyPath</varname> were added in version 256.</para>
</refsect2> </refsect2>
</refsect1> </refsect1>
<refsect1>
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-machined.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>
</refentry> </refentry>

View File

@ -602,4 +602,13 @@ $ gdbus introspect --system \
<para><varname>NamespaceNSID</varname> was added in version 256.</para> <para><varname>NamespaceNSID</varname> was added in version 256.</para>
</refsect2> </refsect2>
</refsect1> </refsect1>
<refsect1>
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>networkctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>
</refentry> </refentry>

View File

@ -103,4 +103,14 @@ node /org/freedesktop/oom1 {
<para><function>Killed()</function> was added in version 252.</para> <para><function>Killed()</function> was added in version 252.</para>
</refsect2> </refsect2>
</refsect1> </refsect1>
<refsect1>
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-oomd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>oomctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>
</refentry> </refentry>

View File

@ -591,4 +591,13 @@ node /org/freedesktop/portable1 {
<para><function>ReattachWithExtensions()</function> was added in version 254.</para> <para><function>ReattachWithExtensions()</function> was added in version 254.</para>
</refsect2> </refsect2>
</refsect1> </refsect1>
<refsect1>
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-portabled.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>portablectl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>
</refentry> </refentry>

View File

@ -935,4 +935,13 @@ $ gdbus introspect --system \
</refsect1> </refsect1>
<xi:include href="org.freedesktop.locale1.xml" xpointer="versioning"/> <xi:include href="org.freedesktop.locale1.xml" xpointer="versioning"/>
<refsect1>
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-resolved.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>resolvectl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>
</refentry> </refentry>

View File

@ -12489,4 +12489,13 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
<para><varname>DeferReactivation</varname> was added in version 257.</para> <para><varname>DeferReactivation</varname> was added in version 257.</para>
</refsect2> </refsect2>
</refsect1> </refsect1>
<refsect1>
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>
</refentry> </refentry>

View File

@ -582,4 +582,13 @@ node /org/freedesktop/sysupdate1/job/_1 {
<varname>Progress</varname> were added in version 257.</para> <varname>Progress</varname> were added in version 257.</para>
</refsect2> </refsect2>
</refsect1> </refsect1>
<refsect1>
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-sysupdated.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>updatectl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>
</refentry> </refentry>

View File

@ -194,7 +194,11 @@ $ gdbus introspect --system \
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para><simplelist type="inline">
<para><ulink url="https://lists.freedesktop.org/archives/systemd-devel/2011-May/002526.html">More information on how the system clock and RTC interact</ulink></para> <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-timedate.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>timedatectl.service</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><ulink url="https://lists.freedesktop.org/archives/systemd-devel/2011-May/002526.html">More information on how the system clock and RTC interact</ulink></member>
</simplelist></para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -153,4 +153,11 @@ $ gdbus introspect --system \
<xi:include href="org.freedesktop.locale1.xml" xpointer="versioning"/> <xi:include href="org.freedesktop.locale1.xml" xpointer="versioning"/>
<refsect1>
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-timesync.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>
</refentry> </refentry>

View File

@ -91,9 +91,9 @@
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para> <para><simplelist type="inline">
<citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry> <member><citerefentry><refentrytitle>systemd-pstore.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
</para> </simplelist></para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -155,6 +155,7 @@ manpages = [
['sd-journal', '3', [], ''], ['sd-journal', '3', [], ''],
['sd-json', '3', [], ''], ['sd-json', '3', [], ''],
['sd-login', '3', [], 'HAVE_PAM'], ['sd-login', '3', [], 'HAVE_PAM'],
['sd-varlink', '3', [], ''],
['sd_booted', '3', [], ''], ['sd_booted', '3', [], ''],
['sd_bus_add_match', ['sd_bus_add_match',
'3', '3',

View File

@ -179,6 +179,9 @@
<member><citerefentry><refentrytitle>sd_bus_track_new</refentrytitle><manvolnum>3</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>sd_bus_track_new</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
</simplelist> </simplelist>
for more information about the functions available.</para> for more information about the functions available.</para>
<para>The <citerefentry><refentrytitle>busctl</refentrytitle><manvolnum>1</manvolnum></citerefentry> tool
makes the functionality implemented by sd-bus available from the command line.</para>
</refsect1> </refsect1>
<xi:include href="libsystemd-pkgconfig.xml" /> <xi:include href="libsystemd-pkgconfig.xml" />
@ -189,9 +192,10 @@
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>sd-event</refentrytitle><manvolnum>3</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>sd-event</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>busctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>busctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>sd-varlink</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
<member><citerefentry project='man-pages'><refentrytitle>dbus-daemon</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> <member><citerefentry project='man-pages'><refentrytitle>dbus-daemon</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry project='man-pages'><refentrytitle>dbus-send</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> <member><citerefentry project='man-pages'><refentrytitle>dbus-send</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</simplelist></para> </simplelist></para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -84,7 +84,8 @@
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para><simplelist type="inline"> <para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>, <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>sd-varlink</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
<member><citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> <member><citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</simplelist></para> </simplelist></para>
</refsect1> </refsect1>

64
man/sd-varlink.xml Normal file
View File

@ -0,0 +1,64 @@
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
<refentry id="sd-varlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>sd-varlink</title>
<productname>systemd</productname>
</refentryinfo>
<refmeta>
<refentrytitle>sd-varlink</refentrytitle>
<manvolnum>3</manvolnum>
</refmeta>
<refnamediv>
<refname>sd-varlink</refname>
<refpurpose>APIs for Varlink IPC</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>#include &lt;systemd/sd-varlink.h&gt;</funcsynopsisinfo>
</funcsynopsis>
<cmdsynopsis>
<command>pkg-config --cflags --libs libsystemd</command>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para><filename>sd-varlink.h</filename> is part of
<citerefentry><refentrytitle>libsystemd</refentrytitle><manvolnum>3</manvolnum></citerefentry> and
provides APIs for implementing Varlink IPC clients and services. See <ulink url="https://varlink.org/"/>
for more information about Varlink IPC.</para>
<para>Varlink IPC uses <ulink url="https://json.org/">JSON</ulink> as marshalling format. The sd-varlink
API relies on the
<citerefentry><refentrytitle>sd-json</refentrytitle><manvolnum>3</manvolnum></citerefentry> API for JSON
serialization, deserialization and manipulation.</para>
<para>The <citerefentry><refentrytitle>varlinkctl</refentrytitle><manvolnum>1</manvolnum></citerefentry> tool
makes the functionality implemented by sd-varlink available from the command line.</para>
</refsect1>
<xi:include href="libsystemd-pkgconfig.xml" />
<refsect1>
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>sd-event</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>sd-json</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>varlinkctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
<member><citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>
</refentry>

View File

@ -250,9 +250,10 @@
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para> <para><simplelist type="inline">
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</para> <member><citerefentry><refentrytitle>sd-device</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -77,9 +77,10 @@
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para> <para><simplelist type="inline">
<citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry> <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</para> <member><citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -226,10 +226,11 @@
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para><simplelist type="inline">
<para> <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<citerefentry><refentrytitle>systemd-path</refentrytitle><manvolnum>1</manvolnum></citerefentry> <member><citerefentry><refentrytitle>sd-path</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
</para> <member><citerefentry><refentrytitle>systemd-path</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -75,9 +75,9 @@
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para> <para><simplelist type="inline">
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</para> </simplelist></para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -71,9 +71,9 @@
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para> <para><simplelist type="inline">
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</para> </simplelist></para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -83,9 +83,9 @@
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para> <para><simplelist type="inline">
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</para> </simplelist></para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -79,9 +79,9 @@
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para> <para><simplelist type="inline">
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</para> </simplelist></para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -76,6 +76,7 @@
<member><citerefentry><refentrytitle>machine-info</refentrytitle><manvolnum>5</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>machine-info</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>hostnamectl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>hostnamectl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>sethostname</refentrytitle><manvolnum>2</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>sethostname</refentrytitle><manvolnum>2</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>org.freedesktop.hostname1</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
</simplelist></para> </simplelist></para>
</refsect1> </refsect1>

View File

@ -83,8 +83,9 @@
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para><citerefentry> <para>
<refentrytitle>hwdb</refentrytitle><manvolnum>7</manvolnum> <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
</citerefentry></para> <citerefentry><refentrytitle>hwdb</refentrytitle><manvolnum>7</manvolnum></citerefentry>
</para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -50,6 +50,7 @@
<member><citerefentry><refentrytitle>importctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>importctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-machined.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd-machined.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>org.freedesktop.import1</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
</simplelist></para> </simplelist></para>
</refsect1> </refsect1>

View File

@ -41,9 +41,9 @@
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para> <para><simplelist type="inline">
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</para> </simplelist></para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -55,6 +55,7 @@
<member><citerefentry><refentrytitle>vconsole.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>vconsole.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<member><citerefentry project='man-pages'><refentrytitle>localectl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> <member><citerefentry project='man-pages'><refentrytitle>localectl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry project='mankier'><refentrytitle>loadkeys</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> <member><citerefentry project='mankier'><refentrytitle>loadkeys</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>org.freedesktop.locale1</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
</simplelist></para> </simplelist></para>
</refsect1> </refsect1>

View File

@ -104,6 +104,7 @@
<member><citerefentry><refentrytitle>logind.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>logind.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>pam_systemd</refentrytitle><manvolnum>8</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>pam_systemd</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>3</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>org.freedesktop.login1</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
</simplelist></para> </simplelist></para>
</refsect1> </refsect1>

View File

@ -135,6 +135,7 @@
<member><citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>nss-mymachines</refentrytitle><manvolnum>8</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>nss-mymachines</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>org.freedesktop.machine1</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
</simplelist></para> </simplelist></para>
</refsect1> </refsect1>

View File

@ -77,7 +77,7 @@
<option>--osrel=</option>, <option>--cmdline=</option>, <option>--initrd=</option>, <option>--osrel=</option>, <option>--cmdline=</option>, <option>--initrd=</option>,
<option>--ucode=</option>, <option>--splash=</option>, <option>--dtb=</option>, <option>--ucode=</option>, <option>--splash=</option>, <option>--dtb=</option>,
<option>--uname=</option>, <option>--sbat=</option>, <option>--pcrpkey=</option>, <option>--uname=</option>, <option>--sbat=</option>, <option>--pcrpkey=</option>,
<option>--profile=</option>, see below. Only <option>--linux=</option> is mandatory. (Alternatively, <option>--profile=</option>, <option>--dtbauto=</option>, <option>--hwids=</option>, see below. Only <option>--linux=</option> is mandatory. (Alternatively,
specify <option>--current</option> to use the current values of PCR register 11 instead.)</para> specify <option>--current</option> to use the current values of PCR register 11 instead.)</para>
<xi:include href="version-info.xml" xpointer="v252"/> <xi:include href="version-info.xml" xpointer="v252"/>
@ -125,6 +125,8 @@
<term><option>--sbat=<replaceable>PATH</replaceable></option></term> <term><option>--sbat=<replaceable>PATH</replaceable></option></term>
<term><option>--pcrpkey=<replaceable>PATH</replaceable></option></term> <term><option>--pcrpkey=<replaceable>PATH</replaceable></option></term>
<term><option>--profile=<replaceable>PATH</replaceable></option></term> <term><option>--profile=<replaceable>PATH</replaceable></option></term>
<term><option>--dtbauto=<replaceable>PATH</replaceable></option></term>
<term><option>--hwids=<replaceable>PATH</replaceable></option></term>
<listitem><para>When used with the <command>calculate</command> or <command>sign</command> verb, <listitem><para>When used with the <command>calculate</command> or <command>sign</command> verb,
configures the files to read the unified kernel image components from. Each option corresponds with configures the files to read the unified kernel image components from. Each option corresponds with
@ -134,7 +136,7 @@
<xi:include href="version-info.xml" xpointer="v252"/> <xi:include href="version-info.xml" xpointer="v252"/>
<para id="v257">With the exception of <option>--profile=</option>, which has been added in version <para id="v257">With the exception of <option>--profile=</option>, <option>--dtbauto=</option> and <option>--hwids=</option>, which have been added in version
257.</para></listitem> 257.</para></listitem>
</varlistentry> </varlistentry>
@ -264,13 +266,15 @@
<example> <example>
<title>Generate a unified kernel image, and calculate the expected TPM PCR 11 value</title> <title>Generate a unified kernel image, and calculate the expected TPM PCR 11 value</title>
<programlisting>$ ukify --output=vmlinux.efi \ <programlisting>$ ukify build \
--linux=vmlinux \
--initrd=initrd.cpio \
--os-release=@os-release.txt \ --os-release=@os-release.txt \
--cmdline=@cmdline.txt \ --cmdline=@cmdline.txt \
--splash=splash.bmp \ --splash=splash.bmp \
--devicetree=devicetree.dtb \ --devicetree=devicetree.dtb \
--measure \ --measure \
vmlinux initrd.cpio --output=vmlinux.efi
11:sha1=d775a7b4482450ac77e03ee19bda90bd792d6ec7 11:sha1=d775a7b4482450ac77e03ee19bda90bd792d6ec7
11:sha256=bc6170f9ce28eb051ab465cd62be8cf63985276766cf9faf527ffefb66f45651 11:sha256=bc6170f9ce28eb051ab465cd62be8cf63985276766cf9faf527ffefb66f45651
11:sha384=1cf67dff4757e61e5...7f49ad720be02fd07263e1f93061243aec599d1ee4b4 11:sha384=1cf67dff4757e61e5...7f49ad720be02fd07263e1f93061243aec599d1ee4b4
@ -289,7 +293,7 @@
<programlisting>$ openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out tpm2-pcr-private-key.pem <programlisting>$ openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out tpm2-pcr-private-key.pem
..+.+++++++++......+.........+......+.......+....+.....+.+...+.......... ..+.+++++++++......+.........+......+.......+....+.....+.+...+..........
$ openssl rsa -pubout -in tpm2-pcr-private-key.pem -out tpm2-pcr-public-key.pem $ openssl rsa -pubout -in tpm2-pcr-private-key.pem -out tpm2-pcr-public-key.pem
# systemd-measure sign \ $ systemd-measure sign \
--linux=vmlinux \ --linux=vmlinux \
--osrel=os-release.txt \ --osrel=os-release.txt \
--cmdline=cmdline.txt \ --cmdline=cmdline.txt \
@ -301,7 +305,9 @@ $ openssl rsa -pubout -in tpm2-pcr-private-key.pem -out tpm2-pcr-public-key.pem
--bank=sha256 \ --bank=sha256 \
--private-key=tpm2-pcr-private-key.pem \ --private-key=tpm2-pcr-private-key.pem \
--public-key=tpm2-pcr-public-key.pem >tpm2-pcr-signature.json --public-key=tpm2-pcr-public-key.pem >tpm2-pcr-signature.json
# ukify --output=vmlinuz.efi \ $ ukify build \
--linux=vmlinux \
--initrd=initrd.cpio \
--os-release=@os-release.txt \ --os-release=@os-release.txt \
--cmdline=@cmdline.txt \ --cmdline=@cmdline.txt \
--splash=splash.bmp \ --splash=splash.bmp \
@ -309,7 +315,7 @@ $ openssl rsa -pubout -in tpm2-pcr-private-key.pem -out tpm2-pcr-public-key.pem
--pcr-private-key=tpm2-pcr-private-key.pem \ --pcr-private-key=tpm2-pcr-private-key.pem \
--pcr-public-key=tpm2-pcr-public-key.pem \ --pcr-public-key=tpm2-pcr-public-key.pem \
--pcr-banks=sha1,sha256 \ --pcr-banks=sha1,sha256 \
vmlinux initrd.cpio</programlisting> --output=vmlinuz.efi</programlisting>
<para>Later on, enroll the signed PCR policy on a LUKS volume:</para> <para>Later on, enroll the signed PCR policy on a LUKS volume:</para>
@ -345,7 +351,9 @@ $ openssl rsa -pubout -in tpm2-pcr-private-key.pem -out tpm2-pcr-public-key.pem
$ openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out tpm2-pcr-private-key-initrd.pem $ openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out tpm2-pcr-private-key-initrd.pem
..+.......++........+........+......+........+....+.....+.+..+.......... ..+.......++........+........+......+........+....+.....+.+..+..........
$ openssl rsa -pubout -in tpm2-pcr-private-key-initrd.pem -out tpm2-pcr-public-key-initrd.pem $ openssl rsa -pubout -in tpm2-pcr-private-key-initrd.pem -out tpm2-pcr-public-key-initrd.pem
# ukify --output vmlinux-1.2.3.efi \ $ ukify build \
--linux=vmlinux-1.2.3 \
--initrd=initrd.cpio \
--os-release=@os-release.txt \ --os-release=@os-release.txt \
--cmdline=@cmdline.txt \ --cmdline=@cmdline.txt \
--splash=splash.bmp \ --splash=splash.bmp \
@ -357,8 +365,8 @@ $ openssl rsa -pubout -in tpm2-pcr-private-key-initrd.pem -out tpm2-pcr-public-k
--pcr-private-key=tpm2-pcr-private-key-initrd.pem \ --pcr-private-key=tpm2-pcr-private-key-initrd.pem \
--pcr-public-key=tpm2-pcr-public-key-initrd.pem \ --pcr-public-key=tpm2-pcr-public-key-initrd.pem \
--phases=enter-initrd \ --phases=enter-initrd \
vmlinux-1.2.3 initrd.cpio \ --uname=1.2.3 \
--uname=1.2.3 --output=vmlinux-1.2.3.efi
+ /usr/lib/systemd/systemd-measure sign --linux=vmlinux-1.2.3 \ + /usr/lib/systemd/systemd-measure sign --linux=vmlinux-1.2.3 \
--osrel=os-release.txt --cmdline=cmdline.txt --dtb=devicetree.dtb \ --osrel=os-release.txt --cmdline=cmdline.txt --dtb=devicetree.dtb \
--splash=splash.bmp --initrd=initrd.cpio --bank=sha1 --bank=sha256 \ --splash=splash.bmp --initrd=initrd.cpio --bank=sha1 --bank=sha256 \

View File

@ -62,9 +62,9 @@
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para> <para><simplelist type="inline">
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>, <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<citerefentry><refentrytitle>systemd-nsresourced.service</refentrytitle><manvolnum>8</manvolnum></citerefentry> <member><citerefentry><refentrytitle>systemd-nsresourced.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
</para> </simplelist></para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -63,6 +63,12 @@
<para><command>systemd-networkd</command> may be introspected and controlled at runtime using <para><command>systemd-networkd</command> may be introspected and controlled at runtime using
<citerefentry><refentrytitle>networkctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>. <citerefentry><refentrytitle>networkctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
</para> </para>
<para>See
<citerefentry><refentrytitle>org.freedesktop.network1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>org.freedesktop.LogControl1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for a description of the D-Bus API.</para>
</refsect1> </refsect1>
<refsect1><title>Configuration Files</title> <refsect1><title>Configuration Files</title>
@ -91,6 +97,7 @@
<member><citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-networkd-wait-online.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd-networkd-wait-online.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-network-generator.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd-network-generator.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>org.freedesktop.network1</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
</simplelist></para> </simplelist></para>
</refsect1> </refsect1>

View File

@ -69,13 +69,13 @@
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para> <para><simplelist type="inline">
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>, <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<citerefentry><refentrytitle>systemd-mountfsd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>, <member><citerefentry><refentrytitle>systemd-mountfsd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>, <member><citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>, <member><citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<citerefentry><refentrytitle>systemd-dissect</refentrytitle><manvolnum>1</manvolnum></citerefentry>, <member><citerefentry><refentrytitle>systemd-dissect</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<citerefentry project='man-pages'><refentrytitle>user_namespaces</refentrytitle><manvolnum>7</manvolnum></citerefentry> <member><citerefentry project='man-pages'><refentrytitle>user_namespaces</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
</para> </simplelist></para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -57,6 +57,12 @@
<para>See <citerefentry><refentrytitle>oomd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> <para>See <citerefentry><refentrytitle>oomd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for more information about the configuration of this service.</para> for more information about the configuration of this service.</para>
<para>See
<citerefentry><refentrytitle>org.freedesktop.oom1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>org.freedesktop.LogControl1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for a description of the D-Bus API.</para>
</refsect1> </refsect1>
<refsect1> <refsect1>
@ -129,6 +135,7 @@
<member><citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>oomd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>oomd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>oomctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>oomctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>org.freedesktop.oom1</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
</simplelist></para> </simplelist></para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -37,6 +37,12 @@
<para>See the <ulink url="https://systemd.io/PORTABLE_SERVICES">Portable Services</ulink> page <para>See the <ulink url="https://systemd.io/PORTABLE_SERVICES">Portable Services</ulink> page
for details about the concepts this service implements.</para> for details about the concepts this service implements.</para>
<para>See
<citerefentry><refentrytitle>org.freedesktop.portable1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>org.freedesktop.LogControl1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for a description of the D-Bus API.</para>
</refsect1> </refsect1>
<refsect1> <refsect1>

View File

@ -44,7 +44,7 @@
<filename>kexec.target</filename> to execute the respective actions.</para> <filename>kexec.target</filename> to execute the respective actions.</para>
<para>When these services are run, they ensure that PID 1 is replaced by the <para>When these services are run, they ensure that PID 1 is replaced by the
<filename>/usr/lib/systemd/systemd-shutdown</filename> tool which is then responsible for the actual <filename>/usr/lib/systemd/systemd-shutdown</filename> binary which is then responsible for the actual
shutdown. Before shutting down, this binary will try to unmount all remaining file systems (or at least shutdown. Before shutting down, this binary will try to unmount all remaining file systems (or at least
remount them read-only), disable all remaining swap devices, detach all remaining storage devices and remount them read-only), disable all remaining swap devices, detach all remaining storage devices and
kill all remaining processes.</para> kill all remaining processes.</para>
@ -58,12 +58,12 @@
<filename>/usr/lib/systemd/system-shutdown/</filename> and pass one arguments to them: either <filename>/usr/lib/systemd/system-shutdown/</filename> and pass one arguments to them: either
<literal>poweroff</literal>, <literal>halt</literal>, <literal>reboot</literal>, or <literal>poweroff</literal>, <literal>halt</literal>, <literal>reboot</literal>, or
<literal>kexec</literal>, depending on the chosen action. All executables in this directory are executed <literal>kexec</literal>, depending on the chosen action. All executables in this directory are executed
in parallel, and execution of the action is not continued before all executables finished. Note that in parallel, and execution of the action is not continued before all executables finished. (A safety
these executables are run <emphasis>after</emphasis> all services have been shut down, and after most timeout of 90s is applied however.) Note that these executables are run <emphasis>after</emphasis> all
mounts have been unmounted (the root file system as well as <filename>/run/</filename> and various API services have been shut down, and after most mounts have been unmounted (the root file system as well as
file systems are still around though). This means any programs dropped into this directory must be <filename>/run/</filename> and various API file systems are still around though). This means any programs
prepared to run in such a limited execution environment and not rely on external services or hierarchies dropped into this directory must be prepared to run in such a limited execution environment and not rely
such as <filename>/var/</filename> to be around (or writable).</para> on external services or hierarchies such as <filename>/var/</filename> to be around (or writable).</para>
<para>Note that <filename>systemd-poweroff.service</filename> (and the related units) should never be <para>Note that <filename>systemd-poweroff.service</filename> (and the related units) should never be
executed directly. Instead, trigger system shutdown with a command such as <literal>systemctl executed directly. Instead, trigger system shutdown with a command such as <literal>systemctl

View File

@ -107,8 +107,8 @@
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para> <para><simplelist type="inline">
<citerefentry><refentrytitle>pstore.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> <member><citerefentry><refentrytitle>pstore.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
</para> </simplelist></para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -516,6 +516,7 @@ search foobar.com barbar.com
<member><citerefentry project='man-pages'><refentrytitle>hosts</refentrytitle><manvolnum>5</manvolnum></citerefentry></member> <member><citerefentry project='man-pages'><refentrytitle>hosts</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>org.freedesktop.resolve1</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
</simplelist></para> </simplelist></para>
</refsect1> </refsect1>

View File

@ -60,9 +60,9 @@
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para> <para><simplelist type="inline">
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</para> </simplelist></para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -79,6 +79,20 @@
<listitem><para>A <literal>.dtb</literal> section with a compiled binary DeviceTree.</para></listitem> <listitem><para>A <literal>.dtb</literal> section with a compiled binary DeviceTree.</para></listitem>
<listitem><para>Zero or more <literal>.dtbauto</literal> sections. Stub will always try to find first matching one.
Matching process extracts first <varname>compatible</varname> string from <literal>.dtbauto</literal>
section and compares it with the first Devicetree's <varname>compatible</varname> string supplied by
the firmware in configuration tables. If firmware does not provide Devicetree, matching with
<varname>.hwids</varname> section will be used instead. Stub will use SMBIOS data to calculate hardware
IDs of the machine (as per <ulink url="https://learn.microsoft.com/en-us/windows-hardware/drivers/install/specifying-hardware-ids-for-a-computer">specification</ulink>),
then it will proceed to trying to find any of them in <literal>.hwids</literal> section and will use first
matching entry's <varname>compatible</varname> as a search key among the <literal>.dtbauto</literal>
entries, in a similar fashion as the use of <varname>compatible</varname> string read from the firmware
provided Devicetree was described before. First matching <literal>.dtbauto</literal> section will be
loaded and will override <varname>.dtb</varname> if present.</para></listitem>
<listitem><para>A <literal>.hwids</literal> section with hardware IDs of the machines to match Devicetrees (refer to <literal>.dtbauto</literal> section description).</para></listitem>
<listitem><para>A <literal>.uname</literal> section with the kernel version information, i.e. the <listitem><para>A <literal>.uname</literal> section with the kernel version information, i.e. the
output of <command>uname -r</command> for the kernel included in the <literal>.linux</literal> output of <command>uname -r</command> for the kernel included in the <literal>.linux</literal>
section.</para></listitem> section.</para></listitem>

View File

@ -45,11 +45,12 @@
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para> <para><simplelist type="inline">
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>, <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<citerefentry><refentrytitle>systemd-sysupdate</refentrytitle><manvolnum>8</manvolnum></citerefentry> <member><citerefentry><refentrytitle>systemd-sysupdate</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<citerefentry><refentrytitle>updatectl</refentrytitle><manvolnum>1</manvolnum></citerefentry> <member><citerefentry><refentrytitle>updatectl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</para> <member><citerefentry><refentrytitle>org.freedesktop.sysupdate1</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -99,6 +99,7 @@ systemd-timesyncd.service
<member><citerefentry><refentrytitle>localtime</refentrytitle><manvolnum>5</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>localtime</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<member><citerefentry project='man-pages'><refentrytitle>hwclock</refentrytitle><manvolnum>8</manvolnum></citerefentry></member> <member><citerefentry project='man-pages'><refentrytitle>hwclock</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-timesyncd</refentrytitle><manvolnum>8</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd-timesyncd</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>org.freedesktop.timedate1</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
</simplelist></para> </simplelist></para>
</refsect1> </refsect1>

View File

@ -75,8 +75,8 @@
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para> <para><simplelist type="inline">
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</para> </simplelist></para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -893,8 +893,6 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
<refsect1> <refsect1>
<title>Mandatory Access Control</title> <title>Mandatory Access Control</title>
<xi:include href="system-only.xml" xpointer="plural"/>
<variablelist class='unit-directives'> <variablelist class='unit-directives'>
<varlistentry> <varlistentry>
@ -921,6 +919,8 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
prefixed by <literal>-</literal>, all errors will be ignored. This setting has no effect if AppArmor prefixed by <literal>-</literal>, all errors will be ignored. This setting has no effect if AppArmor
is not enabled. This setting does not affect commands prefixed with <literal>+</literal>.</para> is not enabled. This setting does not affect commands prefixed with <literal>+</literal>.</para>
<xi:include href="system-only.xml" xpointer="singular"/>
<xi:include href="version-info.xml" xpointer="v210"/> <xi:include href="version-info.xml" xpointer="v210"/>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -939,6 +939,8 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
value may be specified to unset previous assignments. This does not affect commands prefixed with value may be specified to unset previous assignments. This does not affect commands prefixed with
<literal>+</literal>.</para> <literal>+</literal>.</para>
<xi:include href="system-only.xml" xpointer="singular"/>
<xi:include href="version-info.xml" xpointer="v218"/></listitem> <xi:include href="version-info.xml" xpointer="v218"/></listitem>
</varlistentry> </varlistentry>
@ -1431,6 +1433,10 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
set. This setting cannot ensure protection in all cases. In general it has the same limitations as set. This setting cannot ensure protection in all cases. In general it has the same limitations as
<varname>ReadOnlyPaths=</varname>, see below. Defaults to off.</para> <varname>ReadOnlyPaths=</varname>, see below. Defaults to off.</para>
<para>Note that if <varname>ProtectSystem=</varname> is set to <literal>strict</literal> and
<varname>PrivateTmp=</varname> is enabled, then <filename>/tmp/</filename> and
<filename>/var/tmp/</filename> will be writable.</para>
<xi:include href="version-info.xml" xpointer="v214"/></listitem> <xi:include href="version-info.xml" xpointer="v214"/></listitem>
</varlistentry> </varlistentry>

View File

@ -153,11 +153,14 @@
not apply to <varname>PathChanged=</varname> and not apply to <varname>PathChanged=</varname> and
<varname>PathModified=</varname>.</para> <varname>PathModified=</varname>.</para>
<para>If the path itself or any of the containing directories <para>If the path itself or any of the containing directories are not accessible,
are not accessible, <command>systemd</command> will watch for <command>systemd</command> will watch for permission changes and notice that conditions are satisfied
permission changes and notice that conditions are satisfied when permissions allow that. </para>
when permissions allow that. </para></listitem>
<para>Note that files whose name starts with a dot (i.e. hidden files) are generally ignored when
monitoring these paths.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>Unit=</varname></term> <term><varname>Unit=</varname></term>

View File

@ -551,11 +551,11 @@
<varname>ExecStop=</varname> commands specified with this setting are invoked when a service failed to start <varname>ExecStop=</varname> commands specified with this setting are invoked when a service failed to start
up correctly and is shut down again.</para> up correctly and is shut down again.</para>
<para>It is recommended to use this setting for clean-up operations that shall be executed even when the <para>It is recommended to use this setting for clean-up operations that shall be executed even when
service failed to start up correctly. Commands configured with this setting need to be able to operate even if the service failed to start up correctly. Commands configured with this setting need to be able to
the service failed starting up half-way and left incompletely initialized data around. As the service's operate even if the service failed starting up half-way and left incompletely initialized data
processes have been terminated already when the commands specified with this setting are executed they should around. As the service's processes have likely exited already when the commands specified with this
not attempt to communicate with them.</para> setting are executed they should not attempt to communicate with them.</para>
<para>Note that all commands that are configured with this setting are invoked with the result code of the <para>Note that all commands that are configured with this setting are invoked with the result code of the
service, as well as the main process' exit code and status, set in the <varname>$SERVICE_RESULT</varname>, service, as well as the main process' exit code and status, set in the <varname>$SERVICE_RESULT</varname>,

View File

@ -224,9 +224,10 @@ KeyThree=value 3\
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para> <para><simplelist type="inline">
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry> <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</para> <member><citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -1590,6 +1590,7 @@
<member><citerefentry><refentrytitle>kernel-command-line</refentrytitle><manvolnum>7</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>kernel-command-line</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
<member><citerefentry project='man-pages'><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry></member> <member><citerefentry project='man-pages'><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd.directives</refentrytitle><manvolnum>7</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd.directives</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>org.freedesktop.systemd1</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
</simplelist></para> </simplelist></para>
<para>For more information about the concepts and <para>For more information about the concepts and

View File

@ -82,9 +82,10 @@
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para> <para><simplelist type="inline">
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>, <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</para> <member><citerefentry><refentrytitle>systemd-udevd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -12,7 +12,7 @@ msgid ""
msgstr "" msgstr ""
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-23 15:33+0200\n" "POT-Creation-Date: 2024-08-23 15:33+0200\n"
"PO-Revision-Date: 2024-09-06 09:38+0000\n" "PO-Revision-Date: 2024-11-06 12:46+0000\n"
"Last-Translator: Léane GRASSER <leane.grasser@proton.me>\n" "Last-Translator: Léane GRASSER <leane.grasser@proton.me>\n"
"Language-Team: French <https://translate.fedoraproject.org/projects/systemd/" "Language-Team: French <https://translate.fedoraproject.org/projects/systemd/"
"main/fr/>\n" "main/fr/>\n"
@ -21,7 +21,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n" "Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 5.7.2\n" "X-Generator: Weblate 5.8.2\n"
#: src/core/org.freedesktop.systemd1.policy.in:22 #: src/core/org.freedesktop.systemd1.policy.in:22
msgid "Send passphrase back to system" msgid "Send passphrase back to system"
@ -815,27 +815,27 @@ msgstr ""
#: src/login/org.freedesktop.login1.policy:374 #: src/login/org.freedesktop.login1.policy:374
msgid "Indicate to the boot loader to boot to the boot loader menu" msgid "Indicate to the boot loader to boot to the boot loader menu"
msgstr "Indiquer au boot loader d'afficher le menu de sélection" msgstr "Indiquer au bootloader de démarrer sur le menu de sélection"
#: src/login/org.freedesktop.login1.policy:375 #: src/login/org.freedesktop.login1.policy:375
msgid "" msgid ""
"Authentication is required to indicate to the boot loader to boot to the " "Authentication is required to indicate to the boot loader to boot to the "
"boot loader menu." "boot loader menu."
msgstr "" msgstr ""
"Une authentification est requise pour indiquer au boot loader d'afficher le " "Une authentification est requise pour indiquer au bootloader de démarrer sur "
"menu de sélection." "le menu de sélection."
#: src/login/org.freedesktop.login1.policy:385 #: src/login/org.freedesktop.login1.policy:385
msgid "Indicate to the boot loader to boot a specific entry" msgid "Indicate to the boot loader to boot a specific entry"
msgstr "Indiquer au boot loader de démarrer une entrée spécifique" msgstr "Indiquer au bootloader de démarrer une entrée spécifique"
#: src/login/org.freedesktop.login1.policy:386 #: src/login/org.freedesktop.login1.policy:386
msgid "" msgid ""
"Authentication is required to indicate to the boot loader to boot into a " "Authentication is required to indicate to the boot loader to boot into a "
"specific boot loader entry." "specific boot loader entry."
msgstr "" msgstr ""
"Une authentification est requise pour indiquer au boot loader de démarrer " "Une authentification est requise pour indiquer au bootloader de démarrer une "
"une entrée spécifique." "entrée spécifique."
#: src/login/org.freedesktop.login1.policy:396 #: src/login/org.freedesktop.login1.policy:396
msgid "Set a wall message" msgid "Set a wall message"

View File

@ -527,19 +527,19 @@ int is_idmapping_supported(const char *path) {
return r; return r;
userns_fd = userns_acquire(uid_map, gid_map); userns_fd = userns_acquire(uid_map, gid_map);
if (ERRNO_IS_NEG_NOT_SUPPORTED(userns_fd)) if (ERRNO_IS_NEG_NOT_SUPPORTED(userns_fd) || ERRNO_IS_NEG_PRIVILEGE(userns_fd))
return false; return false;
if (userns_fd < 0) if (userns_fd < 0)
return log_debug_errno(userns_fd, "ID-mapping supported namespace acquire failed for '%s' : %m", path); return log_debug_errno(userns_fd, "ID-mapping supported namespace acquire failed for '%s' : %m", path);
dir_fd = RET_NERRNO(open(path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW)); dir_fd = RET_NERRNO(open(path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW));
if (ERRNO_IS_NEG_NOT_SUPPORTED(dir_fd) || dir_fd == -EINVAL) if (ERRNO_IS_NEG_NOT_SUPPORTED(dir_fd))
return false; return false;
if (dir_fd < 0) if (dir_fd < 0)
return log_debug_errno(dir_fd, "ID-mapping supported open failed for '%s' : %m", path); return log_debug_errno(dir_fd, "ID-mapping supported open failed for '%s' : %m", path);
mount_fd = RET_NERRNO(open_tree(dir_fd, "", AT_EMPTY_PATH | OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC)); mount_fd = RET_NERRNO(open_tree(dir_fd, "", AT_EMPTY_PATH | OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC));
if (ERRNO_IS_NEG_NOT_SUPPORTED(mount_fd) || mount_fd == -EINVAL) if (ERRNO_IS_NEG_NOT_SUPPORTED(mount_fd) || ERRNO_IS_NEG_PRIVILEGE(mount_fd) || mount_fd == -EINVAL)
return false; return false;
if (mount_fd < 0) if (mount_fd < 0)
return log_debug_errno(mount_fd, "ID-mapping supported open_tree failed for '%s' : %m", path); return log_debug_errno(mount_fd, "ID-mapping supported open_tree failed for '%s' : %m", path);
@ -549,7 +549,7 @@ int is_idmapping_supported(const char *path) {
.attr_set = MOUNT_ATTR_IDMAP | MOUNT_ATTR_NOSUID | MOUNT_ATTR_NOEXEC | MOUNT_ATTR_RDONLY | MOUNT_ATTR_NODEV, .attr_set = MOUNT_ATTR_IDMAP | MOUNT_ATTR_NOSUID | MOUNT_ATTR_NOEXEC | MOUNT_ATTR_RDONLY | MOUNT_ATTR_NODEV,
.userns_fd = userns_fd, .userns_fd = userns_fd,
}, sizeof(struct mount_attr))); }, sizeof(struct mount_attr)));
if (ERRNO_IS_NEG_NOT_SUPPORTED(r) || r == -EINVAL || r == -EPERM) if (ERRNO_IS_NEG_NOT_SUPPORTED(r) || ERRNO_IS_NEG_PRIVILEGE(r) || r == -EINVAL)
return false; return false;
if (r < 0) if (r < 0)
return log_debug_errno(r, "ID-mapping supported setattr failed for '%s' : %m", path); return log_debug_errno(r, "ID-mapping supported setattr failed for '%s' : %m", path);

View File

@ -35,6 +35,7 @@
#include "fileio.h" #include "fileio.h"
#include "fs-util.h" #include "fs-util.h"
#include "hostname-util.h" #include "hostname-util.h"
#include "io-util.h"
#include "locale-util.h" #include "locale-util.h"
#include "log.h" #include "log.h"
#include "macro.h" #include "macro.h"
@ -2238,3 +2239,18 @@ static const char* const sched_policy_table[] = {
}; };
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX); DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
_noreturn_ void report_errno_and_exit(int errno_fd, int error) {
int r;
if (error >= 0)
_exit(EXIT_SUCCESS);
assert(errno_fd >= 0);
r = loop_write(errno_fd, &error, sizeof(error));
if (r < 0)
log_debug_errno(r, "Failed to write errno to errno_fd=%d: %m", errno_fd);
_exit(EXIT_FAILURE);
}

View File

@ -273,3 +273,5 @@ int posix_spawn_wrapper(
int proc_dir_open(DIR **ret); int proc_dir_open(DIR **ret);
int proc_dir_read(DIR *d, pid_t *ret); int proc_dir_read(DIR *d, pid_t *ret);
int proc_dir_read_pidref(DIR *d, PidRef *ret); int proc_dir_read_pidref(DIR *d, PidRef *ret);
_noreturn_ void report_errno_and_exit(int errno_fd, int error);

View File

@ -194,14 +194,14 @@ static int version_check(int fd_from, const char *from, int fd_to, const char *t
if (r == -ESRCH) if (r == -ESRCH)
return log_notice_errno(r, "Source file \"%s\" does not carry version information!", from); return log_notice_errno(r, "Source file \"%s\" does not carry version information!", from);
if (r < 0) if (r < 0)
return r; return log_error_errno(r, "Failed to get version information of source file \"%s\": %m", from);
r = get_file_version(fd_to, &b); r = get_file_version(fd_to, &b);
if (r == -ESRCH) if (r == -ESRCH)
return log_notice_errno(r, "Skipping \"%s\", it's owned by another boot loader (no version info found).", return log_notice_errno(r, "Skipping \"%s\", it's owned by another boot loader (no version info found).",
to); to);
if (r < 0) if (r < 0)
return r; return log_error_errno(r, "Failed to get version information of \"%s\": %m", to);
if (compare_product(a, b) != 0) if (compare_product(a, b) != 0)
return log_notice_errno(SYNTHETIC_ERRNO(ESRCH), return log_notice_errno(SYNTHETIC_ERRNO(ESRCH),
"Skipping \"%s\", it's owned by another boot loader.", to); "Skipping \"%s\", it's owned by another boot loader.", to);
@ -324,11 +324,15 @@ static int create_subdirs(const char *root, const char * const *subdirs) {
return 0; return 0;
} }
static int update_efi_boot_binaries(const char *esp_path, const char *source_path) { static int update_efi_boot_binaries(const char *esp_path, const char *source_path, const char *exclude_path) {
_cleanup_closedir_ DIR *d = NULL; _cleanup_closedir_ DIR *d = NULL;
_cleanup_free_ char *p = NULL; _cleanup_free_ char *p = NULL;
int r, ret = 0; int r, ret = 0;
assert(esp_path);
assert(source_path);
assert(exclude_path);
r = chase_and_opendir("/EFI/BOOT", esp_path, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS, &p, &d); r = chase_and_opendir("/EFI/BOOT", esp_path, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS, &p, &d);
if (r == -ENOENT) if (r == -ENOENT)
return 0; return 0;
@ -339,9 +343,16 @@ static int update_efi_boot_binaries(const char *esp_path, const char *source_pat
_cleanup_close_ int fd = -EBADF; _cleanup_close_ int fd = -EBADF;
_cleanup_free_ char *v = NULL; _cleanup_free_ char *v = NULL;
if (de->d_type != DT_REG)
continue;
if (!endswith_no_case(de->d_name, ".efi")) if (!endswith_no_case(de->d_name, ".efi"))
continue; continue;
/* Skip the file that is already updated. */
if (path_equal_filename(de->d_name, exclude_path))
continue;
fd = openat(dirfd(d), de->d_name, O_RDONLY|O_CLOEXEC); fd = openat(dirfd(d), de->d_name, O_RDONLY|O_CLOEXEC);
if (fd < 0) if (fd < 0)
return log_error_errno(errno, "Failed to open \"%s/%s\" for reading: %m", p, de->d_name); return log_error_errno(errno, "Failed to open \"%s/%s\" for reading: %m", p, de->d_name);
@ -422,7 +433,7 @@ static int copy_one_file(const char *esp_path, const char *name, bool force) {
/* If we were installed under any other name in /EFI/BOOT, make sure we update those binaries /* If we were installed under any other name in /EFI/BOOT, make sure we update those binaries
* as well. */ * as well. */
if (!force) if (!force)
RET_GATHER(ret, update_efi_boot_binaries(esp_path, source_path)); RET_GATHER(ret, update_efi_boot_binaries(esp_path, source_path, default_dest_path));
} }
return ret; return ret;

129
src/boot/efi/chid.c Normal file
View File

@ -0,0 +1,129 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/*
* Based on Nikita Travkin's dtbloader implementation.
* Copyright (c) 2024 Nikita Travkin <nikita@trvn.ru>
*
* https://github.com/TravMurav/dtbloader/blob/main/src/chid.c
*/
/*
* Based on Linaro dtbloader implementation.
* Copyright (c) 2019, Linaro. All rights reserved.
*
* https://github.com/aarch64-laptops/edk2/blob/dtbloader-app/EmbeddedPkg/Application/ConfigTableLoader/CHID.c
*/
#include "chid.h"
#include "chid-fundamental.h"
#include "efi.h"
#include "sha1-fundamental.h"
#include "smbios.h"
#include "util.h"
/**
* smbios_to_hashable_string() - Convert ascii smbios string to stripped char16_t.
*/
static char16_t *smbios_to_hashable_string(const char *str) {
if (!str)
/* User of this function is expected to free the result. */
return xnew0(char16_t, 1);
/*
* We need to strip leading and trailing spaces, leading zeroes.
* See fwupd/libfwupdplugin/fu-hwids-smbios.c
*/
while (*str == ' ')
str++;
while (*str == '0')
str++;
size_t len = strlen8(str);
while (len > 0 && str[len - 1] == ' ')
len--;
return xstrn8_to_16(str, len);
}
/* This has to be in a struct due to _cleanup_ in populate_board_chids */
typedef struct SmbiosInfo {
const char16_t *smbios_fields[_CHID_SMBIOS_FIELDS_MAX];
} SmbiosInfo;
static void smbios_info_populate(SmbiosInfo *ret_info) {
static RawSmbiosInfo raw = {};
static bool raw_info_populated = false;
if (!raw_info_populated) {
smbios_raw_info_populate(&raw);
raw_info_populated = true;
}
ret_info->smbios_fields[CHID_SMBIOS_MANUFACTURER] = smbios_to_hashable_string(raw.manufacturer);
ret_info->smbios_fields[CHID_SMBIOS_PRODUCT_NAME] = smbios_to_hashable_string(raw.product_name);
ret_info->smbios_fields[CHID_SMBIOS_PRODUCT_SKU] = smbios_to_hashable_string(raw.product_sku);
ret_info->smbios_fields[CHID_SMBIOS_FAMILY] = smbios_to_hashable_string(raw.family);
ret_info->smbios_fields[CHID_SMBIOS_BASEBOARD_PRODUCT] = smbios_to_hashable_string(raw.baseboard_product);
ret_info->smbios_fields[CHID_SMBIOS_BASEBOARD_MANUFACTURER] = smbios_to_hashable_string(raw.baseboard_manufacturer);
}
static void smbios_info_done(SmbiosInfo *info) {
FOREACH_ELEMENT(i, info->smbios_fields)
free(i);
}
static EFI_STATUS populate_board_chids(EFI_GUID ret_chids[static CHID_TYPES_MAX]) {
_cleanup_(smbios_info_done) SmbiosInfo info = {};
if (!ret_chids)
return EFI_INVALID_PARAMETER;
smbios_info_populate(&info);
chid_calculate(info.smbios_fields, ret_chids);
return EFI_SUCCESS;
}
EFI_STATUS chid_match(const void *hwid_buffer, size_t hwid_length, const Device **ret_device) {
EFI_STATUS status;
if ((uintptr_t) hwid_buffer % alignof(Device) != 0)
return EFI_INVALID_PARAMETER;
const Device *devices = ASSERT_PTR(hwid_buffer);
EFI_GUID chids[CHID_TYPES_MAX] = {};
static const size_t priority[] = { 3, 6, 8, 10, 4, 5, 7, 9, 11 }; /* From most to least specific. */
status = populate_board_chids(chids);
if (EFI_STATUS_IS_ERROR(status))
return log_error_status(status, "Failed to populate board CHIDs: %m");
size_t n_devices = 0;
/* Count devices and check validity */
for (; (n_devices + 1) * sizeof(*devices) < hwid_length;) {
if (devices[n_devices].struct_size == 0)
break;
if (devices[n_devices].struct_size != sizeof(*devices))
return EFI_UNSUPPORTED;
n_devices++;
}
if (n_devices == 0)
return EFI_NOT_FOUND;
FOREACH_ELEMENT(i, priority)
FOREACH_ARRAY(dev, devices, n_devices) {
/* Can't take a pointer to a packed struct member, so copy to a local variable */
EFI_GUID chid = dev->chid;
if (efi_guid_equal(&chids[*i], &chid)) {
*ret_device = dev;
return EFI_SUCCESS;
}
}
return EFI_NOT_FOUND;
}

23
src/boot/efi/chid.h Normal file
View File

@ -0,0 +1,23 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#pragma once
#include "efi.h"
#include "chid-fundamental.h"
typedef struct Device {
uint32_t struct_size; /* = sizeof(struct Device), or 0 for EOL */
uint32_t name_offset; /* nul-terminated string or 0 if not present */
uint32_t compatible_offset; /* nul-terminated string or 0 if not present */
EFI_GUID chid;
} _packed_ Device;
static inline const char* device_get_name(const void *base, const Device *device) {
return device->name_offset == 0 ? NULL : (const char *) ((const uint8_t *) base + device->name_offset);
}
static inline const char* device_get_compatible(const void *base, const Device *device) {
return device->compatible_offset == 0 ? NULL : (const char *) ((const uint8_t *) base + device->compatible_offset);
}
EFI_STATUS chid_match(const void *chids_buffer, size_t chids_length, const Device **ret_device);

View File

@ -106,6 +106,129 @@ EFI_STATUS devicetree_install(struct devicetree_state *state, EFI_FILE *root_dir
MAKE_GUID_PTR(EFI_DTB_TABLE), PHYSICAL_ADDRESS_TO_POINTER(state->addr)); MAKE_GUID_PTR(EFI_DTB_TABLE), PHYSICAL_ADDRESS_TO_POINTER(state->addr));
} }
static const char* devicetree_get_compatible(const void *dtb) {
if ((uintptr_t) dtb % alignof(FdtHeader) != 0)
return NULL;
const FdtHeader *dt_header = ASSERT_PTR(dtb);
if (be32toh(dt_header->magic) != UINT32_C(0xd00dfeed))
return NULL;
uint32_t dt_size = be32toh(dt_header->total_size);
uint32_t struct_off = be32toh(dt_header->off_dt_struct);
uint32_t struct_size = be32toh(dt_header->size_dt_struct);
uint32_t strings_off = be32toh(dt_header->off_dt_strings);
uint32_t strings_size = be32toh(dt_header->size_dt_strings);
uint32_t end;
if (PTR_TO_SIZE(dtb) > SIZE_MAX - dt_size)
return NULL;
if (!ADD_SAFE(&end, strings_off, strings_size) || end > dt_size)
return NULL;
const char *strings_block = (const char *) ((const uint8_t *) dt_header + strings_off);
if (struct_off % sizeof(uint32_t) != 0)
return NULL;
if (struct_size % sizeof(uint32_t) != 0 ||
!ADD_SAFE(&end, struct_off, struct_size) ||
end > strings_off)
return NULL;
const uint32_t *cursor = (const uint32_t *) ((const uint8_t *) dt_header + struct_off);
size_t size_words = struct_size / sizeof(uint32_t);
size_t len, name_off, len_words, s;
for (size_t i = 0; i < end; i++) {
switch (be32toh(cursor[i])) {
case FDT_BEGIN_NODE:
if (i >= size_words || cursor[++i] != 0)
return NULL;
break;
case FDT_NOP:
break;
case FDT_PROP:
/* At least 3 words should present: len, name_off, c (nul-terminated string always has non-zero length) */
if (i + 3 >= size_words || cursor[++i] != 0)
return NULL;
len = be32toh(cursor[++i]);
name_off = be32toh(cursor[++i]);
len_words = DIV_ROUND_UP(len, sizeof(uint32_t));
if (ADD_SAFE(&s, name_off, STRLEN("compatible")) &&
s < strings_size && streq8(strings_block + name_off, "compatible")) {
const char *c = (const char *) &cursor[++i];
if (len == 0 || i + len_words > size_words || c[len - 1] != '\0')
c = NULL;
return c;
}
i += len_words;
break;
default:
return NULL;
}
}
return NULL;
}
bool firmware_devicetree_exists(void) {
return !!find_configuration_table(MAKE_GUID_PTR(EFI_DTB_TABLE));
}
/* This function checks if the firmware provided Devicetree
* and a UKI provided Devicetree contain the same first entry
* on their respective "compatible" fields (which usually defines
* the actual device model). More specifically, given the FW/UKI
* "compatible" property pair:
*
* compatible = "string1", "string2";
* compatible = "string1", "string3";
*
* the function reports a match, while for
*
* compatible = "string1", "string3";
* compatible = "string2", "string1";
*
* it reports a mismatch.
*
* Other entries might refer to SoC and therefore can't be used for matching
*/
EFI_STATUS devicetree_match(const void *uki_dtb, size_t uki_dtb_length) {
const void *fw_dtb = find_configuration_table(MAKE_GUID_PTR(EFI_DTB_TABLE));
if (!fw_dtb)
return EFI_UNSUPPORTED;
const char *fw_compat = devicetree_get_compatible(fw_dtb);
if (!fw_compat)
return EFI_UNSUPPORTED;
return devicetree_match_by_compatible(uki_dtb, uki_dtb_length, fw_compat);
}
EFI_STATUS devicetree_match_by_compatible(const void *uki_dtb, size_t uki_dtb_length, const char *compat) {
if ((uintptr_t) uki_dtb % alignof(FdtHeader) != 0)
return EFI_INVALID_PARAMETER;
const FdtHeader *dt_header = ASSERT_PTR(uki_dtb);
if (uki_dtb_length < sizeof(FdtHeader) ||
uki_dtb_length < be32toh(dt_header->total_size))
return EFI_INVALID_PARAMETER;
if (!compat)
return EFI_INVALID_PARAMETER;
const char *dt_compat = devicetree_get_compatible(uki_dtb);
if (!dt_compat)
return EFI_INVALID_PARAMETER;
/* Only matches the first compatible string from each DT */
return streq8(dt_compat, compat) ? EFI_SUCCESS : EFI_NOT_FOUND;
}
EFI_STATUS devicetree_install_from_memory( EFI_STATUS devicetree_install_from_memory(
struct devicetree_state *state, const void *dtb_buffer, size_t dtb_length) { struct devicetree_state *state, const void *dtb_buffer, size_t dtb_length) {

View File

@ -9,6 +9,30 @@ struct devicetree_state {
void *orig; void *orig;
}; };
enum {
FDT_BEGIN_NODE = 1,
FDT_END_NODE = 2,
FDT_PROP = 3,
FDT_NOP = 4,
FDT_END = 9,
};
typedef struct FdtHeader {
uint32_t magic;
uint32_t total_size;
uint32_t off_dt_struct;
uint32_t off_dt_strings;
uint32_t off_mem_rsv_map;
uint32_t version;
uint32_t last_comp_version;
uint32_t boot_cpuid_phys;
uint32_t size_dt_strings;
uint32_t size_dt_struct;
} FdtHeader;
bool firmware_devicetree_exists(void);
EFI_STATUS devicetree_match(const void *uki_dtb, size_t uki_dtb_length);
EFI_STATUS devicetree_match_by_compatible(const void *uki_dtb, size_t uki_dtb_length, const char *compat);
EFI_STATUS devicetree_install(struct devicetree_state *state, EFI_FILE *root_dir, char16_t *name); EFI_STATUS devicetree_install(struct devicetree_state *state, EFI_FILE *root_dir, char16_t *name);
EFI_STATUS devicetree_install_from_memory( EFI_STATUS devicetree_install_from_memory(
struct devicetree_state *state, const void *dtb_buffer, size_t dtb_length); struct devicetree_state *state, const void *dtb_buffer, size_t dtb_length);

View File

@ -254,6 +254,7 @@ endif
############################################################ ############################################################
libefi_sources = files( libefi_sources = files(
'chid.c',
'console.c', 'console.c',
'device-path-util.c', 'device-path-util.c',
'devicetree.c', 'devicetree.c',

View File

@ -1,5 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "chid.h"
#include "devicetree.h"
#include "pe.h" #include "pe.h"
#include "util.h" #include "util.h"
@ -162,11 +164,46 @@ static bool pe_section_name_equal(const char *a, const char *b) {
return true; return true;
} }
static void pe_locate_sections( static bool pe_use_this_dtb(
const void *dtb,
size_t dtb_size,
const void *base,
const Device *device,
size_t section_nb) {
assert(dtb);
EFI_STATUS err;
err = devicetree_match(dtb, dtb_size);
if (err == EFI_SUCCESS)
return true;
if (err != EFI_UNSUPPORTED)
return false;
/* There's nothing to match against if firmware does not provide DTB and there is no .hwids section */
if (!device || !base)
return false;
const char *compatible = device_get_compatible(base, device);
if (!compatible)
return false;
err = devicetree_match_by_compatible(dtb, dtb_size, compatible);
if (err == EFI_SUCCESS)
return true;
if (err == EFI_INVALID_PARAMETER)
log_error_status(err, "Found bad DT blob in PE section %zu", section_nb);
return false;
}
static void pe_locate_sections_internal(
const PeSectionHeader section_table[], const PeSectionHeader section_table[],
size_t n_section_table, size_t n_section_table,
const char *const section_names[], const char *const section_names[],
size_t validate_base, size_t validate_base,
const void *device_table,
const Device *device,
PeSectionVector sections[]) { PeSectionVector sections[]) {
assert(section_table || n_section_table == 0); assert(section_table || n_section_table == 0);
@ -206,6 +243,20 @@ static void pe_locate_sections(
continue; continue;
} }
/* Special handling for .dtbauto sections compared to plain .dtb */
if (pe_section_name_equal(section_names[i], ".dtbauto")) {
/* .dtbauto sections require validate_base for matching */
if (!validate_base)
break;
if (!pe_use_this_dtb(
(const uint8_t *) SIZE_TO_PTR(validate_base) + j->VirtualAddress,
j->VirtualSize,
device_table,
device,
i))
continue;
}
/* At this time, the sizes and offsets have been validated. Store them away */ /* At this time, the sizes and offsets have been validated. Store them away */
sections[i] = (PeSectionVector) { sections[i] = (PeSectionVector) {
.memory_size = j->VirtualSize, .memory_size = j->VirtualSize,
@ -224,6 +275,73 @@ static void pe_locate_sections(
} }
} }
static bool looking_for_dbauto(const char *const section_names[]) {
assert(section_names);
for (size_t i = 0; section_names[i]; i++)
if (pe_section_name_equal(section_names[i], ".dtbauto"))
return true;
return false;
}
static void pe_locate_sections(
const PeSectionHeader section_table[],
size_t n_section_table,
const char *const section_names[],
size_t validate_base,
PeSectionVector sections[]) {
if (!looking_for_dbauto(section_names))
return pe_locate_sections_internal(
section_table,
n_section_table,
section_names,
validate_base,
/* device_base */ NULL,
/* device */ NULL,
sections);
/* It doesn't make sense not to provide validate_base here */
assert(validate_base != 0);
const void *hwids = NULL;
const Device *device = NULL;
if (!firmware_devicetree_exists()) {
/* Find HWIDs table and search for the current device */
PeSectionVector hwids_section = {};
pe_locate_sections_internal(
section_table,
n_section_table,
(const char *const[]) { ".hwids", NULL },
validate_base,
/* device_table */ NULL,
/* device */ NULL,
&hwids_section);
if (hwids_section.memory_offset != 0) {
hwids = (const uint8_t *) SIZE_TO_PTR(validate_base) + hwids_section.memory_offset;
EFI_STATUS err = chid_match(hwids, hwids_section.memory_size, &device);
if (err != EFI_SUCCESS) {
log_error_status(err, "HWID matching failed, no DT blob will be selected: %m");
hwids = NULL;
}
} else
log_info("HWIDs section is missing, no DT blob will be selected");
}
return pe_locate_sections_internal(
section_table,
n_section_table,
section_names,
validate_base,
hwids,
device,
sections);
}
static uint32_t get_compatibility_entry_address(const DosFileHeader *dos, const PeFileHeader *pe) { static uint32_t get_compatibility_entry_address(const DosFileHeader *dos, const PeFileHeader *pe) {
/* The kernel may provide alternative PE entry points for different PE architectures. This allows /* The kernel may provide alternative PE entry points for different PE architectures. This allows
* booting a 64-bit kernel on 32-bit EFI that is otherwise running on a 64-bit CPU. The locations of any * booting a 64-bit kernel on 32-bit EFI that is otherwise running on a 64-bit CPU. The locations of any

View File

@ -614,12 +614,13 @@ static EFI_STATUS load_addons(
if (err != EFI_SUCCESS || if (err != EFI_SUCCESS ||
(!PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_CMDLINE) && (!PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_CMDLINE) &&
!PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_DTB) && !PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_DTB) &&
!PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_DTBAUTO) &&
!PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_INITRD) && !PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_INITRD) &&
!PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_UCODE))) { !PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_UCODE))) {
if (err == EFI_SUCCESS) if (err == EFI_SUCCESS)
err = EFI_NOT_FOUND; err = EFI_NOT_FOUND;
log_error_status(err, log_error_status(err,
"Unable to locate embedded .cmdline/.dtb/.initrd/.ucode sections in %ls, ignoring: %m", "Unable to locate embedded .cmdline/.dtb/.dtbauto/.initrd/.ucode sections in %ls, ignoring: %m",
items[i]); items[i]);
continue; continue;
} }
@ -647,7 +648,21 @@ static EFI_STATUS load_addons(
*cmdline = xasprintf("%ls%ls%ls", strempty(tmp), isempty(tmp) ? u"" : u" ", extra16); *cmdline = xasprintf("%ls%ls%ls", strempty(tmp), isempty(tmp) ? u"" : u" ", extra16);
} }
if (devicetree_addons && PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_DTB)) { // FIXME: do we want to do something else here?
// This should behave exactly as .dtb/.dtbauto in the main UKI
if (devicetree_addons && PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_DTBAUTO)) {
*devicetree_addons = xrealloc(*devicetree_addons,
*n_devicetree_addons * sizeof(NamedAddon),
(*n_devicetree_addons + 1) * sizeof(NamedAddon));
(*devicetree_addons)[(*n_devicetree_addons)++] = (NamedAddon) {
.blob = {
.iov_base = xmemdup((const uint8_t*) loaded_addon->ImageBase + sections[UNIFIED_SECTION_DTBAUTO].memory_offset, sections[UNIFIED_SECTION_DTBAUTO].memory_size),
.iov_len = sections[UNIFIED_SECTION_DTBAUTO].memory_size,
},
.filename = xstrdup16(items[i]),
};
} else if (devicetree_addons && PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_DTB)) {
*devicetree_addons = xrealloc(*devicetree_addons, *devicetree_addons = xrealloc(*devicetree_addons,
*n_devicetree_addons * sizeof(NamedAddon), *n_devicetree_addons * sizeof(NamedAddon),
(*n_devicetree_addons + 1) * sizeof(NamedAddon)); (*n_devicetree_addons + 1) * sizeof(NamedAddon));
@ -968,13 +983,20 @@ static void install_embedded_devicetree(
assert(sections); assert(sections);
assert(dt_state); assert(dt_state);
if (!PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_DTB)) UnifiedSection section = _UNIFIED_SECTION_MAX;
/* Use automatically selected DT if available, otherwise go for "normal" one */
if (PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_DTBAUTO))
section = UNIFIED_SECTION_DTBAUTO;
else if (PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_DTB))
section = UNIFIED_SECTION_DTB;
else
return; return;
err = devicetree_install_from_memory( err = devicetree_install_from_memory(
dt_state, dt_state,
(const uint8_t*) loaded_image->ImageBase + sections[UNIFIED_SECTION_DTB].memory_offset, (const uint8_t*) loaded_image->ImageBase + sections[section].memory_offset,
sections[UNIFIED_SECTION_DTB].memory_size); sections[section].memory_size);
if (err != EFI_SUCCESS) if (err != EFI_SUCCESS)
log_error_status(err, "Error loading embedded devicetree, ignoring: %m"); log_error_status(err, "Error loading embedded devicetree, ignoring: %m");
} }

View File

@ -69,6 +69,7 @@ static inline void* xmemdup(const void *p, size_t l) {
} }
#define xnew(type, n) ((type *) xmalloc_multiply((n), sizeof(type))) #define xnew(type, n) ((type *) xmalloc_multiply((n), sizeof(type)))
#define xnew0(type, n) ((type *) xcalloc_multiply((n), sizeof(type)))
bool free_and_xstrdup16(char16_t **p, const char16_t *s); bool free_and_xstrdup16(char16_t **p, const char16_t *s);

View File

@ -103,6 +103,7 @@ static int help(int argc, char *argv[], void *userdata) {
" --sbat=PATH Path to SBAT file %7$s .sbat\n" " --sbat=PATH Path to SBAT file %7$s .sbat\n"
" --pcrpkey=PATH Path to public key for PCR signatures %7$s .pcrpkey\n" " --pcrpkey=PATH Path to public key for PCR signatures %7$s .pcrpkey\n"
" --profile=PATH Path to profile file %7$s .profile\n" " --profile=PATH Path to profile file %7$s .profile\n"
" --hwids=PATH Path to HWIDs file %7$s .hwids\n"
"\nSee the %2$s for details.\n", "\nSee the %2$s for details.\n",
program_invocation_short_name, program_invocation_short_name,
link, link,
@ -146,8 +147,10 @@ static int parse_argv(int argc, char *argv[]) {
ARG_SBAT, ARG_SBAT,
_ARG_PCRSIG, /* the .pcrsig section is not input for signing, hence not actually an argument here */ _ARG_PCRSIG, /* the .pcrsig section is not input for signing, hence not actually an argument here */
ARG_PCRPKEY, ARG_PCRPKEY,
ARG_PROFILE,
ARG_HWIDS,
_ARG_SECTION_LAST, _ARG_SECTION_LAST,
ARG_PROFILE = _ARG_SECTION_LAST, ARG_DTBAUTO = _ARG_SECTION_LAST,
ARG_BANK, ARG_BANK,
ARG_PRIVATE_KEY, ARG_PRIVATE_KEY,
ARG_PRIVATE_KEY_SOURCE, ARG_PRIVATE_KEY_SOURCE,
@ -170,10 +173,12 @@ static int parse_argv(int argc, char *argv[]) {
{ "ucode", required_argument, NULL, ARG_UCODE }, { "ucode", required_argument, NULL, ARG_UCODE },
{ "splash", required_argument, NULL, ARG_SPLASH }, { "splash", required_argument, NULL, ARG_SPLASH },
{ "dtb", required_argument, NULL, ARG_DTB }, { "dtb", required_argument, NULL, ARG_DTB },
{ "dtbauto", required_argument, NULL, ARG_DTBAUTO },
{ "uname", required_argument, NULL, ARG_UNAME }, { "uname", required_argument, NULL, ARG_UNAME },
{ "sbat", required_argument, NULL, ARG_SBAT }, { "sbat", required_argument, NULL, ARG_SBAT },
{ "pcrpkey", required_argument, NULL, ARG_PCRPKEY }, { "pcrpkey", required_argument, NULL, ARG_PCRPKEY },
{ "profile", required_argument, NULL, ARG_PROFILE }, { "profile", required_argument, NULL, ARG_PROFILE },
{ "hwids", required_argument, NULL, ARG_HWIDS },
{ "current", no_argument, NULL, 'c' }, { "current", no_argument, NULL, 'c' },
{ "bank", required_argument, NULL, ARG_BANK }, { "bank", required_argument, NULL, ARG_BANK },
{ "tpm2-device", required_argument, NULL, ARG_TPM2_DEVICE }, { "tpm2-device", required_argument, NULL, ARG_TPM2_DEVICE },

View File

@ -2165,10 +2165,8 @@ static int setup_private_users(PrivateUsers private_users, uid_t ouid, gid_t ogi
errno_pipe[0] = safe_close(errno_pipe[0]); errno_pipe[0] = safe_close(errno_pipe[0]);
/* Wait until the parent unshared the user namespace */ /* Wait until the parent unshared the user namespace */
if (read(unshare_ready_fd, &c, sizeof(c)) < 0) { if (read(unshare_ready_fd, &c, sizeof(c)) < 0)
r = -errno; report_errno_and_exit(errno_pipe[1], -errno);
goto child_fail;
}
/* Disable the setgroups() system call in the child user namespace, for good. */ /* Disable the setgroups() system call in the child user namespace, for good. */
a = procfs_file_alloca(ppid, "setgroups"); a = procfs_file_alloca(ppid, "setgroups");
@ -2176,14 +2174,14 @@ static int setup_private_users(PrivateUsers private_users, uid_t ouid, gid_t ogi
if (fd < 0) { if (fd < 0) {
if (errno != ENOENT) { if (errno != ENOENT) {
r = log_debug_errno(errno, "Failed to open %s: %m", a); r = log_debug_errno(errno, "Failed to open %s: %m", a);
goto child_fail; report_errno_and_exit(errno_pipe[1], r);
} }
/* If the file is missing the kernel is too old, let's continue anyway. */ /* If the file is missing the kernel is too old, let's continue anyway. */
} else { } else {
if (write(fd, "deny\n", 5) < 0) { if (write(fd, "deny\n", 5) < 0) {
r = log_debug_errno(errno, "Failed to write \"deny\" to %s: %m", a); r = log_debug_errno(errno, "Failed to write \"deny\" to %s: %m", a);
goto child_fail; report_errno_and_exit(errno_pipe[1], r);
} }
fd = safe_close(fd); fd = safe_close(fd);
@ -2194,12 +2192,14 @@ static int setup_private_users(PrivateUsers private_users, uid_t ouid, gid_t ogi
fd = open(a, O_WRONLY|O_CLOEXEC); fd = open(a, O_WRONLY|O_CLOEXEC);
if (fd < 0) { if (fd < 0) {
r = log_debug_errno(errno, "Failed to open %s: %m", a); r = log_debug_errno(errno, "Failed to open %s: %m", a);
goto child_fail; report_errno_and_exit(errno_pipe[1], r);
} }
if (write(fd, gid_map, strlen(gid_map)) < 0) { if (write(fd, gid_map, strlen(gid_map)) < 0) {
r = log_debug_errno(errno, "Failed to write GID map to %s: %m", a); r = log_debug_errno(errno, "Failed to write GID map to %s: %m", a);
goto child_fail; report_errno_and_exit(errno_pipe[1], r);
} }
fd = safe_close(fd); fd = safe_close(fd);
/* The write the UID map */ /* The write the UID map */
@ -2207,18 +2207,15 @@ static int setup_private_users(PrivateUsers private_users, uid_t ouid, gid_t ogi
fd = open(a, O_WRONLY|O_CLOEXEC); fd = open(a, O_WRONLY|O_CLOEXEC);
if (fd < 0) { if (fd < 0) {
r = log_debug_errno(errno, "Failed to open %s: %m", a); r = log_debug_errno(errno, "Failed to open %s: %m", a);
goto child_fail; report_errno_and_exit(errno_pipe[1], r);
} }
if (write(fd, uid_map, strlen(uid_map)) < 0) { if (write(fd, uid_map, strlen(uid_map)) < 0) {
r = log_debug_errno(errno, "Failed to write UID map to %s: %m", a); r = log_debug_errno(errno, "Failed to write UID map to %s: %m", a);
goto child_fail; report_errno_and_exit(errno_pipe[1], r);
} }
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
child_fail:
(void) write(errno_pipe[1], &r, sizeof(r));
_exit(EXIT_FAILURE);
} }
errno_pipe[1] = safe_close(errno_pipe[1]); errno_pipe[1] = safe_close(errno_pipe[1]);

View File

@ -3170,21 +3170,11 @@ int main(int argc, char *argv[]) {
} }
if (!skip_setup) { if (!skip_setup) {
/* Before we actually start deleting cgroup v1 code, make it harder to boot
* in cgroupv1 mode first. See also #30852. */
r = mount_cgroup_legacy_controllers(loaded_policy); r = mount_cgroup_legacy_controllers(loaded_policy);
if (r < 0) { if (r < 0) {
if (r == -ERFKILL) error_message = "Failed to mount cgroup v1 hierarchy";
error_message = "Refusing to run under cgroup v1, SYSTEMD_CGROUP_ENABLE_LEGACY_FORCE=1 not specified on kernel command line";
else
error_message = "Failed to mount cgroup v1 hierarchy";
goto finish; goto finish;
} }
if (r > 0) {
log_full(LOG_CRIT, "Legacy cgroup v1 support selected. This is no longer supported. Will proceed anyway after 30s.");
(void) usleep_safe(30 * USEC_PER_SEC);
}
} }
/* The efivarfs is now mounted, let's lock down the system token. */ /* The efivarfs is now mounted, let's lock down the system token. */

View File

@ -5067,7 +5067,7 @@ static int manager_dispatch_pidref_transport_fd(sd_event_source *source, int fd,
_cleanup_close_ int child_pidfd = -EBADF, parent_pidfd = -EBADF; _cleanup_close_ int child_pidfd = -EBADF, parent_pidfd = -EBADF;
struct ucred *ucred = NULL; struct ucred *ucred = NULL;
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred)) + CMSG_SPACE(sizeof(int)) * 2) control; CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred)) + CMSG_SPACE(sizeof(int)) * 2) control;
pid_t child_pid; pid_t child_pid = 0; /* silence false-positive warning by coverity */
struct msghdr msghdr = { struct msghdr msghdr = {
.msg_iov = &IOVEC_MAKE(&child_pid, sizeof(child_pid)), .msg_iov = &IOVEC_MAKE(&child_pid, sizeof(child_pid)),
.msg_iovlen = 1, .msg_iovlen = 1,

View File

@ -0,0 +1,120 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/*
* Based on Nikita Travkin's dtbloader implementation.
* Copyright (c) 2024 Nikita Travkin <nikita@trvn.ru>
*
* https://github.com/TravMurav/dtbloader/blob/main/src/chid.c
*/
/*
* Based on Linaro dtbloader implementation.
* Copyright (c) 2019, Linaro. All rights reserved.
*
* https://github.com/aarch64-laptops/edk2/blob/dtbloader-app/EmbeddedPkg/Application/ConfigTableLoader/CHID.c
*/
#if SD_BOOT
# include "efi-string.h"
# include "util.h"
#else
# include <byteswap.h>
# include <string.h>
# include <uchar.h>
# include <utf8.h>
#define strsize16(str) ((char16_strlen(str) + 1) * sizeof(char16_t))
#endif
#include "chid-fundamental.h"
#include "macro-fundamental.h"
#include "memory-util-fundamental.h"
#include "sha1-fundamental.h"
static void get_chid(const char16_t *const smbios_fields[static _CHID_SMBIOS_FIELDS_MAX], uint32_t mask, EFI_GUID *ret_chid) {
assert(mask != 0);
assert(ret_chid);
const EFI_GUID namespace = { UINT32_C(0x12d8ff70), UINT16_C(0x7f4c), UINT16_C(0x7d4c), {} }; /* Swapped to BE */
struct sha1_ctx ctx = {};
sha1_init_ctx(&ctx);
sha1_process_bytes(&namespace, sizeof(namespace), &ctx);
for (unsigned i = 0; i < _CHID_SMBIOS_FIELDS_MAX; i++)
if ((mask >> i) & 1) {
if (i > 0)
sha1_process_bytes(L"&", 2, &ctx);
sha1_process_bytes(smbios_fields[i], strsize16(smbios_fields[i]), &ctx);
}
uint8_t hash[SHA1_DIGEST_SIZE];
sha1_finish_ctx(&ctx, hash);
assert_cc(sizeof(hash) >= sizeof(*ret_chid));
memcpy(ret_chid, hash, sizeof(*ret_chid));
/* Convert the resulting CHID back to little-endian: */
ret_chid->Data1 = bswap_32(ret_chid->Data1);
ret_chid->Data2 = bswap_16(ret_chid->Data2);
ret_chid->Data3 = bswap_16(ret_chid->Data3);
/* set specific bits according to RFC4122 Section 4.1.3 */
ret_chid->Data3 = (ret_chid->Data3 & 0x0fff) | (5 << 12);
ret_chid->Data4[0] = (ret_chid->Data4[0] & UINT8_C(0x3f)) | UINT8_C(0x80);
}
static const uint32_t chid_smbios_table[CHID_TYPES_MAX] = {
[3] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_FAMILY) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_NAME) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_SKU) |
(UINT32_C(1) << CHID_SMBIOS_BASEBOARD_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_BASEBOARD_PRODUCT),
[4] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_FAMILY) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_NAME) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_SKU),
[5] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_FAMILY) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_NAME),
[6] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_SKU) |
(UINT32_C(1) << CHID_SMBIOS_BASEBOARD_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_BASEBOARD_PRODUCT),
[7] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_SKU),
[8] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_NAME) |
(UINT32_C(1) << CHID_SMBIOS_BASEBOARD_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_BASEBOARD_PRODUCT),
[9] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_NAME),
[10] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_FAMILY) |
(UINT32_C(1) << CHID_SMBIOS_BASEBOARD_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_BASEBOARD_PRODUCT),
[11] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_FAMILY),
[13] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_BASEBOARD_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_BASEBOARD_PRODUCT),
};
void chid_calculate(const char16_t *const smbios_fields[static _CHID_SMBIOS_FIELDS_MAX], EFI_GUID ret_chids[static CHID_TYPES_MAX]) {
assert(smbios_fields);
assert(ret_chids);
for (size_t i = 0; i < _CHID_SMBIOS_FIELDS_MAX; i++)
if (chid_smbios_table[i] != 0)
get_chid(smbios_fields, chid_smbios_table[i], &ret_chids[i]);
else
memzero(&ret_chids[i], sizeof(EFI_GUID));
}

View File

@ -0,0 +1,21 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#pragma once
#include "efi-fundamental.h"
#include "string-util-fundamental.h"
#define CHID_TYPES_MAX 15
typedef enum ChidSmbiosFields {
CHID_SMBIOS_MANUFACTURER,
CHID_SMBIOS_FAMILY,
CHID_SMBIOS_PRODUCT_NAME,
CHID_SMBIOS_PRODUCT_SKU,
CHID_SMBIOS_BASEBOARD_MANUFACTURER,
CHID_SMBIOS_BASEBOARD_PRODUCT,
_CHID_SMBIOS_FIELDS_MAX,
} ChidSmbiosFields;
/* CHID (also called HWID by fwupd) is described at https://github.com/fwupd/fwupd/blob/main/docs/hwids.md */
void chid_calculate(const char16_t *const smbios_fields[static _CHID_SMBIOS_FIELDS_MAX], EFI_GUID ret_chids[static CHID_TYPES_MAX]);

View File

@ -4,6 +4,7 @@ fundamental_include = include_directories('.')
fundamental_sources = files( fundamental_sources = files(
'bootspec-fundamental.c', 'bootspec-fundamental.c',
'chid-fundamental.c',
'efivars-fundamental.c', 'efivars-fundamental.c',
'iovec-util-fundamental.h', 'iovec-util-fundamental.h',
'sha1-fundamental.c', 'sha1-fundamental.c',

View File

@ -21,5 +21,7 @@ const char* const unified_sections[_UNIFIED_SECTION_MAX + 1] = {
[UNIFIED_SECTION_PCRSIG] = ".pcrsig", [UNIFIED_SECTION_PCRSIG] = ".pcrsig",
[UNIFIED_SECTION_PCRPKEY] = ".pcrpkey", [UNIFIED_SECTION_PCRPKEY] = ".pcrpkey",
[UNIFIED_SECTION_PROFILE] = ".profile", [UNIFIED_SECTION_PROFILE] = ".profile",
[UNIFIED_SECTION_DTBAUTO] = ".dtbauto",
[UNIFIED_SECTION_HWIDS] = ".hwids",
NULL, NULL,
}; };

View File

@ -18,6 +18,8 @@ typedef enum UnifiedSection {
UNIFIED_SECTION_PCRSIG, UNIFIED_SECTION_PCRSIG,
UNIFIED_SECTION_PCRPKEY, UNIFIED_SECTION_PCRPKEY,
UNIFIED_SECTION_PROFILE, UNIFIED_SECTION_PROFILE,
UNIFIED_SECTION_DTBAUTO,
UNIFIED_SECTION_HWIDS,
_UNIFIED_SECTION_MAX, _UNIFIED_SECTION_MAX,
} UnifiedSection; } UnifiedSection;

View File

@ -2,6 +2,7 @@
#include "alloc-util.h" #include "alloc-util.h"
#include "devnum-util.h" #include "devnum-util.h"
#include "env-util.h"
#include "fd-util.h" #include "fd-util.h"
#include "glyph-util.h" #include "glyph-util.h"
#include "in-addr-util.h" #include "in-addr-util.h"
@ -369,6 +370,40 @@ int json_dispatch_devnum(const char *name, sd_json_variant *variant, sd_json_dis
return 0; return 0;
} }
int json_dispatch_strv_environment(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
_cleanup_strv_free_ char **n = NULL;
char ***l = userdata;
int r;
if (sd_json_variant_is_null(variant)) {
*l = strv_free(*l);
return 0;
}
if (!sd_json_variant_is_array(variant))
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an array.", strna(name));
for (size_t i = 0; i < sd_json_variant_elements(variant); i++) {
sd_json_variant *e;
const char *a;
e = sd_json_variant_by_index(variant, i);
if (!sd_json_variant_is_string(e))
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an array of strings.", strna(name));
assert_se(a = sd_json_variant_string(e));
if (!env_assignment_is_valid(a))
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an array of environment variables.", strna(name));
r = strv_env_replace_strdup(&n, a);
if (r < 0)
return json_log_oom(variant, flags);
}
return strv_free_and_replace(*l, n);
}
static int json_variant_new_stat(sd_json_variant **ret, const struct stat *st) { static int json_variant_new_stat(sd_json_variant **ret, const struct stat *st) {
char mode[STRLEN("0755")+1]; char mode[STRLEN("0755")+1];

View File

@ -116,6 +116,7 @@ int json_dispatch_path(const char *name, sd_json_variant *variant, sd_json_dispa
int json_dispatch_pidref(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata); int json_dispatch_pidref(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
int json_dispatch_devnum(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata); int json_dispatch_devnum(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
int json_dispatch_ifindex(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata); int json_dispatch_ifindex(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
int json_dispatch_strv_environment(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
static inline int json_variant_unbase64_iovec(sd_json_variant *v, struct iovec *ret) { static inline int json_variant_unbase64_iovec(sd_json_variant *v, struct iovec *ret) {
return sd_json_variant_unbase64(v, ret ? &ret->iov_base : NULL, ret ? &ret->iov_len : NULL); return sd_json_variant_unbase64(v, ret ? &ret->iov_base : NULL, ret ? &ret->iov_len : NULL);

View File

@ -294,59 +294,11 @@ int bus_machine_method_open_pty(sd_bus_message *message, void *userdata, sd_bus_
return sd_bus_send(NULL, reply, NULL); return sd_bus_send(NULL, reply, NULL);
} }
static int container_bus_new(Machine *m, sd_bus_error *error, sd_bus **ret) {
int r;
assert(m);
assert(ret);
switch (m->class) {
case MACHINE_HOST:
*ret = NULL;
break;
case MACHINE_CONTAINER: {
_cleanup_(sd_bus_close_unrefp) sd_bus *bus = NULL;
char *address;
r = sd_bus_new(&bus);
if (r < 0)
return r;
if (asprintf(&address, "x-machine-unix:pid=%" PID_PRI, m->leader.pid) < 0)
return -ENOMEM;
bus->address = address;
bus->bus_client = true;
bus->trusted = false;
bus->runtime_scope = RUNTIME_SCOPE_SYSTEM;
r = sd_bus_start(bus);
if (r == -ENOENT)
return sd_bus_error_set_errnof(error, r, "There is no system bus in container %s.", m->name);
if (r < 0)
return r;
*ret = TAKE_PTR(bus);
break;
}
default:
return -EOPNOTSUPP;
}
return 0;
}
int bus_machine_method_open_login(sd_bus_message *message, void *userdata, sd_bus_error *error) { int bus_machine_method_open_login(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_free_ char *pty_name = NULL; _cleanup_free_ char *pty_name = NULL;
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *allocated_bus = NULL;
_cleanup_close_ int master = -EBADF; _cleanup_close_ int master = -EBADF;
sd_bus *container_bus = NULL;
Machine *m = ASSERT_PTR(userdata); Machine *m = ASSERT_PTR(userdata);
const char *p, *getty;
int r; int r;
assert(message); assert(message);
@ -372,18 +324,7 @@ int bus_machine_method_open_login(sd_bus_message *message, void *userdata, sd_bu
if (master < 0) if (master < 0)
return master; return master;
p = path_startswith(pty_name, "/dev/pts/"); r = machine_start_getty(m, pty_name, error);
assert(p);
r = container_bus_new(m, error, &allocated_bus);
if (r < 0)
return r;
container_bus = allocated_bus ?: m->manager->bus;
getty = strjoina("container-getty@", p, ".service");
r = bus_call_method(container_bus, bus_systemd_mgr, "StartUnit", error, NULL, "ss", getty, "replace");
if (r < 0) if (r < 0)
return r; return r;
@ -399,15 +340,13 @@ int bus_machine_method_open_login(sd_bus_message *message, void *userdata, sd_bu
} }
int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bus_error *error) { int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL, *tm = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_free_ char *pty_name = NULL; _cleanup_free_ char *pty_name = NULL;
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *allocated_bus = NULL; _cleanup_close_ int master = -EBADF;
sd_bus *container_bus = NULL;
_cleanup_close_ int master = -EBADF, slave = -EBADF;
_cleanup_strv_free_ char **env = NULL, **args_wire = NULL, **args = NULL; _cleanup_strv_free_ char **env = NULL, **args_wire = NULL, **args = NULL;
_cleanup_free_ char *command_line = NULL; _cleanup_free_ char *command_line = NULL;
Machine *m = ASSERT_PTR(userdata); Machine *m = ASSERT_PTR(userdata);
const char *unit, *user, *path, *description, *utmp_id; const char *user, *path;
int r; int r;
assert(message); assert(message);
@ -420,25 +359,10 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu
if (r < 0) if (r < 0)
return r; return r;
if (isempty(path)) { if (isempty(path)) {
path = "/bin/sh"; path = machine_default_shell_path();
args = machine_default_shell_args(user);
args = new0(char*, 3 + 1);
if (!args) if (!args)
return -ENOMEM; return -ENOMEM;
args[0] = strdup("sh");
if (!args[0])
return -ENOMEM;
args[1] = strdup("-c");
if (!args[1])
return -ENOMEM;
r = asprintf(&args[2],
"shell=$(getent passwd %s 2>/dev/null | { IFS=: read _ _ _ _ _ _ x; echo \"$x\"; })\n"\
"exec \"${shell:-/bin/sh}\" -l", /* -l is means --login */
user);
if (r < 0) {
args[2] = NULL;
return -ENOMEM;
}
} else { } else {
if (!path_is_absolute(path)) if (!path_is_absolute(path))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified path '%s' is not absolute", path); return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified path '%s' is not absolute", path);
@ -484,153 +408,10 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu
if (master < 0) if (master < 0)
return master; return master;
/* First try to get an fd for the PTY peer via the new racefree ioctl(), directly. Otherwise go via r = machine_start_shell(m, master, pty_name, user, path, args, env, error);
* joining the namespace, because it goes by path */
slave = pty_open_peer_racefree(master, O_RDWR|O_NOCTTY|O_CLOEXEC);
if (ERRNO_IS_NEG_NOT_SUPPORTED(slave))
slave = machine_open_terminal(m, pty_name, O_RDWR|O_NOCTTY|O_CLOEXEC);
if (slave < 0)
return slave;
utmp_id = path_startswith(pty_name, "/dev/");
assert(utmp_id);
r = container_bus_new(m, error, &allocated_bus);
if (r < 0) if (r < 0)
return r; return r;
container_bus = allocated_bus ?: m->manager->bus;
r = bus_message_new_method_call(container_bus, &tm, bus_systemd_mgr, "StartTransientUnit");
if (r < 0)
return r;
/* Name and mode */
const char *p = ASSERT_PTR(path_startswith(pty_name, "/dev/pts/"));
unit = strjoina("container-shell@", p, ".service");
r = sd_bus_message_append(tm, "ss", unit, "fail");
if (r < 0)
return r;
/* Properties */
r = sd_bus_message_open_container(tm, 'a', "(sv)");
if (r < 0)
return r;
description = strjoina("Shell for User ", user);
r = sd_bus_message_append(tm,
"(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)",
"Description", "s", description,
"StandardInputFileDescriptor", "h", slave,
"StandardOutputFileDescriptor", "h", slave,
"StandardErrorFileDescriptor", "h", slave,
"SendSIGHUP", "b", true,
"IgnoreSIGPIPE", "b", false,
"KillMode", "s", "mixed",
"TTYPath", "s", pty_name,
"TTYReset", "b", true,
"UtmpIdentifier", "s", utmp_id,
"UtmpMode", "s", "user",
"PAMName", "s", "login",
"WorkingDirectory", "s", "-~");
if (r < 0)
return r;
r = sd_bus_message_append(tm, "(sv)", "User", "s", user);
if (r < 0)
return r;
if (!strv_isempty(env)) {
r = sd_bus_message_open_container(tm, 'r', "sv");
if (r < 0)
return r;
r = sd_bus_message_append(tm, "s", "Environment");
if (r < 0)
return r;
r = sd_bus_message_open_container(tm, 'v', "as");
if (r < 0)
return r;
r = sd_bus_message_append_strv(tm, env);
if (r < 0)
return r;
r = sd_bus_message_close_container(tm);
if (r < 0)
return r;
r = sd_bus_message_close_container(tm);
if (r < 0)
return r;
}
/* Exec container */
r = sd_bus_message_open_container(tm, 'r', "sv");
if (r < 0)
return r;
r = sd_bus_message_append(tm, "s", "ExecStart");
if (r < 0)
return r;
r = sd_bus_message_open_container(tm, 'v', "a(sasb)");
if (r < 0)
return r;
r = sd_bus_message_open_container(tm, 'a', "(sasb)");
if (r < 0)
return r;
r = sd_bus_message_open_container(tm, 'r', "sasb");
if (r < 0)
return r;
r = sd_bus_message_append(tm, "s", path);
if (r < 0)
return r;
r = sd_bus_message_append_strv(tm, args);
if (r < 0)
return r;
r = sd_bus_message_append(tm, "b", true);
if (r < 0)
return r;
r = sd_bus_message_close_container(tm);
if (r < 0)
return r;
r = sd_bus_message_close_container(tm);
if (r < 0)
return r;
r = sd_bus_message_close_container(tm);
if (r < 0)
return r;
r = sd_bus_message_close_container(tm);
if (r < 0)
return r;
r = sd_bus_message_close_container(tm);
if (r < 0)
return r;
/* Auxiliary units */
r = sd_bus_message_append(tm, "a(sa(sv))", 0);
if (r < 0)
return r;
r = sd_bus_call(container_bus, tm, 0, error, NULL);
if (r < 0)
return r;
slave = safe_close(slave);
r = sd_bus_message_new_method_return(message, &reply); r = sd_bus_message_new_method_return(message, &reply);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -7,6 +7,7 @@
#include "sd-varlink.h" #include "sd-varlink.h"
#include "bus-polkit.h" #include "bus-polkit.h"
#include "fd-util.h"
#include "hostname-util.h" #include "hostname-util.h"
#include "json-util.h" #include "json-util.h"
#include "machine-varlink.h" #include "machine-varlink.h"
@ -16,7 +17,9 @@
#include "process-util.h" #include "process-util.h"
#include "signal-util.h" #include "signal-util.h"
#include "socket-util.h" #include "socket-util.h"
#include "string-table.h"
#include "string-util.h" #include "string-util.h"
#include "user-util.h"
#include "varlink-util.h" #include "varlink-util.h"
static JSON_DISPATCH_ENUM_DEFINE(dispatch_machine_class, MachineClass, machine_class_from_string); static JSON_DISPATCH_ENUM_DEFINE(dispatch_machine_class, MachineClass, machine_class_from_string);
@ -375,3 +378,195 @@ int vl_method_kill(sd_varlink *link, sd_json_variant *parameters, sd_varlink_met
return sd_varlink_reply(link, NULL); return sd_varlink_reply(link, NULL);
} }
typedef enum MachineOpenMode {
MACHINE_OPEN_MODE_TTY,
MACHINE_OPEN_MODE_LOGIN,
MACHINE_OPEN_MODE_SHELL,
_MACHINE_OPEN_MODE_MAX,
_MACHINE_OPEN_MODE_INVALID = -EINVAL,
} MachineOpenMode;
static const char* const machine_open_mode_table[_MACHINE_OPEN_MODE_MAX] = {
[MACHINE_OPEN_MODE_TTY] = "tty",
[MACHINE_OPEN_MODE_LOGIN] = "login",
[MACHINE_OPEN_MODE_SHELL] = "shell",
};
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(machine_open_mode, MachineOpenMode);
static JSON_DISPATCH_ENUM_DEFINE(json_dispatch_machine_open_mode, MachineOpenMode, machine_open_mode_from_string);
typedef struct MachineOpenParameters {
const char *name, *user;
PidRef pidref;
MachineOpenMode mode;
char *path, **args, **env;
} MachineOpenParameters;
static void machine_open_paramaters_done(MachineOpenParameters *p) {
assert(p);
pidref_done(&p->pidref);
free(p->path);
strv_free(p->args);
strv_free(p->env);
}
inline static const char* machine_open_polkit_action(MachineOpenMode mode, MachineClass class) {
switch (mode) {
case MACHINE_OPEN_MODE_TTY:
return class == MACHINE_HOST ? "org.freedesktop.machine1.host-open-pty" : "org.freedesktop.machine1.open-pty";
case MACHINE_OPEN_MODE_LOGIN:
return class == MACHINE_HOST ? "org.freedesktop.machine1.host-login" : "org.freedesktop.machine1.login";
case MACHINE_OPEN_MODE_SHELL:
return class == MACHINE_HOST ? "org.freedesktop.machine1.host-shell" : "org.freedesktop.machine1.shell";
default:
assert_not_reached();
}
}
inline static char** machine_open_polkit_details(MachineOpenMode mode, const char *machine_name, const char *user, const char *path, const char *command_line) {
assert(machine_name);
switch (mode) {
case MACHINE_OPEN_MODE_TTY:
return strv_new("machine", machine_name);
case MACHINE_OPEN_MODE_LOGIN:
return strv_new("machine", machine_name, "verb", "login");
case MACHINE_OPEN_MODE_SHELL:
assert(user);
assert(path);
assert(command_line);
return strv_new(
"machine", machine_name,
"verb", "shell",
"user", user,
"program", path,
"command_line", command_line);
default:
assert_not_reached();
}
}
int vl_method_open(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
static const sd_json_dispatch_field dispatch_table[] = {
VARLINK_DISPATCH_MACHINE_LOOKUP_FIELDS(MachineOpenParameters),
{ "mode", SD_JSON_VARIANT_STRING, json_dispatch_machine_open_mode, offsetof(MachineOpenParameters, mode), SD_JSON_MANDATORY },
{ "user", SD_JSON_VARIANT_STRING, json_dispatch_const_user_group_name, offsetof(MachineOpenParameters, user), SD_JSON_RELAX },
{ "path", SD_JSON_VARIANT_STRING, json_dispatch_path, offsetof(MachineOpenParameters, path), 0 },
{ "args", SD_JSON_VARIANT_ARRAY, sd_json_dispatch_strv, offsetof(MachineOpenParameters, args), 0 },
{ "environment", SD_JSON_VARIANT_ARRAY, json_dispatch_strv_environment, offsetof(MachineOpenParameters, env), 0 },
VARLINK_DISPATCH_POLKIT_FIELD,
{}
};
Manager *manager = ASSERT_PTR(userdata);
_cleanup_close_ int ptmx_fd = -EBADF;
_cleanup_(machine_open_paramaters_done) MachineOpenParameters p = {
.pidref = PIDREF_NULL,
.mode = _MACHINE_OPEN_MODE_INVALID,
};
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
_cleanup_free_ char *ptmx_name = NULL, *command_line = NULL;
_cleanup_strv_free_ char **polkit_details = NULL, **args = NULL;
const char *user = NULL, *path = NULL; /* gcc complains about uninitialized variables */
Machine *machine;
int r, ptmx_fd_idx;
assert(link);
assert(parameters);
r = sd_varlink_set_allow_fd_passing_output(link, true);
if (r < 0)
return log_error_errno(r, "Failed to enable varlink fd passing for write: %m");
r = sd_varlink_dispatch(link, parameters, dispatch_table, &p);
if (r != 0)
return r;
if (p.mode == MACHINE_OPEN_MODE_SHELL) {
/* json_dispatch_const_user_group_name() does valid_user_group_name(p.user) */
/* json_dispatch_path() does path_is_absolute(p.path) */
/* json_dispatch_strv_environment() does validation of p.env */
user = p.user ?: "root";
path = p.path ?: machine_default_shell_path();
args = !p.path ? machine_default_shell_args(user) : strv_isempty(p.args) ? strv_new(path) : TAKE_PTR(p.args);
if (!args)
return -ENOMEM;
command_line = strv_join(args, " ");
if (!command_line)
return -ENOMEM;
}
r = lookup_machine_by_name_or_pidref(link, manager, p.name, &p.pidref, &machine);
if (r == -ESRCH)
return sd_varlink_error(link, "io.systemd.Machine.NoSuchMachine", NULL);
if (r < 0)
return r;
polkit_details = machine_open_polkit_details(p.mode, machine->name, user, path, command_line);
r = varlink_verify_polkit_async(
link,
manager->bus,
machine_open_polkit_action(p.mode, machine->class),
(const char**) polkit_details,
&manager->polkit_registry);
if (r <= 0)
return r;
ptmx_fd = machine_openpt(machine, O_RDWR|O_NOCTTY|O_CLOEXEC, &ptmx_name);
if (ERRNO_IS_NEG_NOT_SUPPORTED(ptmx_fd))
return sd_varlink_error(link, "io.systemd.Machine.NotSupported", NULL);
if (ptmx_fd < 0)
return log_debug_errno(ptmx_fd, "Failed to open pseudo terminal: %m");
switch (p.mode) {
case MACHINE_OPEN_MODE_TTY:
/* noop */
break;
case MACHINE_OPEN_MODE_LOGIN:
r = machine_start_getty(machine, ptmx_name, /* error = */ NULL);
if (r == -ENOENT)
return sd_varlink_error(link, "io.systemd.Machine.NoIPC", NULL);
if (ERRNO_IS_NEG_NOT_SUPPORTED(r))
return sd_varlink_error(link, "io.systemd.Machine.NotSupported", NULL);
if (r < 0)
return log_debug_errno(r, "Failed to start getty for machine '%s': %m", machine->name);
break;
case MACHINE_OPEN_MODE_SHELL: {
assert(user && path && args); /* to avoid gcc complaining about possible uninitialized variables */
r = machine_start_shell(machine, ptmx_fd, ptmx_name, user, path, args, p.env, /* error = */ NULL);
if (r == -ENOENT)
return sd_varlink_error(link, "io.systemd.Machine.NoIPC", NULL);
if (ERRNO_IS_NEG_NOT_SUPPORTED(r))
return sd_varlink_error(link, "io.systemd.Machine.NotSupported", NULL);
if (r < 0)
return log_debug_errno(r, "Failed to start shell for machine '%s': %m", machine->name);
break;
}
default:
assert_not_reached();
}
ptmx_fd_idx = sd_varlink_push_fd(link, ptmx_fd);
/* no need to handle -EPERM because we do sd_varlink_set_allow_fd_passing_output() above */
if (ptmx_fd_idx < 0)
return log_debug_errno(ptmx_fd_idx, "Failed to push file descriptor over varlink: %m");
TAKE_FD(ptmx_fd);
r = sd_json_buildo(
&v,
SD_JSON_BUILD_PAIR_INTEGER("ptyFileDescriptor", ptmx_fd_idx),
JSON_BUILD_PAIR_STRING_NON_EMPTY("ptyPath", ptmx_name));
if (r < 0)
return r;
return sd_varlink_reply(link, v);
}

View File

@ -24,3 +24,4 @@ int vl_method_register(sd_varlink *link, sd_json_variant *parameters, sd_varlink
int vl_method_unregister_internal(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata); int vl_method_unregister_internal(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
int vl_method_terminate_internal(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata); int vl_method_terminate_internal(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
int vl_method_kill(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata); int vl_method_kill(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
int vl_method_open(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);

View File

@ -8,6 +8,7 @@
#include "alloc-util.h" #include "alloc-util.h"
#include "bus-error.h" #include "bus-error.h"
#include "bus-internal.h"
#include "bus-locator.h" #include "bus-locator.h"
#include "bus-unit-util.h" #include "bus-unit-util.h"
#include "bus-util.h" #include "bus-util.h"
@ -702,6 +703,276 @@ int machine_open_terminal(Machine *m, const char *path, int mode) {
} }
} }
static int machine_bus_new(Machine *m, sd_bus_error *error, sd_bus **ret) {
int r;
assert(m);
assert(ret);
switch (m->class) {
case MACHINE_HOST:
*ret = NULL;
return 0;
case MACHINE_CONTAINER: {
_cleanup_(sd_bus_close_unrefp) sd_bus *bus = NULL;
char *address;
r = sd_bus_new(&bus);
if (r < 0)
return log_debug_errno(r, "Failed to allocate new DBus: %m");
if (asprintf(&address, "x-machine-unix:pid=%" PID_PRI, m->leader.pid) < 0)
return -ENOMEM;
bus->address = address;
bus->bus_client = true;
bus->trusted = false;
bus->runtime_scope = RUNTIME_SCOPE_SYSTEM;
r = sd_bus_start(bus);
if (r == -ENOENT)
return sd_bus_error_set_errnof(error, r, "There is no system bus in container %s.", m->name);
if (r < 0)
return r;
*ret = TAKE_PTR(bus);
return 0;
}
default:
return -EOPNOTSUPP;
}
}
int machine_start_getty(Machine *m, const char *ptmx_name, sd_bus_error *error) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *allocated_bus = NULL;
sd_bus *container_bus = NULL;
const char *p, *getty;
int r;
assert(m);
assert(ptmx_name);
p = path_startswith(ptmx_name, "/dev/pts/");
if (!p)
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Path of pseudo TTY has unexpected prefix");
r = machine_bus_new(m, error, &allocated_bus);
if (r < 0)
return log_debug_errno(r, "Failed to create DBus to machine: %m");
container_bus = allocated_bus ?: m->manager->bus;
getty = strjoina("container-getty@", p, ".service");
r = bus_call_method(container_bus, bus_systemd_mgr, "StartUnit", error, /* reply = */ NULL, "ss", getty, "replace");
if (r < 0)
return log_debug_errno(r, "Failed to StartUnit '%s' in container '%s': %m", getty, m->name);
return 0;
}
int machine_start_shell(
Machine *m,
int ptmx_fd,
const char *ptmx_name,
const char *user,
const char *path,
char **args,
char **env,
sd_bus_error *error) {
_cleanup_close_ int pty_fd = -EBADF;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *tm = NULL;
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *allocated_bus = NULL;
const char *p, *utmp_id, *unit, *description;
sd_bus *container_bus = NULL;
int r;
assert(m);
assert(ptmx_fd >= 0);
assert(ptmx_name);
if (isempty(user) || isempty(path) || strv_isempty(args))
return -EINVAL;
p = path_startswith(ptmx_name, "/dev/pts/");
utmp_id = path_startswith(ptmx_name, "/dev/");
if (!p || !utmp_id)
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Path of pseudo TTY has unexpected prefix");
/* First try to get an fd for the PTY peer via the new racefree ioctl(), directly. Otherwise go via
* joining the namespace, because it goes by path */
pty_fd = pty_open_peer_racefree(ptmx_fd, O_RDWR|O_NOCTTY|O_CLOEXEC);
if (ERRNO_IS_NEG_NOT_SUPPORTED(pty_fd))
pty_fd = machine_open_terminal(m, ptmx_name, O_RDWR|O_NOCTTY|O_CLOEXEC);
if (pty_fd < 0)
return log_debug_errno(pty_fd, "Failed to open terminal: %m");
r = machine_bus_new(m, error, &allocated_bus);
if (r < 0)
return log_debug_errno(r, "Failed to create DBus to machine: %m");
container_bus = allocated_bus ?: m->manager->bus;
r = bus_message_new_method_call(container_bus, &tm, bus_systemd_mgr, "StartTransientUnit");
if (r < 0)
return r;
/* Name and mode */
unit = strjoina("container-shell@", p, ".service");
r = sd_bus_message_append(tm, "ss", unit, "fail");
if (r < 0)
return r;
/* Properties */
r = sd_bus_message_open_container(tm, 'a', "(sv)");
if (r < 0)
return r;
description = strjoina("Shell for User ", user);
r = sd_bus_message_append(tm,
"(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)",
"Description", "s", description,
"StandardInputFileDescriptor", "h", pty_fd,
"StandardOutputFileDescriptor", "h", pty_fd,
"StandardErrorFileDescriptor", "h", pty_fd,
"SendSIGHUP", "b", true,
"IgnoreSIGPIPE", "b", false,
"KillMode", "s", "mixed",
"TTYPath", "s", ptmx_name,
"TTYReset", "b", true,
"UtmpIdentifier", "s", utmp_id,
"UtmpMode", "s", "user",
"PAMName", "s", "login",
"WorkingDirectory", "s", "-~");
if (r < 0)
return r;
r = sd_bus_message_append(tm, "(sv)", "User", "s", user);
if (r < 0)
return r;
if (!strv_isempty(env)) {
r = sd_bus_message_open_container(tm, 'r', "sv");
if (r < 0)
return r;
r = sd_bus_message_append(tm, "s", "Environment");
if (r < 0)
return r;
r = sd_bus_message_open_container(tm, 'v', "as");
if (r < 0)
return r;
r = sd_bus_message_append_strv(tm, env);
if (r < 0)
return r;
r = sd_bus_message_close_container(tm);
if (r < 0)
return r;
r = sd_bus_message_close_container(tm);
if (r < 0)
return r;
}
/* Exec container */
r = sd_bus_message_open_container(tm, 'r', "sv");
if (r < 0)
return r;
r = sd_bus_message_append(tm, "s", "ExecStart");
if (r < 0)
return r;
r = sd_bus_message_open_container(tm, 'v', "a(sasb)");
if (r < 0)
return r;
r = sd_bus_message_open_container(tm, 'a', "(sasb)");
if (r < 0)
return r;
r = sd_bus_message_open_container(tm, 'r', "sasb");
if (r < 0)
return r;
r = sd_bus_message_append(tm, "s", path);
if (r < 0)
return r;
r = sd_bus_message_append_strv(tm, args);
if (r < 0)
return r;
r = sd_bus_message_append(tm, "b", true);
if (r < 0)
return r;
r = sd_bus_message_close_container(tm);
if (r < 0)
return r;
r = sd_bus_message_close_container(tm);
if (r < 0)
return r;
r = sd_bus_message_close_container(tm);
if (r < 0)
return r;
r = sd_bus_message_close_container(tm);
if (r < 0)
return r;
r = sd_bus_message_close_container(tm);
if (r < 0)
return r;
/* Auxiliary units */
r = sd_bus_message_append(tm, "a(sa(sv))", 0);
if (r < 0)
return r;
r = sd_bus_call(container_bus, tm, 0, error, NULL);
if (r < 0)
return r;
return 0;
}
char** machine_default_shell_args(const char *user) {
_cleanup_strv_free_ char **args = NULL;
int r;
assert(user);
args = new0(char*, 3 + 1);
if (!args)
return NULL;
args[0] = strdup("sh");
if (!args[0])
return NULL;
args[1] = strdup("-c");
if (!args[1])
return NULL;
r = asprintf(&args[2],
"shell=$(getent passwd %s 2>/dev/null | { IFS=: read _ _ _ _ _ _ x; echo \"$x\"; })\n"\
"exec \"${shell:-/bin/sh}\" -l", /* -l is means --login */
user);
if (r < 0) {
args[2] = NULL;
return NULL;
}
return TAKE_PTR(args);
}
void machine_release_unit(Machine *m) { void machine_release_unit(Machine *m) {
assert(m); assert(m);

View File

@ -102,6 +102,10 @@ KillWhom kill_whom_from_string(const char *s) _pure_;
int machine_openpt(Machine *m, int flags, char **ret_slave); int machine_openpt(Machine *m, int flags, char **ret_slave);
int machine_open_terminal(Machine *m, const char *path, int mode); int machine_open_terminal(Machine *m, const char *path, int mode);
int machine_start_getty(Machine *m, const char *ptmx_name, sd_bus_error *error);
int machine_start_shell(Machine *m, int ptmx_fd, const char *ptmx_name, const char *user, const char *path, char **args, char **env, sd_bus_error *error);
#define machine_default_shell_path() ("/bin/sh")
char** machine_default_shell_args(const char *user);
int machine_get_uid_shift(Machine *m, uid_t *ret); int machine_get_uid_shift(Machine *m, uid_t *ret);

View File

@ -773,6 +773,7 @@ static int manager_varlink_init_machine(Manager *m) {
"io.systemd.Machine.Unregister", vl_method_unregister, "io.systemd.Machine.Unregister", vl_method_unregister,
"io.systemd.Machine.Terminate", vl_method_terminate, "io.systemd.Machine.Terminate", vl_method_terminate,
"io.systemd.Machine.Kill", vl_method_kill, "io.systemd.Machine.Kill", vl_method_kill,
"io.systemd.Machine.Open", vl_method_open,
"io.systemd.MachineImage.List", vl_method_list_images, "io.systemd.MachineImage.List", vl_method_list_images,
"io.systemd.MachineImage.Update", vl_method_update_image, "io.systemd.MachineImage.Update", vl_method_update_image,
"io.systemd.MachineImage.Clone", vl_method_clone_image, "io.systemd.MachineImage.Clone", vl_method_clone_image,

View File

@ -154,18 +154,3 @@ Operation *operation_free(Operation *o) {
return mfree(o); return mfree(o);
} }
_noreturn_ void report_errno_and_exit(int errno_fd, int r) {
if (r >= 0)
_exit(EXIT_SUCCESS);
assert(errno_fd >= 0);
ssize_t n = write(errno_fd, &r, sizeof(r));
if (n < 0)
log_debug_errno(errno, "Failed to write operation's errno: %m");
if (n != sizeof(r))
log_debug_errno(SYNTHETIC_ERRNO(EIO), "Sent unexpectedly short message");
_exit(EXIT_FAILURE);
}

View File

@ -39,5 +39,3 @@ static inline int operation_new_with_bus_reply(Manager *manager, Machine *machin
static inline int operation_new_with_varlink_reply(Manager *manager, Machine *machine, pid_t child, sd_varlink *link, int errno_fd, Operation **ret) { static inline int operation_new_with_varlink_reply(Manager *manager, Machine *machine, pid_t child, sd_varlink *link, int errno_fd, Operation **ret) {
return operation_new(manager, machine, child, /* message = */ NULL, link, errno_fd, ret); return operation_new(manager, machine, child, /* message = */ NULL, link, errno_fd, ret);
} }
void report_errno_and_exit(int errno_fd, int r);

View File

@ -1384,7 +1384,7 @@ int link_drop_ipv6ll_addresses(Link *link) {
return 0; return 0;
} }
int link_drop_foreign_addresses(Link *link) { int link_drop_unmanaged_addresses(Link *link) {
Address *address; Address *address;
int r = 0; int r = 0;
@ -1401,18 +1401,22 @@ int link_drop_foreign_addresses(Link *link) {
if (link->flags & IFF_LOOPBACK && in_addr_is_localhost_one(address->family, &address->in_addr) > 0) if (link->flags & IFF_LOOPBACK && in_addr_is_localhost_one(address->family, &address->in_addr) > 0)
continue; continue;
/* Ignore addresses we configured. */
if (address->source != NETWORK_CONFIG_SOURCE_FOREIGN)
continue;
/* Ignore addresses not assigned yet or already removing. */ /* Ignore addresses not assigned yet or already removing. */
if (!address_exists(address)) if (!address_exists(address))
continue; continue;
/* link_address_is_dynamic() is slightly heavy. Let's call the function only when KeepConfiguration= is set. */ if (address->source == NETWORK_CONFIG_SOURCE_FOREIGN) {
if (IN_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP, KEEP_CONFIGURATION_STATIC) && if (link->network->keep_configuration == KEEP_CONFIGURATION_YES)
link_address_is_dynamic(link, address) == (link->network->keep_configuration == KEEP_CONFIGURATION_DHCP)) continue;
continue;
/* link_address_is_dynamic() is slightly heavy. Let's call the function only when
* KeepConfiguration=dhcp or static. */
if (IN_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP, KEEP_CONFIGURATION_STATIC) &&
link_address_is_dynamic(link, address) == (link->network->keep_configuration == KEEP_CONFIGURATION_DHCP))
continue;
} else if (address->source != NETWORK_CONFIG_SOURCE_STATIC)
continue; /* Ignore dynamically configurad addresses. */
address_mark(address); address_mark(address);
} }
@ -1464,15 +1468,6 @@ int link_drop_static_addresses(Link *link) {
return r; return r;
} }
void link_foreignize_addresses(Link *link) {
Address *address;
assert(link);
SET_FOREACH(address, link->addresses)
address->source = NETWORK_CONFIG_SOURCE_FOREIGN;
}
int address_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg) { int address_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg) {
int r; int r;

View File

@ -113,9 +113,8 @@ bool link_check_addresses_ready(Link *link, NetworkConfigSource source);
DEFINE_SECTION_CLEANUP_FUNCTIONS(Address, address_unref); DEFINE_SECTION_CLEANUP_FUNCTIONS(Address, address_unref);
int link_drop_static_addresses(Link *link); int link_drop_static_addresses(Link *link);
int link_drop_foreign_addresses(Link *link); int link_drop_unmanaged_addresses(Link *link);
int link_drop_ipv6ll_addresses(Link *link); int link_drop_ipv6ll_addresses(Link *link);
void link_foreignize_addresses(Link *link);
bool link_address_is_dynamic(const Link *link, const Address *address); bool link_address_is_dynamic(const Link *link, const Address *address);
int link_get_address_full( int link_get_address_full(

View File

@ -1252,6 +1252,28 @@ int dhcp_request_prefix_delegation(Link *link) {
dhcp6_pd_assign_subnet_prefixes(link, uplink); dhcp6_pd_assign_subnet_prefixes(link, uplink);
} }
int link_drop_dhcp_pd_config(Link *link, Network *network) {
assert(link);
assert(network);
if (!link_dhcp_pd_is_enabled(link))
return 0;
/* If will be disabled or at least one config is changed, then drop all configurations. */
if (!network->dhcp_pd ||
link->network->dhcp_pd_assign != network->dhcp_pd_assign ||
(link->network->dhcp_pd_assign &&
(link->network->dhcp_pd_manage_temporary_address != network->dhcp_pd_manage_temporary_address ||
!set_equal(link->network->dhcp_pd_tokens, network->dhcp_pd_tokens))) ||
link->network->dhcp_pd_subnet_id != network->dhcp_pd_subnet_id ||
link->network->dhcp_pd_route_metric != network->dhcp_pd_route_metric ||
link->network->dhcp_pd_uplink_index != network->dhcp_pd_uplink_index ||
!streq_ptr(link->network->dhcp_pd_uplink_name, network->dhcp_pd_uplink_name))
return dhcp_pd_remove(link, /* only_marked = */ false);
return 0;
}
int config_parse_dhcp_pd_subnet_id( int config_parse_dhcp_pd_subnet_id(
const char *unit, const char *unit,
const char *filename, const char *filename,

View File

@ -10,12 +10,14 @@
typedef struct Address Address; typedef struct Address Address;
typedef struct Link Link; typedef struct Link Link;
typedef struct Network Network;
bool link_dhcp_pd_is_enabled(Link *link); bool link_dhcp_pd_is_enabled(Link *link);
bool dhcp_pd_is_uplink(Link *link, Link *target, bool accept_auto); bool dhcp_pd_is_uplink(Link *link, Link *target, bool accept_auto);
int dhcp_pd_find_uplink(Link *link, Link **ret); int dhcp_pd_find_uplink(Link *link, Link **ret);
int dhcp_pd_remove(Link *link, bool only_marked); int dhcp_pd_remove(Link *link, bool only_marked);
int dhcp_request_prefix_delegation(Link *link); int dhcp_request_prefix_delegation(Link *link);
int link_drop_dhcp_pd_config(Link *link, Network *network);
int dhcp4_pd_prefix_acquired(Link *uplink); int dhcp4_pd_prefix_acquired(Link *uplink);
int dhcp6_pd_prefix_acquired(Link *uplink); int dhcp6_pd_prefix_acquired(Link *uplink);
void dhcp_pd_prefix_lost(Link *uplink); void dhcp_pd_prefix_lost(Link *uplink);

View File

@ -1375,49 +1375,49 @@ static int dhcp4_set_client_identifier(Link *link) {
return 0; return 0;
} }
static int dhcp4_find_dynamic_address(Link *link, struct in_addr *ret) { static int dhcp4_set_request_address(Link *link) {
Address *a;
assert(link); assert(link);
assert(link->network); assert(link->network);
assert(ret); assert(link->dhcp_client);
/* 1. Use already assigned address. */
Address *a;
SET_FOREACH(a, link->addresses) {
if (a->source != NETWORK_CONFIG_SOURCE_DHCP4)
continue;
assert(a->family == AF_INET);
log_link_debug(link, "DHCPv4 CLIENT: requesting previously acquired address %s.",
IN4_ADDR_TO_STRING(&a->in_addr.in));
return sd_dhcp_client_set_request_address(link->dhcp_client, &a->in_addr.in);
}
/* 2. If no address is assigned yet, use explicitly configured address. */
if (in4_addr_is_set(&link->network->dhcp_request_address)) {
log_link_debug(link, "DHCPv4 CLIENT: requesting address %s specified by RequestAddress=.",
IN4_ADDR_TO_STRING(&link->network->dhcp_request_address));
return sd_dhcp_client_set_request_address(link->dhcp_client, &link->network->dhcp_request_address);
}
/* 3. If KeepConfiguration=dhcp, use a foreign dynamic address. */
if (!FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP)) if (!FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP))
return false; return 0;
SET_FOREACH(a, link->addresses) { SET_FOREACH(a, link->addresses) {
if (a->source != NETWORK_CONFIG_SOURCE_FOREIGN) if (a->source != NETWORK_CONFIG_SOURCE_FOREIGN)
continue; continue;
if (a->family != AF_INET) if (a->family != AF_INET)
continue; continue;
if (link_address_is_dynamic(link, a)) if (!link_address_is_dynamic(link, a))
break; continue;
log_link_debug(link, "DHCPv4 CLIENT: requesting foreign dynamic address %s.",
IN4_ADDR_TO_STRING(&a->in_addr.in));
return sd_dhcp_client_set_request_address(link->dhcp_client, &a->in_addr.in);
} }
if (!a) return 0;
return false;
*ret = a->in_addr.in;
return true;
}
static int dhcp4_set_request_address(Link *link) {
struct in_addr a;
assert(link);
assert(link->network);
assert(link->dhcp_client);
a = link->network->dhcp_request_address;
if (in4_addr_is_null(&a))
(void) dhcp4_find_dynamic_address(link, &a);
if (in4_addr_is_null(&a))
return 0;
log_link_debug(link, "DHCPv4 CLIENT: requesting %s.", IN4_ADDR_TO_STRING(&a));
return sd_dhcp_client_set_request_address(link->dhcp_client, &a);
} }
static bool link_needs_dhcp_broadcast(Link *link) { static bool link_needs_dhcp_broadcast(Link *link) {
@ -1833,6 +1833,26 @@ int link_request_dhcp4_client(Link *link) {
return 0; return 0;
} }
int link_drop_dhcp4_config(Link *link, Network *network) {
int ret = 0;
assert(link);
assert(network);
if (!link_dhcp4_enabled(link))
return 0; /* Currently DHCPv4 client is not enabled, there is nothing we need to drop. */
if (!FLAGS_SET(network->dhcp, ADDRESS_FAMILY_IPV4))
/* Currently enabled but will be disabled. Stop the client and drop the lease. */
ret = sd_dhcp_client_stop(link->dhcp_client);
/* Even if the client is currently enabled and also enabled in the new .network file, detailed
* settings for the client may be different. Let's unref() the client. But do not unref() the lease.
* it will be unref()ed later when a new lease is acquired. */
link->dhcp_client = sd_dhcp_client_unref(link->dhcp_client);
return ret;
}
int config_parse_dhcp_max_attempts( int config_parse_dhcp_max_attempts(
const char *unit, const char *unit,
const char *filename, const char *filename,

View File

@ -25,6 +25,7 @@ int dhcp4_lease_lost(Link *link);
int dhcp4_check_ready(Link *link); int dhcp4_check_ready(Link *link);
int link_request_dhcp4_client(Link *link); int link_request_dhcp4_client(Link *link);
int link_drop_dhcp4_config(Link *link, Network *network);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_client_identifier); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_client_identifier);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_max_attempts); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_max_attempts);

View File

@ -841,6 +841,26 @@ int link_request_dhcp6_client(Link *link) {
return 0; return 0;
} }
int link_drop_dhcp6_config(Link *link, Network *network) {
int ret = 0;
assert(link);
assert(network);
if (!link_dhcp6_enabled(link))
return 0; /* Currently DHCPv6 client is not enabled, there is nothing we need to drop. */
if (!FLAGS_SET(network->dhcp, ADDRESS_FAMILY_IPV6))
/* Currently enabled but will be disabled. Stop the client and drop the lease. */
ret = sd_dhcp6_client_stop(link->dhcp6_client);
/* Even if the client is currently enabled and also enabled in the new .network file, detailed
* settings for the client may be different. Let's unref() the client. But do not unref() the lease.
* it will be unref()ed later when a new lease is acquired. */
link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
return ret;
}
int link_serialize_dhcp6_client(Link *link, FILE *f) { int link_serialize_dhcp6_client(Link *link, FILE *f) {
_cleanup_free_ char *duid = NULL; _cleanup_free_ char *duid = NULL;
uint32_t iaid; uint32_t iaid;

View File

@ -13,6 +13,7 @@ typedef enum DHCP6ClientStartMode {
} DHCP6ClientStartMode; } DHCP6ClientStartMode;
typedef struct Link Link; typedef struct Link Link;
typedef struct Network Network;
bool link_dhcp6_with_address_enabled(Link *link); bool link_dhcp6_with_address_enabled(Link *link);
int dhcp6_check_ready(Link *link); int dhcp6_check_ready(Link *link);
@ -21,6 +22,7 @@ int dhcp6_start(Link *link);
int dhcp6_start_on_ra(Link *link, bool information_request); int dhcp6_start_on_ra(Link *link, bool information_request);
int link_request_dhcp6_client(Link *link); int link_request_dhcp6_client(Link *link);
int link_drop_dhcp6_config(Link *link, Network *network);
int link_serialize_dhcp6_client(Link *link, FILE *f); int link_serialize_dhcp6_client(Link *link, FILE *f);

View File

@ -179,10 +179,21 @@ static int ipv4ll_set_address(Link *link) {
assert(link->network); assert(link->network);
assert(link->ipv4ll); assert(link->ipv4ll);
if (!in4_addr_is_set(&link->network->ipv4ll_start_address)) /* 1. Use already assigned address. */
return 0; Address *a;
SET_FOREACH(a, link->addresses) {
if (a->source != NETWORK_CONFIG_SOURCE_IPV4LL)
continue;
return sd_ipv4ll_set_address(link->ipv4ll, &link->network->ipv4ll_start_address); assert(a->family == AF_INET);
return sd_ipv4ll_set_address(link->ipv4ll, &a->in_addr.in);
}
/* 2. If no address is assigned yet, use explicitly configured address. */
if (in4_addr_is_set(&link->network->ipv4ll_start_address))
return sd_ipv4ll_set_address(link->ipv4ll, &link->network->ipv4ll_start_address);
return 0;
} }
int ipv4ll_configure(Link *link) { int ipv4ll_configure(Link *link) {
@ -231,6 +242,27 @@ int ipv4ll_configure(Link *link) {
return sd_ipv4ll_set_check_mac_callback(link->ipv4ll, ipv4ll_check_mac, link->manager); return sd_ipv4ll_set_check_mac_callback(link->ipv4ll, ipv4ll_check_mac, link->manager);
} }
int link_drop_ipv4ll_config(Link *link, Network *network) {
int ret = 0;
assert(link);
assert(network);
if (!link_ipv4ll_enabled(link))
return 0;
Network *saved = link->network;
link->network = network;
bool enabled = link_ipv4ll_enabled(link);
link->network = saved;
if (!enabled)
ret = sd_ipv4ll_stop(link->ipv4ll);
link->ipv4ll = sd_ipv4ll_unref(link->ipv4ll);
return ret;
}
int ipv4ll_update_mac(Link *link) { int ipv4ll_update_mac(Link *link) {
assert(link); assert(link);

View File

@ -6,10 +6,12 @@
#define IPV4LL_ROUTE_METRIC 2048 #define IPV4LL_ROUTE_METRIC 2048
typedef struct Link Link; typedef struct Link Link;
typedef struct Network Network;
bool link_ipv4ll_enabled(Link *link); bool link_ipv4ll_enabled(Link *link);
int ipv4ll_configure(Link *link); int ipv4ll_configure(Link *link);
int link_drop_ipv4ll_config(Link *link, Network *network);
int ipv4ll_update_mac(Link *link); int ipv4ll_update_mac(Link *link);
CONFIG_PARSER_PROTOTYPE(config_parse_ipv4ll); CONFIG_PARSER_PROTOTYPE(config_parse_ipv4ll);

Some files were not shown because too many files have changed in this diff Show More