Emanuele Giuseppe Esposito, Eric Daigle, Evgeny Vereshchagin,
Felix Riemann, Fernando Fernandez Mancera, Florian Schmaus, Franck Bui,
Frantisek Sumsal, Friedrich Altheide, GabrÃel Arthúr Pétursson,
- Gaël Donval, Georges Basile Stavracas Neto, Gerd Hoffmann,
- Guilhem Lettron, Göran Uddeborg, Hans de Goede, Harald Brinkmann,
- Heinrich Schuchardt, Henry Li, Holger Assmann, Ivan Kruglov,
+ Gaël Donval, Georges Basile Stavracas Neto, Gerd Hoffmann, GNOME
+ Foundation, Guilhem Lettron, Göran Uddeborg, Hans de Goede, Harald
+ Brinkmann, Heinrich Schuchardt, Henry Li, Holger Assmann, Ivan Kruglov,
Ivan Shapovalov, Jakub Sitnicki, James Muir, Jan Engelhardt, Jan Macku,
Jeff King, JmbFountain, Joakim Nohlgård, Julius Alexandre,
Jörg Behrmann, Keian, Kirk, Kristian Klausen, Krzesimir Nowak,
Fuzzers are invoked primarily in three ways:
firstly, each fuzzer is compiled as a normal executable and executed for each of the input samples under `test/fuzz/` as part of the test suite.
Secondly, fuzzers may be instrumented with sanitizers and invoked as part of the test suite (if `-Dfuzz-tests=true` is configured).
-Thirdly, fuzzers are executed through fuzzing engines that tryto find new "interesting" inputs through coverage feedback and massive parallelization; see the links for oss-fuzz in [Code quality](CODE_QUALITY).
+Thirdly, fuzzers are executed through fuzzing engines that tryto find new "interesting" inputs through coverage feedback and massive parallelization; see the links for oss-fuzz in [Code quality](/CODE_QUALITY).
For testing and debugging, fuzzers can be executed as any other program, including under `valgrind` or `gdb`.
## Integration Tests
* `1 << 1` → The boot loader honours `LoaderConfigTimeoutOneShot` when set.
* `1 << 2` → The boot loader honours `LoaderEntryDefault` when set.
* `1 << 3` → The boot loader honours `LoaderEntryOneShot` when set.
- * `1 << 4` → The boot loader supports boot counting as described in [Automatic Boot Assessment](AUTOMATIC_BOOT_ASSESSMENT).
+ * `1 << 4` → The boot loader supports boot counting as described in [Automatic Boot Assessment](/AUTOMATIC_BOOT_ASSESSMENT).
* `1 << 5` → The boot loader supports looking for boot menu entries in the Extended Boot Loader Partition.
* `1 << 6` → The boot loader supports passing a random seed to the OS.
* `1 << 13` → The boot loader honours `menu-disabled` option when set.
This document augments the existing documentation we already have:
-* [The New Control Group Interfaces](CONTROL_GROUP_INTERFACE)
-* [Writing VM and Container Managers](WRITING_VM_AND_CONTAINER_MANAGERS)
+* [The New Control Group Interfaces](/CONTROL_GROUP_INTERFACE)
+* [Writing VM and Container Managers](/WRITING_VM_AND_CONTAINER_MANAGERS)
These wiki documents are not as up to date as they should be, currently, but
the basic concepts still fully apply. You should read them too, if you do something
15. Each PR is automatically tested with [Address Sanitizer](https://clang.llvm.org/docs/AddressSanitizer.html)
and [Undefined Behavior Sanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html).
- See [Testing systemd using sanitizers](TESTING_WITH_SANITIZERS)
+ See [Testing systemd using sanitizers](/TESTING_WITH_SANITIZERS)
for more information.
16. Fossies provides [source code misspelling reports](https://fossies.org/features.html#codespell).
# The Container Interface
-Also consult [Writing Virtual Machine or Container Managers](WRITING_VM_AND_CONTAINER_MANAGERS).
+Also consult [Writing Virtual Machine or Container Managers](/WRITING_VM_AND_CONTAINER_MANAGERS).
systemd has a number of interfaces for interacting with container managers,
when systemd is used inside of an OS container. If you work on a container
## Security vulnerability reports
-See [reporting of security vulnerabilities](SECURITY).
+See [reporting of security vulnerabilities](/SECURITY).
## Posting Pull Requests
* Make sure to post PRs only relative to a recent tip of the `main` branch.
-* Follow our [Coding Style](CODING_STYLE) when contributing code. This is a requirement for all code we merge.
-* Please make sure to test your change before submitting the PR. See the [Hacking guide](HACKING) for details on how to do this.
+* Follow our [Coding Style](/CODING_STYLE) when contributing code. This is a requirement for all code we merge.
+* Please make sure to test your change before submitting the PR. See the [Hacking guide](/HACKING) for details on how to do this.
* Make sure to run the test suite locally, before posting your PR. We use a CI system, meaning we don't even look at your PR if the build and tests don't pass.
* If you need to update the code in an existing PR, force-push into the same branch, overriding old commits with new versions.
* After you have pushed a new version, add a comment explaining the latest changes.
Starting with version 205 systemd provides a number of interfaces that may be used to create and manage labelled groups of processes for the purpose of monitoring and controlling them and their resource usage.
This is built on top of the Linux kernel Control Groups ("cgroups") facility.
-Previously, the kernel's cgroups API was exposed directly as shared application API, following the rules of the [Pax Control Groups](PAX_CONTROL_GROUPS) document.
+Previously, the kernel's cgroups API was exposed directly as shared application API, following the rules of the [Pax Control Groups](/PAX_CONTROL_GROUPS) document.
However, the kernel cgroup interface has been reworked into an API that requires that each individual cgroup is managed by a single writer only.
With this change the main cgroup tree becomes private property of that userspace component and is no longer a shared resource.
### What's the timeframe of this? Do I need to care now?
-In the short-term future writing directly to the control group tree from applications should still be OK, as long as the [Pax Control Groups](PAX_CONTROL_GROUPS) document is followed. In the medium-term future it will still be supported to alter/read individual attributes of cgroups directly, but no longer to create/delete cgroups without using the systemd API. In the longer-term future altering/reading attributes will also be unavailable to userspace applications, unless done via systemd's APIs (either D-Bus based IPC APIs or shared library APIs for _passive_ operations).
+In the short-term future writing directly to the control group tree from applications should still be OK, as long as the [Pax Control Groups](/PAX_CONTROL_GROUPS) document is followed. In the medium-term future it will still be supported to alter/read individual attributes of cgroups directly, but no longer to create/delete cgroups without using the systemd API. In the longer-term future altering/reading attributes will also be unavailable to userspace applications, unless done via systemd's APIs (either D-Bus based IPC APIs or shared library APIs for _passive_ operations).
It is recommended to use the new systemd APIs described below in any case. Note that the kernel cgroup interface is currently being reworked (available when the "sane_behaviour" kernel option is used). This will change the cgroupfs interface. By using systemd's APIs this change is abstracted away and invisible to applications.
### VM and Container Managers
-Use these APIs to register any kind of process workload with systemd to be placed in a resource controlled cgroup. Note however that for containers and virtual machines it is better to use the [`machined`](https://www.freedesktop.org/software/systemd/man/latest/org.freedesktop.machine1.html) interfaces since they provide integration with "ps" and similar tools beyond what mere cgroup registration provides. Also see [Writing VM and Container Managers](WRITING_VM_AND_CONTAINER_MANAGERS) for details.
+Use these APIs to register any kind of process workload with systemd to be placed in a resource controlled cgroup. Note however that for containers and virtual machines it is better to use the [`machined`](https://www.freedesktop.org/software/systemd/man/latest/org.freedesktop.machine1.html) interfaces since they provide integration with "ps" and similar tools beyond what mere cgroup registration provides. Also see [Writing VM and Container Managers](/WRITING_VM_AND_CONTAINER_MANAGERS) for details.
### Reading Accounting Information
Before continuing, please read up on these basic concepts:
-* [Home Directories](HOME_DIRECTORY)
-* [JSON User Records](USER_RECORD)
-* [JSON Group Records](GROUP_RECORD)
-* [User/Group Record Lookup API via Varlink](USER_GROUP_API)
+* [Home Directories](/HOME_DIRECTORY)
+* [JSON User Records](/USER_RECORD)
+* [JSON Group Records](/GROUP_RECORD)
+* [User/Group Record Lookup API via Varlink](/USER_GROUP_API)
## Caveat
management and sandboxing.
The `systemd-coredump` handler will extract a backtrace and
-[ELF packaging metadata](ELF_PACKAGE_METADATA) from any coredumps it
+[ELF packaging metadata](/ELF_PACKAGE_METADATA) from any coredumps it
receives and log both.
The information about coredumps stored in the journal can be enumerated and queried with the
[`coredumpctl`](https://www.freedesktop.org/software/systemd/man/coredumpctl.html)
8. Credentials are an effective way to pass parameters into services that run
with `RootImage=` or `RootDirectory=` and thus cannot read these resources
directly from the host directory tree.
- Specifically, [Portable Services](PORTABLE_SERVICES) may be
+ Specifically, [Portable Services](/PORTABLE_SERVICES) may be
parameterized this way securely and robustly.
9. Credentials can be binary and relatively large (though currently an overall
[`systemd-nspawn(1)`](https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html#Credentials)'s
`--set-credential=` and `--load-credential=` switches implement this, in
order to pass arbitrary credentials from host to container payload. Also see
- the [Container Interface](CONTAINER_INTERFACE) documentation.
+ the [Container Interface](/CONTAINER_INTERFACE) documentation.
2. Quite similar, VMs can be passed credentials via SMBIOS OEM strings (example
qemu command line switch `-smbios
-device scsi-hd,drive=hd,bootindex=1 \
-device vhost-vsock-pci,id=vhost-vsock-pci0,guest-cid=42 \
-smbios type=11,value=io.systemd.credential:vmm.notify_socket=vsock:2:1234 \
- -smbios type=11,value=io.systemd.credential.binary:tmpfiles.extra=$(echo "f~ /root/.ssh/authorized_keys 600 root root - $(ssh-add -L | base64 -w 0)" | base64 -w 0)
+ -smbios type=11,value=io.systemd.credential.binary:tmpfiles.extra=$(echo -e "d /root/.ssh 0750 root root -\nf~ /root/.ssh/authorized_keys 0600 root root - $(ssh-add -L | base64 -w 0)" | base64 -w 0)
```
A process on the host can listen for the notification, for example:
expected format is six groups of two hexadecimal digits separated by colons,
e.g. `SYSTEMD_NSPAWN_NETWORK_MAC=12:34:56:78:90:AB`
+`systemd-vmspawn`:
+
+* `$SYSTEMD_VMSPAWN_NETWORK_MAC=...` — if set, allows users to set a specific MAC
+ address for a VM, ensuring that it uses the provided value instead of
+ generating a random one. It is effective when used with `--network-tap`. The
+ expected format is six groups of two hexadecimal digits separated by colons,
+ e.g. `SYSTEMD_VMSPAWN_NETWORK_MAC=12:34:56:78:90:AB`
+
`systemd-logind`:
* `$SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1` — if set, report that
# Frequently Asked Questions
-Also check out the [Tips & Tricks](TIPS_AND_TRICKS)!
+Also check out the [Tips & Tricks](/TIPS_AND_TRICKS)!
**Q: How do I change the current runlevel?**
**Q: Whenever my service tries to acquire RT scheduling for one of its threads this is refused with EPERM even though my service is running with full privileges. This works fine on my non-systemd system!**
-A: By default, systemd places all systemd daemons in their own cgroup in the "cpu" hierarchy. Unfortunately, due to a kernel limitation, this has the effect of disallowing RT entirely for the service. See [My Service Can't Get Realtime!](MY_SERVICE_CANT_GET_REATLIME) for a longer discussion and what to do about this.
+A: By default, systemd places all systemd daemons in their own cgroup in the "cpu" hierarchy. Unfortunately, due to a kernel limitation, this has the effect of disallowing RT entirely for the service. See [My Service Can't Get Realtime!](/MY_SERVICE_CANT_GET_REATLIME) for a longer discussion and what to do about this.
**Q: My service is ordered after `network.target` but at boot it is still called before the network is up. What's going on?**
-A: That's a long story, and that's why we have a wiki page of its own about this: [Running Services After the Network is up](NETWORK_ONLINE)
+A: That's a long story, and that's why we have a wiki page of its own about this: [Running Services After the Network is up](/NETWORK_ONLINE)
**Q: My systemd system always comes up with `/tmp` as a tiny `tmpfs`. How do I get rid of this?**
-A: That's also a long story, please have a look on [API File Systems](API_FILE_SYSTEMS)
+A: That's also a long story, please have a look on [API File Systems](/API_FILE_SYSTEMS)
# JSON Group Records
Long story short: JSON Group Records are to `struct group` what
-[JSON User Records](USER_RECORD) are to `struct passwd`.
+[JSON User Records](/USER_RECORD) are to `struct passwd`.
Conceptually, much of what applies to JSON user records also applies to JSON group records.
They also consist of seven sections, with similar properties and
If you notice a bug or a missing feature, please feel invited to fix it, and submit your work as a
[GitHub Pull Request (PR)](https://github.com/systemd/systemd/pull/new).
-Please make sure to follow our [Coding Style](CODING_STYLE) when submitting patches.
-Also have a look at our [Contribution Guidelines](CONTRIBUTING).
+Please make sure to follow our [Coding Style](/CODING_STYLE) when submitting patches.
+Also have a look at our [Contribution Guidelines](/CONTRIBUTING).
When adding new functionality, tests should be added.
For shared functionality (in `src/basic/` and `src/shared/`) unit tests should be sufficient.
`systemctl restart <units>` or `systemctl daemon-reexec` if you're working on pid1
or `systemctl soft-reboot` to restart everything.
+Aside from the image, the `mkosi.output` directory will also be populated with a
+set of distribution packages. Assuming you're running the same distribution and
+release as the mkosi image, you can install these rpms on your host or test
+system as well for any testing or debugging that cannot easily be performed in a
+VM or container.
+
+By default, no debuginfo packages are produced. To produce debuginfo packages,
+run mkosi with the `WITH_DEBUG` environment variable set to `1`:
+
+```sh
+$ mkosi -E WITH_DEBUG=1 -f
+```
+
+or configure it in `mkosi.local.conf`:
+
+```conf
+[Content]
+Environment=WITH_DEBUG=1
+```
+
Putting this all together, here's a series of commands for preparing a patch for systemd:
```sh
## Sanitizers in mkosi
-See [Testing systemd using sanitizers](TESTING_WITH_SANITIZERS) for more information on how to build with sanitizers enabled in mkosi.
+See [Testing systemd using sanitizers](/TESTING_WITH_SANITIZERS) for more information on how to build with sanitizers enabled in mkosi.
## Fuzzers
```
If you find a bug that impacts the security of systemd,
-please follow the guidance in [CONTRIBUTING.md](CONTRIBUTING) on how to report a security vulnerability.
+please follow the guidance in [CONTRIBUTING.md](/CONTRIBUTING) on how to report a security vulnerability.
For more details on building fuzzers and integrating with OSS-Fuzz, visit:
Inside of the home directory a file `~/.identity` contains the JSON formatted
user record of the user.
-It follows the format defined in [`JSON User Records`](USER_RECORD).
+It follows the format defined in [`JSON User Records`](/USER_RECORD).
It is recommended to bring the record into 'normalized' form(i.e. all objects should contain their fields
sorted alphabetically by their key) before storing it there,
though this is not required nor enforced.
* LSB header dependency information matters. The SysV implementations on many distributions did not use the dependency information encoded in LSB init script headers, or used them only in very limited ways. Due to that they are often incorrect or incomplete. systemd however fully interprets these headers and follows them closely at runtime (and not at installation time like some implementations).
* Timeouts apply to all init script operations in systemd. While on SysV systems a hanging init script could freeze the system on systemd all init script operations are subject to a timeout of 5min.
* Services are executed in completely clean execution contexts, no context of the invoking user session is inherited. Not even $HOME or similar are set. Init scripts depending on these will not work correctly.
-* Services cannot read from stdin, as this will be connected to /dev/null. That means interactive init scripts are not supported (i.e. Debian's X-Interactive in the LSB header is not supported either.) Thankfully most distributions do not support interaction in init scripts anyway. If you need interaction to ask disk or SSL passphrases please consider using the minimal password querying framework systemd supports. ([details](PASSWORD_AGENTS), [manual page](http://0pointer.de/public/systemd-man/systemd-ask-password.html))
+* Services cannot read from stdin, as this will be connected to /dev/null. That means interactive init scripts are not supported (i.e. Debian's X-Interactive in the LSB header is not supported either.) Thankfully most distributions do not support interaction in init scripts anyway. If you need interaction to ask disk or SSL passphrases please consider using the minimal password querying framework systemd supports. ([details](/PASSWORD_AGENTS), [manual page](http://0pointer.de/public/systemd-man/systemd-ask-password.html))
* Additional verbs for init scripts are not supported. If your init script traditionally supported additional verbs for your init script simply move them to an auxiliary script.
* Additional parameters to the standard verbs (i.e. to "start", "stop" and "status") are not supported. This was an extension of SysV that never was standardized officially, and is not supported in systemd.
* Overriding the "restart" verb is not supported. This verb is always implemented by systemd itself, and consists of a "stop" followed by a "start".
* It's highly recommended that the initrd also mounts `/usr/` (if split off) as
appropriate and passes it pre-mounted to the main system, to avoid the
- problems described in [Booting without /usr is Broken](SEPARATE_USR_IS_BROKEN).
+ problems described in [Booting without /usr is Broken](/SEPARATE_USR_IS_BROKEN).
* If the executable `/run/initramfs/shutdown` exists systemd will use it to
jump back into the initrd on shutdown. `/run/initramfs/` should be a usable
line options, for example `--log-level=` and similar.
* Storage daemons run from the initrd should follow the guide on
- [systemd and Storage Daemons for the Root File System](ROOT_STORAGE_DAEMONS)
+ [systemd and Storage Daemons for the Root File System](/ROOT_STORAGE_DAEMONS)
to survive properly from the boot initrd all the way to the point where
systemd jumps back into the initrd for shutdown.
* The switch-root operation will result in a killing spree of all running
processes. Some processes might need to be excluded from that, see the guide
- on [systemd and Storage Daemons for the Root File System](ROOT_STORAGE_DAEMONS).
+ on [systemd and Storage Daemons for the Root File System](/ROOT_STORAGE_DAEMONS).
_Note that this document describes the binary serialization format of journals only, as used for transfer across the network.
For interfacing with web technologies there's the Journal JSON Format, described below.
-The binary format on disk is documented as the [Journal File Format](JOURNAL_FILE_FORMAT)._
+The binary format on disk is documented as the [Journal File Format](/JOURNAL_FILE_FORMAT)._
_Before reading on, please make sure you are aware of the [basic properties of journal entries](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html), in particular realize that they may include binary non-text data (though usually don't), and the same field might have multiple values assigned within the same entry (though usually hasn't)._
_Note that this section describes the JSON serialization format of the journal only, as used for interfacing with web technologies.
For binary transfer of journal data across the network there's the Journal Export Format described above.
-The binary format on disk is documented as [Journal File Format](JOURNAL_FILE_FORMAT)._
+The binary format on disk is documented as [Journal File Format](/JOURNAL_FILE_FORMAT)._
_Before reading on, please make sure you are aware of the [basic properties of journal entries](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html), in particular realize that they may include binary non-text data (though usually don't), and the same field might have multiple values assigned within the same entry (though usually hasn't)._
_Or, to put this in other words: this low-level document is probably not what you want to use as base of your project.
You want our [C API](https://www.freedesktop.org/software/systemd/man/sd-journal.html) instead!
And if you really don't want the C API, then you want the
-[Journal Export Format or Journal JSON Format](JOURNAL_EXPORT_FORMATS) instead!
+[Journal Export Format or Journal JSON Format](/JOURNAL_EXPORT_FORMATS) instead!
This document is primarily for your entertainment and education.
Thank you!_
Instead, a management daemon of some kind needs to arbitrate access to it, and it needs to actively propagate changes between the entities it manages.
More specifically, on systemd systems this management daemon is systemd itself, accessible via a number of bus APIs.
This means instead of dealing directly with the low-level interfaces of the cgroup file system, please use systemd's high-level APIs as a replacement, see the
-[New Control Group Interfaces](CONTROL_GROUP_INTERFACE)
+[New Control Group Interfaces](/CONTROL_GROUP_INTERFACE)
for details. They offer similar functionality.**
Are you writing an application interfacing with the cgroups tree?
| [hostnamed](https://www.freedesktop.org/software/systemd/man/org.freedesktop.hostname1.html) | D-Bus | yes | yes | GNOME | yes | [Ubuntu](https://launchpad.net/ubuntu/+source/ubuntu-system-service), [Gentoo](http://www.gentoo.org/proj/en/desktop/gnome/openrc-settingsd.xml), [BSD](http://uglyman.kremlin.cc/gitweb/gitweb.cgi?p=systembsd.git;a=summary) | partially |
| [localed](https://www.freedesktop.org/software/systemd/man/org.freedesktop.locale1.html) | D-Bus | yes | yes | GNOME | yes | [Ubuntu](https://launchpad.net/ubuntu/+source/ubuntu-system-service), [Gentoo](http://www.gentoo.org/proj/en/desktop/gnome/openrc-settingsd.xml), [BSD](http://uglyman.kremlin.cc/gitweb/gitweb.cgi?p=systembsd.git;a=summary) | partially |
| [timedated](https://www.freedesktop.org/software/systemd/man/org.freedesktop.timedate1.html) | D-Bus | yes | yes | GNOME | yes | [Gentoo](http://www.gentoo.org/proj/en/desktop/gnome/openrc-settingsd.xml), [BSD](http://uglyman.kremlin.cc/gitweb/gitweb.cgi?p=systembsd.git;a=summary) | partially |
-| [initrd interface](INITRD_INTERFACE) | Environment, flag files | yes | yes | mkosi, dracut, ArchLinux | yes | ArchLinux | no |
-| [Container interface](CONTAINER_INTERFACE) | Environment, Mounts | yes | yes | libvirt/LXC | yes | - | no |
-| [Boot Loader interface](BOOT_LOADER_INTERFACE) | EFI variables | yes | yes | gummiboot | yes | - | no |
+| [initrd interface](/INITRD_INTERFACE) | Environment, flag files | yes | yes | mkosi, dracut, ArchLinux | yes | ArchLinux | no |
+| [Container interface](/CONTAINER_INTERFACE) | Environment, Mounts | yes | yes | libvirt/LXC | yes | - | no |
+| [Boot Loader interface](/BOOT_LOADER_INTERFACE) | EFI variables | yes | yes | gummiboot | yes | - | no |
| [Service bus API](https://www.freedesktop.org/software/systemd/man/org.freedesktop.systemd1.html) | D-Bus | yes | yes | system-config-services | no | - | no |
| [logind](https://www.freedesktop.org/software/systemd/man/org.freedesktop.login1.html) | D-Bus | yes | yes | GNOME | no | - | no |
| [sd-bus.h API](https://www.freedesktop.org/software/systemd/man/sd-bus.html) | C Library | yes | yes | - | maybe | - | maybe |
| [$XDG_RUNTIME_DIR](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) | Environment | yes | yes | glib, GNOME | yes | - | no |
| [$LISTEN_FDS $LISTEN_PID FD Passing](https://www.freedesktop.org/software/systemd/man/sd_listen_fds.html) | Environment | yes | yes | numerous (via sd-daemon.h) | yes | - | no |
| [$NOTIFY_SOCKET Daemon Notifications](https://www.freedesktop.org/software/systemd/man/sd_notify.html) | Environment | yes | yes | a few, including udev | yes | - | no |
-| [argv[0][0]='@' Logic](ROOT_STORAGE_DAEMONS) | `/proc` marking | yes | yes | mdadm | yes | - | no |
+| [argv[0][0]='@' Logic](/ROOT_STORAGE_DAEMONS) | `/proc` marking | yes | yes | mdadm | yes | - | no |
| [Unit file format](https://www.freedesktop.org/software/systemd/man/systemd.unit.html) | File format | yes | yes | numerous | no | - | no |
| [Network](https://www.freedesktop.org/software/systemd/man/systemd.network.html) & [Netdev file format](https://www.freedesktop.org/software/systemd/man/systemd.netdev.html) | File format | yes | yes | no | no | - | no |
| [Link file format](https://www.freedesktop.org/software/systemd/man/systemd.link.html) | File format | yes | yes | no | no | - | no |
-| [Journal File Format](JOURNAL_FILE_FORMAT) | File format | yes | yes | - | maybe | - | no |
+| [Journal File Format](/JOURNAL_FILE_FORMAT) | File format | yes | yes | - | maybe | - | no |
| [Journal Export Format](JOURNAL_EXPORT_FORMATS#journal-export-format) | File format | yes | yes | - | yes | - | no |
| [Journal JSON Format](JOURNAL_EXPORT_FORMATS#journal-json-format) | File format | yes | yes | - | yes | - | no |
-| [Cooperation in cgroup tree](PAX_CONTROL_GROUPS) | Treaty | yes | yes | libvirt | yes | libvirt | no |
-| [Password Agents](PASSWORD_AGENTS) | Socket+Files | yes | yes | - | yes | - | no |
+| [Cooperation in cgroup tree](/PAX_CONTROL_GROUPS) | Treaty | yes | yes | libvirt | yes | libvirt | no |
+| [Password Agents](/PASSWORD_AGENTS) | Socket+Files | yes | yes | - | yes | - | no |
| [udev multi-seat properties](https://www.freedesktop.org/software/systemd/man/sd-login.html) | udev Property | yes | yes | X11, gdm | no | - | no |
| udev session switch ACL properties | udev Property | no | no | - | no | - | no |
| [CLI of systemctl,...](https://www.freedesktop.org/software/systemd/man/systemctl.html) | CLI | yes | yes | numerous | no | - | no |
for an introduction why. That said, any boot loader can re-implement the
logic described above, and can pass a random seed that systemd as PID 1
will then upload into the kernel's entropy pool. For details see the
- [Boot Loader Interface](BOOT_LOADER_INTERFACE) documentation.
+ [Boot Loader Interface](/BOOT_LOADER_INTERFACE) documentation.
11. *Why not pass the boot loader random seed via kernel command line instead
of as EFI variable?*
The recommended way to distinguish between run-from-initrd and run-from-rootfs
for a daemon is to check for `/etc/initrd-release` (which exists on all modern
-initrd implementations, see the [initrd Interface](INITRD_INTERFACE) for
+initrd implementations, see the [initrd Interface](/INITRD_INTERFACE) for
details) which when exists results in `argv[0][0]` being set to `@`, and
otherwise doesn't. Something like this:
program consult this blog story: [Socket
Activation](https://0pointer.de/blog/projects/socket-activation.html)
-* Consider having a look at the [initrd Interface of systemd](INITRD_INTERFACE).
+* Consider having a look at the [initrd Interface of systemd](/INITRD_INTERFACE).
Such a setup would be more efficient, can provide additional security, is more flexible to use,
provides saner options for custom setups, and is much simpler to setup and maintain.
-For more information on this please continue to [The Case for the /usr Merge](THE_CASE_FOR_THE_USR_MERGE).
+For more information on this please continue to [The Case for the /usr Merge](/THE_CASE_FOR_THE_USR_MERGE).
**Myth #10**: The status quo of a split /usr with mounting it without initrd is perfectly well supported right now and works.
-**Fact**: A split /usr without involvement of an initrd mounting it before jumping into the root file system [hasn't worked correctly since a long time](SEPARATE_USR_IS_BROKEN).
+**Fact**: A split /usr without involvement of an initrd mounting it before jumping into the root file system [hasn't worked correctly since a long time](/SEPARATE_USR_IS_BROKEN).
**Myth #11**: Instead of merging / into /usr it would make a lot more sense to merge /usr into /.
# Tips & Tricks
-Also check out the [Frequently Asked Questions](FAQ)!
+Also check out the [Frequently Asked Questions](/FAQ)!
## Listing running services
Before reading on, please read up on the basic concepts, specifically:
-* [Home Directories](HOME_DIRECTORY)
-* [JSON User Records](USER_RECORD)
-* [JSON Group Records](GROUP_RECORD)
-* [User/Group Record Lookup API via Varlink](USER_GROUP_API)
+* [Home Directories](/HOME_DIRECTORY)
+* [JSON User Records](/USER_RECORD)
+* [JSON Group Records](/GROUP_RECORD)
+* [User/Group Record Lookup API via Varlink](/USER_GROUP_API)
## Support for Suspending Home Directory Access during System Suspend
In case you wonder, there's no automatic mechanism for converting existing
users registered in `/etc/passwd` or LDAP to users managed by `systemd-homed`.
There's documentation for doing this manually though, see
-[Converting Existing Users to systemd-homed managed Users](CONVERTING_TO_HOMED).
+[Converting Existing Users to systemd-homed managed Users](/CONVERTING_TO_HOMED).
## Future Additions
# User/Group Record Lookup API via Varlink
-JSON User/Group Records (as described in the [JSON User Records](USER_RECORD)
-and [JSON Group Records](GROUP_RECORD) documents) that are defined on the
+JSON User/Group Records (as described in the [JSON User Records](/USER_RECORD)
+and [JSON Group Records](/GROUP_RECORD) documents) that are defined on the
local system may be queried with a [Varlink](https://varlink.org/) API.
This API takes both the role of what
[`getpwnam(3)`](https://man7.org/linux/man-pages/man3/getpwnam.3.html) and
1. [`systemd-homed.service`](https://www.freedesktop.org/software/systemd/man/systemd-homed.service.html)
manages `human` user home directories and embeds these JSON records
directly in the home directory images
- (see [Home Directories](HOME_DIRECTORY) for details).
+ (see [Home Directories](/HOME_DIRECTORY) for details).
2. [`pam_systemd`](https://www.freedesktop.org/software/systemd/man/pam_systemd.html)
processes these JSON records for users that log in, and applies various
4. Default parameters for backup applications and similar
Similar to JSON User Records there are also
-[JSON Group Records](GROUP_RECORD) that encapsulate UNIX groups.
+[JSON Group Records](/GROUP_RECORD) that encapsulate UNIX groups.
JSON User Records are not suitable for storing all identity information about
the user, such as binary data or large unstructured blobs of text. These parts
-of a user's identity should be stored in the [Blob Directories](USER_RECORD_BLOB_DIRS).
+of a user's identity should be stored in the [Blob Directories](/USER_RECORD_BLOB_DIRS).
JSON User Records may be transferred or written to disk in various protocols
and formats. To inquire about such records defined on the local system use the
-[User/Group Lookup API via Varlink](USER_GROUP_API). User/group records may
+[User/Group Lookup API via Varlink](/USER_GROUP_API). User/group records may
also be dropped in number of drop-in directories as files. See
[`nss-systemd(8)`](https://www.freedesktop.org/software/systemd/man/nss-systemd.html)
for details.
Takes a string with a valid UNIX user name.
This field is the only mandatory field, all others are optional.
Corresponds with the `pw_name` field of `struct passwd` and the `sp_namp` field of `struct spwd` (i.e. the shadow user record stored in `/etc/shadow`).
-See [User/Group Name Syntax](USER_NAMES)
+See [User/Group Name Syntax](/USER_NAMES)
for the (relaxed) rules the various systemd components enforce on user/group names.
`realm` → The "realm" a user is defined in.
see above) with a user record without one set, even if the `userName` field matches.
`blobDirectory` → The absolute path to a world-readable copy of the user's blob
-directory. See [Blob Directories](USER_RECORD_BLOB_DIRS) for more details.
+directory. See [Blob Directories](/USER_RECORD_BLOB_DIRS) for more details.
`blobManifest` → An object, which maps valid blob directory filenames (see
-[Blob Directories](USER_RECORD_BLOB_DIRS) for requirements) to SHA256 hashes
+[Blob Directories](/USER_RECORD_BLOB_DIRS) for requirements) to SHA256 hashes
formatted as hex strings. This exists for the purpose of including the contents
of the blob directory in the record's signature. Managers that support blob
directories and utilize signed user records (like `systemd-homed`) should use
# User Record Blob Directories
The blob directories are for storing binary or unstructured data that would
-otherwise be stored in [JSON User Records](USER_RECORD). For instance,
+otherwise be stored in [JSON User Records](/USER_RECORD). For instance,
this includes image files such as the user's avatar picture. This data,
like most of the user record, will be made publicly available to the
system.
systemd's logind service obsoletes ConsoleKit which was previously widely used on Linux distributions.
This provides a number of new features, but also requires updating of the Desktop Environment running on it, in a few ways.
-This document should be read together with [Writing Display Managers](WRITING_DISPLAY_MANAGERS) which focuses on the porting work necessary for display managers.
+This document should be read together with [Writing Display Managers](/WRITING_DISPLAY_MANAGERS) which focuses on the porting work necessary for display managers.
If required it is possible to implement ConsoleKit and systemd-logind support in the same desktop environment code, detecting at runtime which interface is needed.
The [sd_booted()](http://www.freedesktop.org/software/systemd/man/sd_booted.html) call may be used to determine at runtime whether systemd is used.
- If your session manager handles the special power, suspend, hibernate hardware keys or the laptop lid switch on its own it is welcome to do so,
but needs to disable logind's built-in handling of these events.
Take one or more of the _handle-power-key_, _handle-suspend-key_, _handle-hibernate-key_, _handle-lid-switch_ inhibitor locks for that.
- See [Inhibitor Locks](INHIBITOR_LOCKS) for further details on this.
+ See [Inhibitor Locks](/INHIBITOR_LOCKS) for further details on this.
- Before rebooting/powering-off/suspending/hibernating and when the operation is triggered by the user by clicking on some UI elements
(or suchlike) it is recommended to show the list of currently active inhibitors for the operation, and ask the user to acknowledge the operation.
Note that PK often allows the user to execute the operation ignoring the inhibitors.
- Use logind's ListInhibitors() call to get a list of these inhibitors. See [Inhibitor Locks](INHIBITOR_LOCKS) for further details on this.
+ Use logind's ListInhibitors() call to get a list of these inhibitors. See [Inhibitor Locks](/INHIBITOR_LOCKS) for further details on this.
- If your DE contains a process viewer of some kind ("system monitor") it's a good idea to show session, service and seat information for each process.
Use sd_pid_get_session(), sd_pid_get_unit(), sd_session_get_seat() to determine these.
For details see [sd-login(7)](http://www.freedesktop.org/software/systemd/man/sd-login.html).
For X11 display managers the switch to logind requires a minimal amount of porting, however brings a couple of new features:
true automatic multi-seat support, proper tracking of session processes, (optional) automatic killing of user processes on logout, a synchronous low-level C API and much simplification.
-This document should be read together with [Writing Desktop Environments](WRITING_DESKTOP_ENVIRONMENTS) which focuses on the porting work necessary for desktop environments.
+This document should be read together with [Writing Desktop Environments](/WRITING_DESKTOP_ENVIRONMENTS) which focuses on the porting work necessary for desktop environments.
If required it is possible to implement ConsoleKit and systemd-logind support in the same display manager, detecting at runtime which interface is needed.
The [sd_booted()](http://www.freedesktop.org/software/systemd/man/sd_booted.html) call may be used to determine at runtime whether systemd is used.
## Guest OS Integration
-As container virtualization is much less comprehensive, and the guest is less isolated from the host, there are a number of interfaces defined how the container manager can set up the environment for systemd running inside a container. These Interfaces are documented in [Container Interface of systemd](CONTAINER_INTERFACE).
+As container virtualization is much less comprehensive, and the guest is less isolated from the host, there are a number of interfaces defined how the container manager can set up the environment for systemd running inside a container. These Interfaces are documented in [Container Interface of systemd](/CONTAINER_INTERFACE).
VM virtualization is more comprehensive and fewer integration APIs are available.
In fact there's only one: a VM manager may initialize the SMBIOS DMI field "Product UUUID" to a UUID uniquely identifying this virtual machine instance.
baseurl: "" # the subpath of your site, e.g. /blog/
url: "https://systemd.io" # the base hostname & protocol for your site
-permalink: /:title
+permalink: /:title/
# Build settings
markdown: kramdown
<!--method EnqueueUnitJob is not documented!-->
- <!--method CleanUnit is not documented!-->
-
<!--method FreezeUnit is not documented!-->
<!--method ThawUnit is not documented!-->
shouldn't be bound to a lifecycle of the service, e.g. they should continue running after the restart
of the service. Note that the main PID of the service can not be migrated to an auxiliary scope.
Also, <varname>flags</varname> argument must be 0 and is reserved for future extensions.</para>
+
+ <para><function>CleanUnit()</function> deletes the configuration, state, logs, cache and runtime data
+ directories and clear out the file descriptors store for the unit, as specified in the mask
+ parameters. The possible values are <literal>configuration</literal>, <literal>state</literal>,
+ <literal>logs</literal>, <literal>cache</literal>, <literal>runtime</literal>,
+ <literal>fdstore</literal>, and <literal>all</literal>.</para>
</refsect2>
<refsect2>
<refsect1>
<title>History</title>
<para><function>sd_bus_add_match()</function> and
- <function>sd_bus_message_handler_t()</function> were added in version 231.</para>
+ <function>sd_bus_message_handler_t()</function> were added in version 221.</para>
<para><function>sd_bus_add_match_async()</function>,
<function>sd_bus_match_signal()</function>, and
<function>sd_bus_match_signal_async()</function> were added in version 237.</para>
<term><constant>-EINVAL</constant></term>
<listitem><para>One of the required parameters is <constant>NULL</constant> or
- <parameter>path</parameter> is not a valid object path.
- </para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <parameter>path</parameter> is not a valid object path.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ENOPKG</constant></term>
- <listitem><para>The bus cannot be resolved.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>The bus cannot be resolved.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ECHILD</constant></term>
- <listitem><para>The bus was created in a different process, library or module instance.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>The bus was created in a different process, library or module instance.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ENOMEM</constant></term>
- <listitem><para>Memory allocation failed.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>Memory allocation failed.</para></listitem>
</varlistentry>
</variablelist>
</refsect2>
<refsect1>
<title>History</title>
<para><function>sd_bus_node_enumerator_t()</function> and
- <function>sd_bus_add_node_enumerator()</function> were added in version 246.</para>
+ <function>sd_bus_add_node_enumerator()</function> were added in version 221.</para>
</refsect1>
<refsect1>
combination of flags, see below.</para>
<para><constant>SD_BUS_METHOD_WITH_ARGS()</constant> is a shorthand for calling
- <constant>SD_BUS_METHOD_WITH_ARGS_OFFSET()</constant> with an offset of zero.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/>
- </listitem>
+ <constant>SD_BUS_METHOD_WITH_ARGS_OFFSET()</constant> with an offset of zero.</para></listitem>
</varlistentry>
<varlistentry>
<para>Prefer using <constant>SD_BUS_METHOD_WITH_ARGS_OFFSET()</constant> and
<constant>SD_BUS_METHOD_WITH_ARGS()</constant> over these macros as they allow specifying argument
types and names next to each other which is less error-prone than first specifying all argument
- types followed by specifying all argument names.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/>
- </listitem>
+ types followed by specifying all argument names.</para></listitem>
</varlistentry>
<varlistentry>
<replaceable>args</replaceable>. If a signal has no parameters, pass
<constant>SD_BUS_NO_ARGS</constant> to <replaceable>args</replaceable>. The elements at uneven
indices describe the names of the signal's arguments. Parameter <replaceable>flags</replaceable> is
- a combination of flags. See below for a complete example.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ a combination of flags. See below for a complete example.</para></listitem>
</varlistentry>
<varlistentry>
<para>Prefer using <constant>SD_BUS_SIGNAL_WITH_ARGS()</constant> over these macros as it allows
specifying argument types and names next to each other which is less error-prone than first
- specifying all argument types followed by specifying all argument names.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/>
- </listitem>
+ specifying all argument types followed by specifying all argument names.</para></listitem>
</varlistentry>
<varlistentry>
</para>
<para><constant>SD_BUS_PROPERTY()</constant> is used to define a read-only property.
- </para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ </para></listitem>
</varlistentry>
<varlistentry>
<term><constant>SD_BUS_PARAM()</constant></term>
<listitem><para>Parameter names should be wrapped in this macro, see the example below.
- </para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ </para></listitem>
</varlistentry>
</variablelist>
</refsect2>
<listitem><para>Mark this vtable entry as deprecated using the
<constant>org.freedesktop.DBus.Deprecated</constant> annotation in introspection data. If
specified for <constant>SD_BUS_VTABLE_START()</constant>, the annotation is applied to the
- enclosing interface.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ enclosing interface.</para></listitem>
</varlistentry>
<varlistentry>
<listitem><para>Make this vtable entry hidden. It will not be shown in introspection data.
If specified for <constant>SD_BUS_VTABLE_START()</constant>, all entries in the array are
- hidden.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ hidden.</para></listitem>
</varlistentry>
<varlistentry>
<listitem><para>Mark this vtable entry as a method that will not return a reply using the
<constant>org.freedesktop.DBus.Method.NoReply</constant> annotation in introspection data.
- </para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ </para></listitem>
</varlistentry>
<varlistentry>
<constant>true</constant> and means that the signal is emitted.
<constant>SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION</constant> corresponds to
<constant>invalidates</constant> and means that the signal is emitted, but the value is
- not included in the signal.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ not included in the signal.</para></listitem>
</varlistentry>
<varlistentry>
cannot be combined with <constant>SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE</constant>, and will
not be shown in property listings by default (e.g. <command>busctl introspect</command>).
This corresponds to the <constant>org.freedesktop.systemd1.Explicit</constant> annotation
- in introspection data.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ in introspection data.</para></listitem>
</varlistentry>
<varlistentry>
<listitem><para>Mark this vtable method entry as processing sensitive data. When set,
incoming method call messages and their outgoing reply messages are marked as sensitive using
<citerefentry><refentrytitle>sd_bus_message_sensitive</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- so that they are erased from memory when freed.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ so that they are erased from memory when freed.</para></listitem>
</varlistentry>
<varlistentry>
its associated handler functions is determined slightly differently: instead of adding the offset
parameter of the entry to the user data pointer specified during vtable registration, the offset is
passed directly, converted to a pointer, without taking the user data pointer specified during
- vtable registration into account.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ vtable registration into account.</para></listitem>
</varlistentry>
<varlistentry>
for information about capabilities.</para>
<para>Note that vtable entries may be marked as unprivileged and the whole bus may be marked as
- trusted, see the discussion of <constant>SD_BUS_VTABLE_UNPRIVILEGED</constant> below.</para>
-
- <xi:include href="version-info.xml" xpointer="v251"/>
- </listitem>
+ trusted, see the discussion of <constant>SD_BUS_VTABLE_UNPRIVILEGED</constant> below.</para></listitem>
</varlistentry>
<varlistentry>
additional policy that may permit or deny connections, see
"CONFIGURATION FILE" in
<citerefentry project='man-pages'><refentrytitle>dbus-daemon</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
- </para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ </para></listitem>
</varlistentry>
</variablelist>
</refsect2>
<listitem><para>One of the required parameters is <constant>NULL</constant> or invalid. A
reserved D-Bus interface was passed as the <replaceable>interface</replaceable> parameter.
- </para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ </para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ENOPKG</constant></term>
- <listitem><para>The bus cannot be resolved.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>The bus cannot be resolved.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ECHILD</constant></term>
- <listitem><para>The bus was created in a different process, library or module instance.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>The bus was created in a different process, library or module instance.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ENOMEM</constant></term>
- <listitem><para>Memory allocation failed.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>Memory allocation failed.</para></listitem>
</varlistentry>
<varlistentry>
<listitem><para><function>sd_bus_add_object_vtable()</function> and
<function>sd_bus_add_fallback_vtable()</function> have been both called for the same bus
- object path, which is not allowed.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ object path, which is not allowed.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-EEXIST</constant></term>
<listitem><para>This vtable has already been registered for this
- <replaceable>interface</replaceable> and <replaceable>path</replaceable>.
- </para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <replaceable>interface</replaceable> and <replaceable>path</replaceable>.</para></listitem>
</varlistentry>
</variablelist>
</refsect2>
<function>sd_bus_add_fallback()</function>,
<function>sd_bus_add_object_vtable()</function>,
<function>sd_bus_add_fallback_vtable()</function>, and
- <function>sd_bus_add_filter()</function> were added in version 246.</para>
+ <function>sd_bus_add_filter()</function> were added in version 221.</para>
</refsect1>
<refsect1>
<term><constant>-EINVAL</constant></term>
<listitem><para>One of the required parameters is <constant>NULL</constant> or
- <parameter>path</parameter> is not a valid object path.
- </para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <parameter>path</parameter> is not a valid object path.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ENOPKG</constant></term>
- <listitem><para>The bus cannot be resolved.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>The bus cannot be resolved.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ECHILD</constant></term>
- <listitem><para>The bus was created in a different process, library or module instance.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>The bus was created in a different process, library or module instance.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ENOMEM</constant></term>
- <listitem><para>Memory allocation failed.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>Memory allocation failed.</para></listitem>
</varlistentry>
</variablelist>
</refsect2>
<refsect1>
<title>History</title>
- <para><function>sd_bus_add_object_manager()</function> was added in version 246.</para>
+ <para><function>sd_bus_add_object_manager()</function> was added in version 221.</para>
</refsect1>
<refsect1>
<title>History</title>
<para><function>sd_bus_attach_event()</function>,
<function>sd_bus_detach_event()</function>, and
- <function>sd_bus_get_event()</function> were added in version 240.</para>
+ <function>sd_bus_get_event()</function> were added in version 221.</para>
</refsect1>
<refsect1>
<para>The input parameter <parameter>error</parameter> is
non-<constant>NULL</constant> but was not set to <constant>SD_BUS_ERROR_NULL</constant>.
</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/>
</listitem>
</varlistentry>
<term><constant>-ECHILD</constant></term>
<listitem><para>The bus connection was allocated in a parent process and is being reused
- in a child process after <function>fork()</function>.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ in a child process after <function>fork()</function>.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ENOTCONN</constant></term>
<listitem><para>The input parameter <parameter>bus</parameter> is
- <constant>NULL</constant> or the bus is not connected.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <constant>NULL</constant> or the bus is not connected.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ECONNRESET</constant></term>
<listitem><para>The bus connection was closed while waiting for the response.
- </para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ </para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ETIMEDOUT</constant></term>
- <listitem><para>A response was not received within the given timeout.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>A response was not received within the given timeout.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ELOOP</constant></term>
<listitem><para>The message <parameter>m</parameter> is addressed to its own client.
- </para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ </para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ENOMEM</constant></term>
- <listitem><para>Memory allocation failed.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>Memory allocation failed.</para></listitem>
</varlistentry>
</variablelist>
</refsect2>
<refsect1>
<title>History</title>
<para><function>sd_bus_call()</function> and
- <function>sd_bus_call_async()</function> were added in version 246.</para>
+ <function>sd_bus_call_async()</function> were added in version 221.</para>
</refsect1>
<refsect1>
<refsect1>
<title>History</title>
- <para><function>sd_bus_call_method()</function>,
- <function>sd_bus_call_methodv()</function>,
- <function>sd_bus_call_method_async()</function>, and
+ <para><function>sd_bus_call_method()</function>, and
+ <function>sd_bus_call_method_async()</function> were added in version 221.</para>
+ <para><function>sd_bus_call_methodv()</function>,
<function>sd_bus_call_method_asyncv()</function> were added in version 246.</para>
</refsect1>
<varlistentry>
<term><constant>-ENOPKG</constant></term>
- <listitem><para>The bus object <parameter>bus</parameter> could not be resolved.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/>
- </listitem>
+ <listitem><para>The bus object <parameter>bus</parameter> could not be resolved.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ENOTCONN</constant></term>
<listitem><para>The input parameter <parameter>bus</parameter> is
- <constant>NULL</constant> or the bus is not connected.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <constant>NULL</constant> or the bus is not connected.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ECHILD</constant></term>
<listitem><para>The bus object <parameter>bus</parameter> was created in a different
- process.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ process.</para></listitem>
</varlistentry>
</variablelist>
</refsect2>
<refsect1>
<title>History</title>
- <para><function>sd_bus_can_send()</function> was added in version 246.</para>
+ <para><function>sd_bus_can_send()</function> was added in version 221.</para>
</refsect1>
<refsect1>
<refsect1>
<title>History</title>
<para><function>sd_bus_close()</function> and
- <function>sd_bus_flush()</function> were added in version 240.</para>
- <para><function>sd_bus_default_flush_close()</function> was added in version 246.</para>
+ <function>sd_bus_flush()</function> were added in version 221.</para>
+ <para><function>sd_bus_default_flush_close()</function> was added in version 227.</para>
</refsect1>
<refsect1>
<function>sd_bus_creds_get_selinux_context()</function>,
<function>sd_bus_creds_get_audit_session_id()</function>,
<function>sd_bus_creds_get_audit_login_uid()</function>,
- <function>sd_bus_creds_get_unique_name()</function>, and
- <function>sd_bus_creds_get_well_known_names()</function> were added in version 209.</para>
- <para><function>sd_bus_creds_get_ppid()</function>,
+ <function>sd_bus_creds_get_unique_name()</function>,
+ <function>sd_bus_creds_get_well_known_names()</function>,
+ <function>sd_bus_creds_get_ppid()</function>,
<function>sd_bus_creds_get_uid()</function>,
<function>sd_bus_creds_get_euid()</function>,
<function>sd_bus_creds_get_suid()</function>,
<function>sd_bus_creds_get_sgid()</function>,
<function>sd_bus_creds_get_fsgid()</function>,
<function>sd_bus_creds_get_supplementary_gids()</function>,
- <function>sd_bus_creds_get_tty()</function>, and
- <function>sd_bus_creds_get_description()</function> were added in version 220.</para>
- <para><function>sd_bus_creds_get_user_slice()</function> was added in version 223.</para>
+ <function>sd_bus_creds_get_tty()</function>,
+ <function>sd_bus_creds_get_description()</function>, and
+ <function>sd_bus_creds_get_user_slice()</function> were added in version 221.</para>
<para><function>sd_bus_creds_get_pidfd_dup()</function> was added in version 256.</para>
</refsect1>
<title>History</title>
<para><function>sd_bus_creds_new_from_pid()</function>,
<function>sd_bus_creds_get_mask()</function>,
- <function>sd_bus_creds_ref()</function>, and
- <function>sd_bus_creds_unref()</function> were added in version 209.</para>
- <para><function>sd_bus_creds_get_augmented_mask()</function> was added in version 223.</para>
+ <function>sd_bus_creds_ref()</function>,
+ <function>sd_bus_creds_unref()</function>, and
+ <function>sd_bus_creds_get_augmented_mask()</function> were added in version 221.</para>
<para><function>sd_bus_creds_unrefp()</function> was added in version 229.</para>
<para><function>sd_bus_creds_new_from_pidfd()</function> was added in version 256.</para>
</refsect1>
<listitem><para>The requested bus type is not available because of invalid environment (for example
the user session bus is not available because <varname>$XDG_RUNTIME_DIR</varname> is not set).
- </para>
-
- <xi:include href="version-info.xml" xpointer="v247"/></listitem>
+ </para></listitem>
</varlistentry>
<varlistentry>
<function>sd_bus_open_user()</function>,
<function>sd_bus_open_system()</function>,
<function>sd_bus_open_system_remote()</function>, and
- <function>sd_bus_open_system_machine()</function> were added in version 220.</para>
+ <function>sd_bus_open_system_machine()</function> were added in version 221.</para>
<para><function>sd_bus_open_with_description()</function>,
<function>sd_bus_open_user_with_description()</function>, and
- <function>sd_bus_open_system_with_description()</function> were added in version 240.</para>
+ <function>sd_bus_open_system_with_description()</function> were added in version 239.</para>
<para><function>sd_bus_open_user_machine()</function> was added in version 248.</para>
</refsect1>
<listitem><para>One of the required parameters is <constant>NULL</constant> or invalid. A
reserved D-Bus interface was passed as the <replaceable>interface</replaceable> parameter.
- </para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ </para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ENOPKG</constant></term>
- <listitem><para>The bus cannot be resolved.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>The bus cannot be resolved.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ECHILD</constant></term>
- <listitem><para>The bus was created in a different process, library or module instance.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>The bus was created in a different process, library or module instance.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ENOMEM</constant></term>
- <listitem><para>Memory allocation failed.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>Memory allocation failed.</para></listitem>
</varlistentry>
<varlistentry>
<function>sd_bus_emit_object_added()</function> or
<function>sd_bus_emit_object_removed()</function> was called on an object without an
object manager registered on its own object path or one of its parent object paths.
- </para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ </para></listitem>
</varlistentry>
</variablelist>
<refsect1>
<title>History</title>
<para><function>sd_bus_emit_signal()</function>,
- <function>sd_bus_emit_signalv()</function>,
<function>sd_bus_emit_interfaces_added()</function>,
<function>sd_bus_emit_interfaces_added_strv()</function>,
<function>sd_bus_emit_interfaces_removed()</function>,
<function>sd_bus_emit_interfaces_removed_strv()</function>,
<function>sd_bus_emit_properties_changed()</function>,
- <function>sd_bus_emit_properties_changed_strv()</function>,
- <function>sd_bus_emit_object_added()</function>, and
- <function>sd_bus_emit_object_removed()</function> were added in version 246.</para>
+ <function>sd_bus_emit_properties_changed_strv()</function>, were added in version 221.</para>
+ <para><function>sd_bus_emit_object_added()</function>, and
+ <function>sd_bus_emit_object_removed()</function> were added in version 222.</para>
+ <para><function>sd_bus_emit_signalv()</function> was added in version 246.</para>
<para><function>sd_bus_emit_signal_to()</function> and
<function>sd_bus_emit_signal_tov()</function> were added in version 253.</para>
</refsect1>
<varlistentry>
<term><constant>-ECHILD</constant></term>
- <listitem><para>The bus connection has been created in a different process, library or module instance.</para>
-
- <xi:include href="version-info.xml" xpointer="v245"/></listitem>
+ <listitem><para>The bus connection has been created in a different process, library or module instance.</para></listitem>
</varlistentry>
</variablelist>
</refsect2>
<function>sd_bus_error_set_const()</function>,
<function>sd_bus_error_set_errno()</function>,
<function>sd_bus_error_set_errnof()</function>,
+ <function>sd_bus_error_set_errnofv()</function>,
<function>sd_bus_error_get_errno()</function>,
<function>sd_bus_error_copy()</function>,
<function>sd_bus_error_is_set()</function>, and
- <function>sd_bus_error_has_name()</function> were added in version 209.</para>
- <para><function>sd_bus_error_set_errnofv()</function> was added in version 223.</para>
+ <function>sd_bus_error_has_name()</function> were added in version 221.</para>
<para><function>sd_bus_error_move()</function> was added in version 240.</para>
<para><function>sd_bus_error_has_names_sentinel()</function> was added in version 247.</para>
<para><function>sd_bus_error_setfv()</function> was added in version 252.</para>
<refsect1>
<title>History</title>
- <para><function>sd_bus_error_add_map()</function> was added in version 223.</para>
+ <para><function>sd_bus_error_add_map()</function> was added in version 221.</para>
</refsect1>
<refsect1>
<para><function>sd_bus_get_current_handler()</function>,
<function>sd_bus_get_current_message()</function>,
<function>sd_bus_get_current_slot()</function>, and
- <function>sd_bus_get_current_userdata()</function> were added in version 246.</para>
+ <function>sd_bus_get_current_userdata()</function> were added in version 221.</para>
</refsect1>
<refsect1>
<varlistentry>
<term><constant>-ENOPKG</constant></term>
- <listitem><para>The bus cannot be resolved.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>The bus cannot be resolved.</para></listitem>
</varlistentry>
</variablelist>
</refsect2>
<refsect1>
<title>History</title>
- <para><function>sd_bus_get_fd()</function> was added in version 231.</para>
- <para><function>sd_bus_get_events()</function> and
- <function>sd_bus_get_timeout()</function> were added in version 240.</para>
+ <para><function>sd_bus_get_fd()</function>,
+ <function>sd_bus_get_events()</function>, and
+ <function>sd_bus_get_timeout()</function> were added in version 221.</para>
</refsect1>
<refsect1>
<varlistentry>
<term><constant>-EINVAL</constant></term>
- <listitem><para>An argument is invalid.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>An argument is invalid.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ENOPKG</constant></term>
- <listitem><para>The bus cannot be resolved.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>The bus cannot be resolved.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-EPERM</constant></term>
- <listitem><para>The bus has already been started.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>The bus has already been started.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ECHILD</constant></term>
- <listitem><para>The bus was created in a different process, library or module instance.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>The bus was created in a different process, library or module instance.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ENOMEM</constant></term>
- <listitem><para>Memory allocation failed.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>Memory allocation failed.</para></listitem>
</varlistentry>
</variablelist>
</refsect2>
<refsect1>
<title>History</title>
<para><function>sd_bus_get_name_creds()</function> and
- <function>sd_bus_get_owner_creds()</function> were added in version 246.</para>
+ <function>sd_bus_get_owner_creds()</function> were added in version 221.</para>
</refsect1>
<refsect1>
<varlistentry>
<term><constant>-EINVAL</constant></term>
- <listitem><para>An argument is invalid.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>An argument is invalid.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ENOPKG</constant></term>
- <listitem><para>The bus cannot be resolved.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>The bus cannot be resolved.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ECHILD</constant></term>
- <listitem><para>The bus was created in a different process, library or module instance.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>The bus was created in a different process, library or module instance.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ENOMEM</constant></term>
- <listitem><para>Memory allocation failed.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>Memory allocation failed.</para></listitem>
</varlistentry>
</variablelist>
</refsect2>
<refsect1>
<title>History</title>
- <para><function>sd_bus_get_name_machine_id()</function> was added in version 246.</para>
+ <para><function>sd_bus_get_name_machine_id()</function> was added in version 221.</para>
</refsect1>
<refsect1>
<term><constant>-EINVAL</constant></term>
<listitem><para>The <parameter>p</parameter> parameter is
- <constant>NULL</constant>.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <constant>NULL</constant>.</para></listitem>
</varlistentry>
</variablelist>
</refsect2>
<refsect1>
<title>History</title>
- <para><function>sd_bus_is_open()</function> and
- <function>sd_bus_is_ready()</function> were added in version 237.</para>
+ <para><function>sd_bus_is_open()</function> was added in version 221.</para>
+ <para><function>sd_bus_is_ready()</function> was added in version 237.</para>
</refsect1>
<refsect1>
<term><constant>-EINVAL</constant></term>
<listitem><para><parameter>bus</parameter> or both <parameter>acquired</parameter> and
- <parameter>activatable</parameter> were <constant>NULL</constant>.
- </para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <parameter>activatable</parameter> were <constant>NULL</constant>.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ENOPKG</constant></term>
- <listitem><para>The bus cannot be resolved.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>The bus cannot be resolved.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ECHILD</constant></term>
- <listitem><para>The bus was created in a different process, library or module instance.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>The bus was created in a different process, library or module instance.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ENOMEM</constant></term>
- <listitem><para>Memory allocation failed.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>Memory allocation failed.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ENOTCONN</constant></term>
- <listitem><para>The bus is not connected.</para>
-
- <xi:include href="version-info.xml" xpointer="v246"/></listitem>
+ <listitem><para>The bus is not connected.</para></listitem>
</varlistentry>
</variablelist>
</refsect2>
<refsect1>
<title>History</title>
- <para><function>sd_bus_list_names()</function> was added in version 246.</para>
+ <para><function>sd_bus_list_names()</function> was added in version 221.</para>
</refsect1>
<refsect1>
<refsect1>
<title>History</title>
- <para><function>sd_bus_message_read_basic()</function> was added in version 231.</para>
+ <para><function>sd_bus_message_read_basic()</function> was added in version 221.</para>
</refsect1>
<refsect1>
<refsect1>
<title>History</title>
- <para><function>sd_bus_process()</function> was added in version 231.</para>
+ <para><function>sd_bus_process()</function> was added in version 221.</para>
</refsect1>
<refsect1>
<refsect1>
<title>History</title>
<para><function>sd_event_prepare()</function>,
- <function>sd_event_wait()</function>, and
- <function>sd_event_dispatch()</function> were added in version 220.</para>
- <para><function>sd_event_get_state()</function> was added in version 229.</para>
+ <function>sd_event_wait()</function>,
+ <function>sd_event_dispatch()</function>, and
+ <function>sd_event_get_state()</function> were added in version 221.</para>
<para><function>sd_event_get_iteration()</function> was added in version 231.</para>
</refsect1>
these three types of resources are generally redundant and reproducible on the next invocation of
the unit). Note that the specified units must be stopped to invoke this operation.</para>
+ <table>
+ <title>
+ Possible values for <option>--what=</option>
+ </title>
+
+ <tgroup cols='2'>
+ <thead>
+ <row>
+ <entry>Value</entry>
+ <entry>Unit Setting</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>runtime</literal></entry>
+ <entry><varname>RuntimeDirectory=</varname></entry>
+ </row>
+ <row>
+ <entry><literal>state</literal></entry>
+ <entry><varname>StateDirectory=</varname></entry>
+ </row>
+ <row>
+ <entry><literal>cache</literal></entry>
+ <entry><varname>CacheDirectory=</varname></entry>
+ </row>
+ <row>
+ <entry><literal>logs</literal></entry>
+ <entry><varname>LogsDirectory=</varname></entry>
+ </row>
+ <row>
+ <entry><literal>configuration</literal></entry>
+ <entry><varname>ConfigurationDirectory=</varname></entry>
+ </row>
+ <row>
+ <entry><literal>fdstore</literal></entry>
+ <entry><varname>FileDescriptorStorePreserve=</varname></entry>
+ </row>
+ <row>
+ <entry><literal>all</literal></entry>
+ <entry>All of the above</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
<xi:include href="version-info.xml" xpointer="v243"/>
</listitem>
</varlistentry>
<example>
<title>Provision SSH public key access for root user via Credentials in QEMU</title>
- <programlisting>-smbios type=11,value=io.systemd.credential.binary:tmpfiles.extra=$(echo "f~ /root/.ssh/authorized_keys 700 root root - $(ssh-add -L | base64 -w 0)" | base64 -w 0)
+ <programlisting>-smbios type=11,value=io.systemd.credential.binary:tmpfiles.extra=$(echo -e "d /root/.ssh 0750 root root -\nf~ /root/.ssh/authorized_keys 0600 root root - $(ssh-add -L | base64 -w 0)" | base64 -w 0)
</programlisting>
<para>By passing this line to QEMU, the public key of the current user will be encoded in base64, added
ENV{MAJOR}=="", GOTO="persistent_media_ctl_end"
IMPORT{builtin}="path_id"
-ENV{ID_PATH}=="?*", KERNEL=="media*", SYMLINK+="media/by-path/$env{ID_PATH}-media-controller"
+KERNEL=="media*", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="media/by-path/$env{ID_PATH_WITH_USB_REVISION}-media-controller"
+KERNEL=="media*", ENV{ID_PATH_WITH_USB_REVISION}=="", ENV{ID_PATH}=="?*", SYMLINK+="media/by-path/$env{ID_PATH}-media-controller"
LABEL="persistent_media_ctl_end"
comps='auto yes no'
;;
--what)
- comps='configuration state cache logs runtime all'
+ comps='configuration state cache logs runtime fdstore all'
;;
--image)
comps=$(compgen -A file -- "$cur")
return truncate_nl_full(s, NULL);
}
-static inline char *skip_leading_chars(const char *s, const char *bad) {
+static inline char* skip_leading_chars(const char *s, const char *bad) {
if (!s)
return NULL;
const char *colon;
int r;
+ assert(m);
+ assert(entries_request);
+
colon = strchr(entries_request, ':');
if (!colon)
m->cursor = strdup(entries_request);
const char *colon;
int r;
+ assert(m);
+ assert(time_request);
+
colon = strchr(time_request, ':');
if (!colon)
return -EINVAL;
return -EINVAL;
m->n_skip = 0;
+
range_after_eq = startswith(range, "entries=");
- if (range_after_eq) {
- range_after_eq += strspn(range_after_eq, WHITESPACE);
- return request_parse_range_entries(m, range_after_eq);
- }
+ if (range_after_eq)
+ return request_parse_range_entries(m, skip_leading_chars(range_after_eq, /* bad = */ NULL));
range_after_eq = startswith(range, "realtime=");
- if (range_after_eq) {
- range_after_eq += strspn(range_after_eq, WHITESPACE);
- return request_parse_range_time(m, range_after_eq);
- }
+ if (range_after_eq)
+ return request_parse_range_time(m, skip_leading_chars(range_after_eq, /* bad = */ NULL));
return 0;
}
" -t --identifier=STRING Show entries with the specified syslog identifier\n"
" -T --exclude-identifier=STRING\n"
" Hide entries with the specified syslog identifier\n"
- " -p --priority=RANGE Show entries with the specified priority\n"
+ " -p --priority=RANGE Show entries within the specified priority range\n"
" --facility=FACILITY... Show entries with the specified facilities\n"
" -g --grep=PATTERN Show entries with MESSAGE matching PATTERN\n"
" --case-sensitive[=BOOL] Force case sensitive or insensitive matching\n"
sd_ndisc_router* ndisc_router_new(ICMP6Packet *packet);
int ndisc_router_parse(sd_ndisc *nd, sd_ndisc_router *rt);
+
+int ndisc_router_flags_to_string(uint64_t flags, char **ret);
+const char* ndisc_router_preference_to_string(int s) _const_;
#include "alloc-util.h"
#include "ndisc-internal.h"
#include "ndisc-router-internal.h"
+#include "string-table.h"
static sd_ndisc_router* ndisc_router_free(sd_ndisc_router *rt) {
if (!rt)
return 0;
}
+int ndisc_router_flags_to_string(uint64_t flags, char **ret) {
+ _cleanup_free_ char *s = NULL;
+
+ assert(ret);
+
+ if (FLAGS_SET(flags, ND_RA_FLAG_MANAGED) &&
+ !strextend_with_separator(&s, ", ", "managed"))
+ return -ENOMEM;
+
+ if (FLAGS_SET(flags, ND_RA_FLAG_OTHER) &&
+ !strextend_with_separator(&s, ", ", "other"))
+ return -ENOMEM;
+
+ if (FLAGS_SET(flags, ND_RA_FLAG_HOME_AGENT) &&
+ !strextend_with_separator(&s, ", ", "home-agent"))
+ return -ENOMEM;
+
+ *ret = TAKE_PTR(s);
+ return 0;
+}
+
int sd_ndisc_router_get_lifetime(sd_ndisc_router *rt, uint64_t *ret) {
assert_return(rt, -EINVAL);
return 0;
}
+static const char* const ndisc_router_preference_table[] = {
+ [SD_NDISC_PREFERENCE_LOW] = "low",
+ [SD_NDISC_PREFERENCE_MEDIUM] = "medium",
+ [SD_NDISC_PREFERENCE_HIGH] = "high",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_TO_STRING(ndisc_router_preference, int);
+
int sd_ndisc_router_get_sender_mac(sd_ndisc_router *rt, struct ether_addr *ret) {
assert_return(rt, -EINVAL);
return r;
(void) event_source_disable(nd->timeout_event_source);
+ (void) event_source_disable(nd->timeout_no_ra);
+
+ if (DEBUG_LOGGING) {
+ _cleanup_free_ char *s = NULL;
+ struct in6_addr a;
+ uint64_t flags;
+ uint8_t pref;
+ usec_t lifetime;
+
+ r = sd_ndisc_router_get_sender_address(rt, &a);
+ if (r < 0)
+ return r;
+
+ r = sd_ndisc_router_get_flags(rt, &flags);
+ if (r < 0)
+ return r;
+
+ r = ndisc_router_flags_to_string(flags, &s);
+ if (r < 0)
+ return r;
+
+ r = sd_ndisc_router_get_preference(rt, &pref);
+ if (r < 0)
+ return r;
- log_ndisc(nd, "Received Router Advertisement: flags %s preference %s lifetime %s",
- rt->flags & ND_RA_FLAG_MANAGED ? "MANAGED" : rt->flags & ND_RA_FLAG_OTHER ? "OTHER" : "none",
- rt->preference == SD_NDISC_PREFERENCE_HIGH ? "high" : rt->preference == SD_NDISC_PREFERENCE_LOW ? "low" : "medium",
- FORMAT_TIMESPAN(rt->lifetime_usec, USEC_PER_SEC));
+ r = sd_ndisc_router_get_lifetime(rt, &lifetime);
+ if (r < 0)
+ return r;
+
+ log_ndisc(nd, "Received Router Advertisement from %s: flags=0x%0*"PRIx64"%s%s%s, preference=%s, lifetime=%s",
+ IN6_ADDR_TO_STRING(&a),
+ flags & UINT64_C(0x00ffffffffffff00) ? 14 : 2, flags, /* suppress too many zeros if no extension */
+ s ? " (" : "", s, s ? ")" : "",
+ ndisc_router_preference_to_string(pref),
+ FORMAT_TIMESPAN(lifetime, USEC_PER_SEC));
+ }
ndisc_callback(nd, SD_NDISC_EVENT_ROUTER, rt);
return 0;
static int ndisc_handle_neighbor(sd_ndisc *nd, ICMP6Packet *packet) {
_cleanup_(sd_ndisc_neighbor_unrefp) sd_ndisc_neighbor *na = NULL;
- struct in6_addr a;
int r;
assert(nd);
if (r < 0)
return r;
- r = sd_ndisc_neighbor_get_sender_address(na, &a);
- if (r < 0)
- return r;
+ if (DEBUG_LOGGING) {
+ struct in6_addr a;
- log_ndisc(nd, "Received Neighbor Advertisement from %s: Router=%s, Solicited=%s, Override=%s",
- IN6_ADDR_TO_STRING(&a),
- yes_no(sd_ndisc_neighbor_is_router(na) > 0),
- yes_no(sd_ndisc_neighbor_is_solicited(na) > 0),
- yes_no(sd_ndisc_neighbor_is_override(na) > 0));
+ r = sd_ndisc_neighbor_get_sender_address(na, &a);
+ if (r < 0)
+ return r;
+
+ log_ndisc(nd, "Received Neighbor Advertisement from %s: Router=%s, Solicited=%s, Override=%s",
+ IN6_ADDR_TO_STRING(&a),
+ yes_no(sd_ndisc_neighbor_is_router(na) > 0),
+ yes_no(sd_ndisc_neighbor_is_solicited(na) > 0),
+ yes_no(sd_ndisc_neighbor_is_override(na) > 0));
+ }
ndisc_callback(nd, SD_NDISC_EVENT_NEIGHBOR, na);
return 0;
static int ndisc_handle_redirect(sd_ndisc *nd, ICMP6Packet *packet) {
_cleanup_(sd_ndisc_redirect_unrefp) sd_ndisc_redirect *rd = NULL;
- struct in6_addr a;
int r;
assert(nd);
if (r < 0)
return r;
- r = sd_ndisc_redirect_get_sender_address(rd, &a);
- if (r < 0)
- return r;
+ if (DEBUG_LOGGING) {
+ struct in6_addr sender, target, dest;
+
+ r = sd_ndisc_redirect_get_sender_address(rd, &sender);
+ if (r < 0)
+ return r;
+
+ r = sd_ndisc_redirect_get_target_address(rd, &target);
+ if (r < 0)
+ return r;
- log_ndisc(nd, "Received Redirect message from %s: Target=%s, Destination=%s",
- IN6_ADDR_TO_STRING(&a),
- IN6_ADDR_TO_STRING(&rd->target_address),
- IN6_ADDR_TO_STRING(&rd->destination_address));
+ r = sd_ndisc_redirect_get_destination_address(rd, &dest);
+ if (r < 0)
+ return r;
+
+ log_ndisc(nd, "Received Redirect message from %s: Target=%s, Destination=%s",
+ IN6_ADDR_TO_STRING(&sender),
+ IN6_ADDR_TO_STRING(&target),
+ IN6_ADDR_TO_STRING(&dest));
+ }
ndisc_callback(nd, SD_NDISC_EVENT_REDIRECT, rd);
return 0;
int device_get_property_bool(sd_device *device, const char *key);
int device_get_property_int(sd_device *device, const char *key, int *ret);
int device_get_sysattr_int(sd_device *device, const char *sysattr, int *ret_value);
-int device_get_sysattr_unsigned(sd_device *device, const char *sysattr, unsigned *ret_value);
+int device_get_sysattr_unsigned_full(sd_device *device, const char *sysattr, unsigned base, unsigned *ret_value);
+static inline int device_get_sysattr_unsigned(sd_device *device, const char *sysattr, unsigned *ret_value) {
+ return device_get_sysattr_unsigned_full(device, sysattr, 0, ret_value);
+}
int device_get_sysattr_u32(sd_device *device, const char *sysattr, uint32_t *ret_value);
int device_get_sysattr_bool(sd_device *device, const char *sysattr);
int device_get_device_id(sd_device *device, const char **ret);
return v > 0;
}
-int device_get_sysattr_unsigned(sd_device *device, const char *sysattr, unsigned *ret_value) {
+int device_get_sysattr_unsigned_full(sd_device *device, const char *sysattr, unsigned base, unsigned *ret_value) {
const char *value;
int r;
return r;
unsigned v;
- r = safe_atou(value, &v);
+ r = safe_atou_full(value, base, &v);
if (r < 0)
return log_device_debug_errno(device, r, "Failed to parse '%s' attribute: %m", sysattr);
#include "mount-util.h"
#include "namespace-util.h"
#include "netif-naming-scheme.h"
+#include "netif-util.h"
#include "netlink-util.h"
#include "nspawn-network.h"
#include "parse-util.h"
#define VETH_EXTRA_HOST_HASH_KEY SD_ID128_MAKE(48,c7,f6,b7,ea,9d,4c,9e,b7,28,d4,de,91,d5,bf,66)
#define VETH_EXTRA_CONTAINER_HASH_KEY SD_ID128_MAKE(af,50,17,61,ce,f9,4d,35,84,0d,2b,20,54,be,ce,59)
#define MACVLAN_HASH_KEY SD_ID128_MAKE(00,13,6d,bc,66,83,44,81,bb,0c,f9,51,1f,24,a6,6f)
-#define SHORTEN_IFNAME_HASH_KEY SD_ID128_MAKE(e1,90,a4,04,a8,ef,4b,51,8c,cc,c3,3a,9f,11,fc,a2)
static int remove_one_link(sd_netlink *rtnl, const char *name) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
return 1;
}
-static int generate_mac(
- const char *machine_name,
- struct ether_addr *mac,
- sd_id128_t hash_key,
- uint64_t idx) {
-
- uint64_t result;
- size_t l, sz;
- uint8_t *v, *i;
- int r;
-
- l = strlen(machine_name);
- sz = sizeof(sd_id128_t) + l;
- if (idx > 0)
- sz += sizeof(idx);
-
- v = newa(uint8_t, sz);
-
- /* fetch some persistent data unique to the host */
- r = sd_id128_get_machine((sd_id128_t*) v);
- if (r < 0)
- return r;
-
- /* combine with some data unique (on this host) to this
- * container instance */
- i = mempcpy(v + sizeof(sd_id128_t), machine_name, l);
- if (idx > 0) {
- idx = htole64(idx);
- memcpy(i, &idx, sizeof(idx));
- }
-
- /* Let's hash the host machine ID plus the container name. We
- * use a fixed, but originally randomly created hash key here. */
- result = htole64(siphash24(v, sz, hash_key.bytes));
-
- assert_cc(ETH_ALEN <= sizeof(result));
- memcpy(mac->ether_addr_octet, &result, ETH_ALEN);
-
- ether_addr_mark_random(mac);
-
- return 0;
-}
-
static int set_alternative_ifname(sd_netlink *rtnl, const char *ifname, const char *altifname) {
int r;
return 0;
}
-static int shorten_ifname(char *ifname) {
- char new_ifname[IFNAMSIZ];
-
- assert(ifname);
-
- if (strlen(ifname) < IFNAMSIZ) /* Name is short enough */
- return 0;
-
- if (naming_scheme_has(NAMING_NSPAWN_LONG_HASH)) {
- uint64_t h;
-
- /* Calculate 64-bit hash value */
- h = siphash24(ifname, strlen(ifname), SHORTEN_IFNAME_HASH_KEY.bytes);
-
- /* Set the final four bytes (i.e. 32-bit) to the lower 24bit of the hash, encoded in url-safe base64 */
- memcpy(new_ifname, ifname, IFNAMSIZ - 5);
- new_ifname[IFNAMSIZ - 5] = urlsafe_base64char(h >> 18);
- new_ifname[IFNAMSIZ - 4] = urlsafe_base64char(h >> 12);
- new_ifname[IFNAMSIZ - 3] = urlsafe_base64char(h >> 6);
- new_ifname[IFNAMSIZ - 2] = urlsafe_base64char(h);
- } else
- /* On old nspawn versions we just truncated the name, provide compatibility */
- memcpy(new_ifname, ifname, IFNAMSIZ-1);
-
- new_ifname[IFNAMSIZ - 1] = 0;
-
- /* Log the incident to make it more discoverable */
- log_warning("Network interface name '%s' has been changed to '%s' to fit length constraints.", ifname, new_ifname);
-
- strcpy(ifname, new_ifname);
- return 1;
-}
-
int setup_veth(const char *machine_name,
pid_t pid,
char iface_name[IFNAMSIZ],
/* Use two different interface name prefixes depending whether
* we are in bridge mode or not. */
n = strjoina(bridge ? "vb-" : "ve-", machine_name);
- r = shorten_ifname(n);
+ r = net_shorten_ifname(n, /* check_naming_scheme= */ true);
if (r > 0)
a = strjoina(bridge ? "vb-" : "ve-", machine_name);
if (ether_addr_is_null(provided_mac)){
- r = generate_mac(machine_name, &mac_container, CONTAINER_HASH_KEY, 0);
+ r = net_generate_mac(machine_name, &mac_container, CONTAINER_HASH_KEY, 0);
if (r < 0)
return log_error_errno(r, "Failed to generate predictable MAC address for container side: %m");
} else
mac_container = *provided_mac;
- r = generate_mac(machine_name, &mac_host, HOST_HASH_KEY, 0);
+ r = net_generate_mac(machine_name, &mac_host, HOST_HASH_KEY, 0);
if (r < 0)
return log_error_errno(r, "Failed to generate predictable MAC address for host side: %m");
STRV_FOREACH_PAIR(a, b, pairs) {
struct ether_addr mac_host, mac_container;
- r = generate_mac(machine_name, &mac_container, VETH_EXTRA_CONTAINER_HASH_KEY, idx);
+ r = net_generate_mac(machine_name, &mac_container, VETH_EXTRA_CONTAINER_HASH_KEY, idx);
if (r < 0)
return log_error_errno(r, "Failed to generate predictable MAC address for container side of extra veth link: %m");
- r = generate_mac(machine_name, &mac_host, VETH_EXTRA_HOST_HASH_KEY, idx);
+ r = net_generate_mac(machine_name, &mac_host, VETH_EXTRA_HOST_HASH_KEY, idx);
if (r < 0)
return log_error_errno(r, "Failed to generate predictable MAC address for host side of extra veth link: %m");
if (ifi < 0)
return ifi;
- r = generate_mac(machine_name, &mac, MACVLAN_HASH_KEY, idx++);
+ r = net_generate_mac(machine_name, &mac, MACVLAN_HASH_KEY, idx++);
if (r < 0)
return log_error_errno(r, "Failed to create MACVLAN MAC address: %m");
if (!n)
return log_oom();
- shortened = shorten_ifname(n);
+ shortened = net_shorten_ifname(n, /* check_naming_scheme= */ true);
r = sd_netlink_message_append_string(m, IFLA_IFNAME, n);
if (r < 0)
if (!n)
return log_oom();
- shortened = shorten_ifname(n);
+ shortened = net_shorten_ifname(n, /* check_naming_scheme= */ true);
r = sd_netlink_message_append_string(m, IFLA_IFNAME, n);
if (r < 0)
#include "alloc-util.h"
#include "blockdev-util.h"
#include "btrfs-util.h"
+#include "device-private.h"
#include "device-util.h"
#include "devnum-util.h"
#include "dirent-util.h"
}
int blockdev_partscan_enabled(int fd) {
- _cleanup_free_ char *p = NULL, *buf = NULL;
- unsigned long long ull;
- struct stat st;
- int r;
-
- /* Checks if partition scanning is correctly enabled on the block device */
+ _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
+ unsigned capability;
+ int r, ext_range;
- if (fstat(fd, &st) < 0)
- return -errno;
+ /* Checks if partition scanning is correctly enabled on the block device.
+ *
+ * The 'GENHD_FL_NO_PART_SCAN' flag was introduced by
+ * https://github.com/torvalds/linux/commit/d27769ec3df1a8de9ca450d2dcd72d1ab259ba32 (v3.2).
+ * But at that time, the flag is also effectively implied when 'minors' element of 'struct gendisk'
+ * is 1, which can be check with 'ext_range' sysfs attribute. Explicit flag ('GENHD_FL_NO_PART_SCAN')
+ * can be obtained from 'capability' sysattr.
+ *
+ * With https://github.com/torvalds/linux/commit/1ebe2e5f9d68e94c524aba876f27b945669a7879 (v5.17), we
+ * can check the flag from 'ext_range' sysfs attribute directly.
+ *
+ * With https://github.com/torvalds/linux/commit/e81cd5a983bb35dabd38ee472cf3fea1c63e0f23 (v6.3),
+ * the 'capability' sysfs attribute is deprecated, hence we cannot check the flag from it.
+ *
+ * To support both old and new kernels, we need to do the following: first check 'ext_range' sysfs
+ * attribute, and if '1' we can conclude partition scanning is disabled, otherwise check 'capability'
+ * sysattr for older version. */
- if (!S_ISBLK(st.st_mode))
- return -ENOTBLK;
+ assert(fd >= 0);
- if (asprintf(&p, "/sys/dev/block/%u:%u/capability", major(st.st_rdev), minor(st.st_rdev)) < 0)
- return -ENOMEM;
+ r = block_device_new_from_fd(fd, 0, &dev);
+ if (r < 0)
+ return r;
- r = read_one_line_file(p, &buf);
- if (r == -ENOENT) /* If the capability file doesn't exist then we are most likely looking at a
+ r = device_get_sysattr_int(dev, "ext_range", &ext_range);
+ if (r == -ENOENT) /* If the ext_range file doesn't exist then we are most likely looking at a
* partition block device, not the whole block device. And that means we have no
* partition scanning on for it (we do for its parent, but not for the partition
* itself). */
if (r < 0)
return r;
- r = safe_atollu_full(buf, 16, &ull);
+ if (ext_range <= 1) /* The value should be always positive, but the kernel uses '%d' for the
+ * attribute. Let's gracefully handle zero or negative. */
+ return false;
+
+ r = device_get_sysattr_unsigned_full(dev, "capability", 16, &capability);
+ if (r == -ENOENT)
+ return false;
if (r < 0)
return r;
#define GENHD_FL_NO_PART_SCAN (0x0200)
#endif
- return !FLAGS_SET(ull, GENHD_FL_NO_PART_SCAN);
+ /* If 0x200 is set, part scanning is definitely off. */
+ if (FLAGS_SET(capability, GENHD_FL_NO_PART_SCAN))
+ return false;
+
+ /* Otherwise, assume part scanning is on, we have no further checks available. Assume the best. */
+ return true;
}
static int blockdev_is_encrypted(const char *sysfs_path, unsigned depth_left) {
#include "arphrd-util.h"
#include "device-util.h"
+#include "hexdecoct.h"
#include "log-link.h"
#include "memory-util.h"
+#include "netif-naming-scheme.h"
#include "netif-util.h"
#include "siphash24.h"
#include "sparse-endian.h"
#include "strv.h"
+#define SHORTEN_IFNAME_HASH_KEY SD_ID128_MAKE(e1,90,a4,04,a8,ef,4b,51,8c,cc,c3,3a,9f,11,fc,a2)
+
bool netif_has_carrier(uint8_t operstate, unsigned flags) {
/* see Documentation/networking/operstates.txt in the kernel sources */
return 0;
}
+
+int net_generate_mac(
+ const char *machine_name,
+ struct ether_addr *mac,
+ sd_id128_t hash_key,
+ uint64_t idx) {
+
+ uint64_t result;
+ size_t l, sz;
+ uint8_t *v, *i;
+ int r;
+
+ l = strlen(machine_name);
+ sz = sizeof(sd_id128_t) + l;
+ if (idx > 0)
+ sz += sizeof(idx);
+
+ v = newa(uint8_t, sz);
+
+ /* fetch some persistent data unique to the host */
+ r = sd_id128_get_machine((sd_id128_t*) v);
+ if (r < 0)
+ return r;
+
+ /* combine with some data unique (on this host) to this
+ * container instance */
+ i = mempcpy(v + sizeof(sd_id128_t), machine_name, l);
+ if (idx > 0) {
+ idx = htole64(idx);
+ memcpy(i, &idx, sizeof(idx));
+ }
+
+ /* Let's hash the host machine ID plus the container name. We
+ * use a fixed, but originally randomly created hash key here. */
+ result = htole64(siphash24(v, sz, hash_key.bytes));
+
+ assert_cc(ETH_ALEN <= sizeof(result));
+ memcpy(mac->ether_addr_octet, &result, ETH_ALEN);
+
+ ether_addr_mark_random(mac);
+
+ return 0;
+}
+
+int net_shorten_ifname(char *ifname, bool check_naming_scheme) {
+ char new_ifname[IFNAMSIZ];
+
+ assert(ifname);
+
+ if (strlen(ifname) < IFNAMSIZ) /* Name is short enough */
+ return 0;
+
+ if (!check_naming_scheme || naming_scheme_has(NAMING_NSPAWN_LONG_HASH)) {
+ uint64_t h;
+
+ /* Calculate 64-bit hash value */
+ h = siphash24(ifname, strlen(ifname), SHORTEN_IFNAME_HASH_KEY.bytes);
+
+ /* Set the final four bytes (i.e. 32-bit) to the lower 24bit of the hash, encoded in url-safe base64 */
+ memcpy(new_ifname, ifname, IFNAMSIZ - 5);
+ new_ifname[IFNAMSIZ - 5] = urlsafe_base64char(h >> 18);
+ new_ifname[IFNAMSIZ - 4] = urlsafe_base64char(h >> 12);
+ new_ifname[IFNAMSIZ - 3] = urlsafe_base64char(h >> 6);
+ new_ifname[IFNAMSIZ - 2] = urlsafe_base64char(h);
+ } else
+ /* On old nspawn versions we just truncated the name, provide compatibility */
+ memcpy(new_ifname, ifname, IFNAMSIZ-1);
+
+ new_ifname[IFNAMSIZ - 1] = 0;
+
+ /* Log the incident to make it more discoverable */
+ log_warning("Network interface name '%s' has been changed to '%s' to fit length constraints.", ifname, new_ifname);
+
+ strcpy(ifname, new_ifname);
+ return 1;
+}
uint16_t iftype,
const struct hw_addr_data *ib_hw_addr,
struct hw_addr_data *new_hw_addr);
+int net_generate_mac(
+ const char *machine_name,
+ struct ether_addr *mac,
+ sd_id128_t hash_key,
+ uint64_t idx);
+int net_shorten_ifname(char *ifname, bool check_naming_scheme);
return r;
if (isempty(action))
- return log_error_errno(SYNTHETIC_ERRNO(ENODATA), "No scheduled shutdown.");
+ return log_full_errno(arg_quiet ? LOG_DEBUG : LOG_ERR, SYNTHETIC_ERRNO(ENODATA), "No scheduled shutdown.");
if (STR_IN_SET(action, "halt", "poweroff", "exit"))
pretty_action = "Shutdown";
!STARTSWITH_SET(cmd, "ata_id", "cdrom_id", "dmi_memory_id", "fido_id", "mtd_probe", "scsi_id")) {
log_device_debug(event->dev, "Running in test mode, skipping execution of '%s'.", cmd);
result[0] = '\0';
- ret_truncated = false;
+ if (ret_truncated)
+ *ret_truncated = false;
return 0;
}
/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#include <net/if.h>
+#include <linux/if.h>
#include <getopt.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
-#include "bootspec.h"
-#include "chase.h"
-#include "dirent-util.h"
-#include "fd-util.h"
-#include "discover-image.h"
-#include "pidref.h"
#include "sd-daemon.h"
#include "sd-event.h"
#include "sd-id128.h"
#include "alloc-util.h"
#include "architecture.h"
+#include "bootspec.h"
#include "build.h"
+#include "chase.h"
#include "common-signal.h"
#include "copy.h"
#include "creds-util.h"
+#include "dirent-util.h"
+#include "discover-image.h"
#include "dissect-image.h"
#include "escape.h"
+#include "ether-addr-util.h"
#include "event-util.h"
#include "extract-word.h"
+#include "fd-util.h"
#include "fileio.h"
#include "format-util.h"
#include "fs-util.h"
#include "macro.h"
#include "main-func.h"
#include "mkdir.h"
+#include "netif-util.h"
#include "pager.h"
#include "parse-argument.h"
#include "parse-util.h"
#include "path-lookup.h"
#include "path-util.h"
+#include "pidref.h"
#include "pretty-print.h"
#include "process-util.h"
#include "ptyfwd.h"
#include "vmspawn-settings.h"
#include "vmspawn-util.h"
+#define VM_TAP_HASH_KEY SD_ID128_MAKE(01,d0,c6,4c,2b,df,24,fb,c0,f8,b2,09,7d,59,b2,93)
+
static bool arg_quiet = false;
static PagerFlags arg_pager_flags = 0;
static char *arg_directory = NULL;
static bool arg_pass_ssh_key = true;
static char *arg_ssh_key_type = NULL;
static bool arg_discard_disk = true;
+struct ether_addr arg_network_provided_mac = {};
STATIC_DESTRUCTOR_REGISTER(arg_directory, freep);
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
return 0;
}
+static int parse_environment(void) {
+ const char *e;
+ int r;
+
+ e = getenv("SYSTEMD_VMSPAWN_NETWORK_MAC");
+ if (e) {
+ r = parse_ether_addr(e, &arg_network_provided_mac);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse provided MAC address via environment variable");
+ }
+
+ return 0;
+}
+
static int parse_argv(int argc, char *argv[]) {
enum {
ARG_VERSION = 0x100,
if (dot)
(void) pty_forward_set_title_prefix(f, dot);
}
+
static int generate_ssh_keypair(const char *key_path, const char *key_type) {
_cleanup_free_ char *ssh_keygen = NULL;
_cleanup_strv_free_ char **cmdline = NULL;
}
}
- if (arg_network_stack == NETWORK_STACK_TAP)
- r = strv_extend_many(&cmdline, "-nic", "tap,script=no,model=virtio-net-pci");
- else if (arg_network_stack == NETWORK_STACK_USER)
+ if (arg_network_stack == NETWORK_STACK_TAP) {
+ _cleanup_free_ char *tap_name = NULL;
+ struct ether_addr mac_vm = {};
+
+ tap_name = strjoin("tp-", arg_machine);
+ if (!tap_name)
+ return log_oom();
+
+ (void) net_shorten_ifname(tap_name, /* check_naming_scheme= */ false);
+
+ if (ether_addr_is_null(&arg_network_provided_mac)){
+ r = net_generate_mac(arg_machine, &mac_vm, VM_TAP_HASH_KEY, 0);
+ if (r < 0)
+ return log_error_errno(r, "Failed to generate predictable MAC address for VM side: %m");
+ } else
+ mac_vm = arg_network_provided_mac;
+
+ r = strv_extend(&cmdline, "-nic");
+ if (r < 0)
+ return log_oom();
+
+ r = strv_extendf(&cmdline, "tap,ifname=%s,script=no,model=virtio-net-pci,mac=%s", tap_name, ETHER_ADDR_TO_STR(&mac_vm));
+ if (r < 0)
+ return log_oom();
+ } else if (arg_network_stack == NETWORK_STACK_USER)
r = strv_extend_many(&cmdline, "-nic", "user,model=virtio-net-pci");
else
r = strv_extend_many(&cmdline, "-nic", "none");
/* don't attempt to register as a machine when running as a user */
arg_register = arg_privileged;
+ r = parse_environment();
+ if (r < 0)
+ return r;
+
r = parse_argv(argc, argv);
if (r <= 0)
return r;